From 9b2320ea799893e2cd6ae31fa0d478991a43703e Mon Sep 17 00:00:00 2001 From: Dani Mehrjerdi Date: Mon, 16 Dec 2024 16:57:08 +0100 Subject: [PATCH] Add express relay rust client (#280) --- .github/workflows/ci-pre-commit.yml | 8 +- .../publish-express-relay-api-types.yml | 17 + .../publish-rust-express-relay-client.yml | 17 + .pre-commit-config.yaml | 39 +- .vscode/settings.json | 5 +- auction-server/Cargo.lock => Cargo.lock | 1569 +++++++++++------ Cargo.toml | 38 + Dockerfile | 5 +- auction-server/Cargo.toml | 43 +- auction-server/api-types/Cargo.toml | 22 + auction-server/api-types/src/bid.rs | 402 +++++ auction-server/api-types/src/lib.rs | 113 ++ auction-server/api-types/src/opportunity.rs | 662 +++++++ auction-server/api-types/src/profile.rs | 123 ++ auction-server/{ => api-types}/src/serde.rs | 7 +- auction-server/api-types/src/ws.rs | 118 ++ auction-server/build.rs | 1 - auction-server/rust-toolchain.toml | 2 - auction-server/src/api.rs | 231 +-- auction-server/src/api/profile.rs | 71 +- auction-server/src/api/ws.rs | 129 +- auction-server/src/auction/api.rs | 382 +--- auction-server/src/auction/entities/bid.rs | 6 +- .../src/auction/repository/models.rs | 2 +- .../src/auction/service/auction_manager.rs | 2 - .../src/auction/service/simulator.rs | 1 - .../src/auction/service/update_bid_status.rs | 6 +- auction-server/src/auction/service/workers.rs | 2 +- auction-server/src/kernel/entities.rs | 34 - auction-server/src/main.rs | 2 - auction-server/src/models.rs | 1 - auction-server/src/opportunity/api.rs | 616 +------ .../src/opportunity/entities/opportunity.rs | 8 +- .../opportunity/entities/opportunity_evm.rs | 8 +- .../opportunity/entities/opportunity_svm.rs | 9 +- .../src/opportunity/entities/quote.rs | 6 +- .../opportunity/entities/token_amount_evm.rs | 4 +- .../opportunity/entities/token_amount_svm.rs | 2 +- .../src/opportunity/repository/models.rs | 2 +- .../opportunity/service/get_opportunities.rs | 12 +- .../service/handle_opportunity_bid.rs | 8 +- .../service/make_adapter_calldata.rs | 6 +- .../make_opportunity_execution_params.rs | 6 +- .../service/make_permitted_tokens.rs | 6 +- .../src/opportunity/service/verification.rs | 2 +- auction-server/src/opportunity/token_spoof.rs | 1 - auction-server/src/server.rs | 2 - auction-server/src/state.rs | 4 +- contracts/svm/cli/src/main.rs | 2 - .../express_relay/src/sdk/test_helpers.rs | 1 - .../svm/testing/src/express_relay/helpers.rs | 10 +- .../testing/src/express_relay/initialize.rs | 1 - .../testing/src/express_relay/set_admin.rs | 1 - .../testing/src/express_relay/set_relayer.rs | 1 - .../testing/src/express_relay/set_splits.rs | 1 - .../src/express_relay/withdraw_fees.rs | 1 - gas-oracle/Cargo.toml | 2 +- rust-toolchain.toml | 2 + sdk/rust/Cargo.toml | 20 + sdk/rust/abi/ERC20.sol/ERC20.json | 1 + .../abi/ExpressRelay.sol/ExpressRelay.json | 1 + .../OpportunityAdapter.json | 1 + .../OpportunityAdapterFactory.json | 1 + sdk/rust/abi/WETH9.sol/WETH9.json | 1 + sdk/rust/simple-searcher/Cargo.toml | 13 + sdk/rust/simple-searcher/src/main.rs | 228 +++ sdk/rust/src/evm.rs | 284 +++ sdk/rust/src/lib.rs | 496 ++++++ 68 files changed, 3934 insertions(+), 1896 deletions(-) create mode 100644 .github/workflows/publish-express-relay-api-types.yml create mode 100644 .github/workflows/publish-rust-express-relay-client.yml rename auction-server/Cargo.lock => Cargo.lock (85%) create mode 100644 Cargo.toml create mode 100644 auction-server/api-types/Cargo.toml create mode 100644 auction-server/api-types/src/bid.rs create mode 100644 auction-server/api-types/src/lib.rs create mode 100644 auction-server/api-types/src/opportunity.rs create mode 100644 auction-server/api-types/src/profile.rs rename auction-server/{ => api-types}/src/serde.rs (92%) create mode 100644 auction-server/api-types/src/ws.rs delete mode 100644 auction-server/rust-toolchain.toml create mode 100644 rust-toolchain.toml create mode 100644 sdk/rust/Cargo.toml create mode 100644 sdk/rust/abi/ERC20.sol/ERC20.json create mode 100644 sdk/rust/abi/ExpressRelay.sol/ExpressRelay.json create mode 100644 sdk/rust/abi/OpportunityAdapter.sol/OpportunityAdapter.json create mode 100644 sdk/rust/abi/OpportunityAdapterFactory.sol/OpportunityAdapterFactory.json create mode 100644 sdk/rust/abi/WETH9.sol/WETH9.json create mode 100644 sdk/rust/simple-searcher/Cargo.toml create mode 100644 sdk/rust/simple-searcher/src/main.rs create mode 100644 sdk/rust/src/evm.rs create mode 100644 sdk/rust/src/lib.rs diff --git a/.github/workflows/ci-pre-commit.yml b/.github/workflows/ci-pre-commit.yml index 49e3dfd2..80499e4c 100644 --- a/.github/workflows/ci-pre-commit.yml +++ b/.github/workflows/ci-pre-commit.yml @@ -21,13 +21,13 @@ jobs: - uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: nightly-2023-03-01 - components: rustfmt, clippy + toolchain: 1.83.0 + components: clippy - uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: nightly-2024-04-10 - components: rustfmt, clippy + toolchain: nightly-2024-12-03 + components: rustfmt - name: Install Protoc uses: arduino/setup-protoc@v3 with: diff --git a/.github/workflows/publish-express-relay-api-types.yml b/.github/workflows/publish-express-relay-api-types.yml new file mode 100644 index 00000000..bcc40a88 --- /dev/null +++ b/.github/workflows/publish-express-relay-api-types.yml @@ -0,0 +1,17 @@ +name: Publish Express Relay Client to crates.io + +on: + push: + tags: + - express-relay-api-types-v* +jobs: + publish-express-relay-client: + name: Publish Express Relay Client + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v2 + + - run: cargo publish -p express-relay-api-types --token ${CARGO_REGISTRY_TOKEN} + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.PYTH_NETWORK_PYTH_OPS_CARGO_PUSH }} diff --git a/.github/workflows/publish-rust-express-relay-client.yml b/.github/workflows/publish-rust-express-relay-client.yml new file mode 100644 index 00000000..2df7db09 --- /dev/null +++ b/.github/workflows/publish-rust-express-relay-client.yml @@ -0,0 +1,17 @@ +name: Publish Express Relay Client to crates.io + +on: + push: + tags: + - rust-express-relay-client-v* +jobs: + publish-express-relay-client: + name: Publish Express Relay Client + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v2 + - name: Publish Express Relay Client + run: cargo publish -p express-relay-client --token ${CARGO_REGISTRY_TOKEN} + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.PYTH_NETWORK_PYTH_OPS_CARGO_PUSH }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 13b84767..7f59ecc1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,6 +4,7 @@ repos: hooks: - id: trailing-whitespace - id: end-of-file-fixer + exclude: "^sdk/rust/abi/.*" - id: check-added-large-files exclude: package-lock.json # Hook to format many type of files in the repo @@ -15,52 +16,40 @@ repos: additional_dependencies: - "prettier@2.7.1" - "prettier-plugin-solidity@1.0.0-rc.1" + exclude: "^sdk/rust/abi/.*" - repo: local hooks: - # Hooks for auction server - - id: cargo-fmt-auction-server - name: Cargo format for auction server + # Hooks for workspace + - id: cargo-fmt-workspace + name: Cargo format for workspace language: "rust" - entry: cargo +nightly-2024-04-10 fmt --manifest-path ./auction-server/Cargo.toml --all -- --config-path rustfmt.toml + entry: cargo +nightly-2024-12-03 fmt --manifest-path ./Cargo.toml --all -- --config-path rustfmt.toml pass_filenames: false - files: auction-server - - id: cargo-clippy-auction-server - name: Cargo clippy for auction server + files: . + - id: cargo-clippy-workspace + name: Cargo clippy for workspace language: "rust" - entry: cargo +stable clippy --manifest-path ./auction-server/Cargo.toml --tests -- -D warnings + entry: cargo +stable clippy --manifest-path ./Cargo.toml --tests -- -D warnings pass_filenames: false - files: auction-server + files: . # Hooks for vault-simulator - id: cargo-fmt-vault-simulator name: Cargo format for vault simulator language: "rust" - entry: cargo +nightly-2024-04-10 fmt --manifest-path ./vault-simulator/Cargo.toml --all -- --config-path rustfmt.toml + entry: cargo fmt --manifest-path ./vault-simulator/Cargo.toml --all -- --config-path rustfmt.toml pass_filenames: false files: vault-simulator - id: cargo-clippy-vault-simulator name: Cargo clippy for vault simulator language: "rust" - entry: cargo +stable clippy --manifest-path ./vault-simulator/Cargo.toml --tests -- -D warnings + entry: cargo clippy --manifest-path ./vault-simulator/Cargo.toml --tests -- -D warnings pass_filenames: false files: vault-simulator - # Hooks for gas-oracle - - id: cargo-fmt-gas-oracle - name: Cargo format for gas oracle - language: "rust" - entry: cargo +nightly-2024-04-10 fmt --manifest-path ./gas-oracle/Cargo.toml --all -- --config-path rustfmt.toml - pass_filenames: false - files: gas-oracle - - id: cargo-clippy-gas-oracle - name: Cargo clippy for gas oracle - language: "rust" - entry: cargo +stable clippy --manifest-path ./gas-oracle/Cargo.toml --tests -- -D warnings - pass_filenames: false - files: gas-oracle # Hooks for contracts-svm - id: cargo-fmt-contracts-svm name: Cargo format for svm contracts language: "rust" - entry: cargo +nightly-2024-04-10 fmt --manifest-path ./contracts/svm/Cargo.toml --all -- --config-path rustfmt.toml + entry: cargo +nightly-2024-12-03 fmt --manifest-path ./contracts/svm/Cargo.toml --all -- --config-path rustfmt.toml pass_filenames: false files: contracts/svm - id: cargo-clippy-contracts-svm diff --git a/.vscode/settings.json b/.vscode/settings.json index 55330aad..727bbea6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,8 +1,7 @@ { "rust-analyzer.linkedProjects": [ - "./auction-server/Cargo.toml", - "./gas-oracle/Cargo.toml", "./vault-simulator/Cargo.toml", - "./contracts/svm/Cargo.toml" + "./contracts/svm/Cargo.toml", + "./Cargo.toml" ] } diff --git a/auction-server/Cargo.lock b/Cargo.lock similarity index 85% rename from auction-server/Cargo.lock rename to Cargo.lock index d34d4e6f..46df5f4a 100644 --- a/auction-server/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "Inflector" @@ -14,9 +14,9 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.24.1" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] @@ -113,9 +113,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.18" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "anchor-attribute-access-control" @@ -249,7 +249,7 @@ dependencies = [ "borsh 0.10.4", "bytemuck", "getrandom 0.2.15", - "solana-program 1.18.23", + "solana-program 1.18.26", "thiserror", ] @@ -321,9 +321,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.15" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -336,43 +336,43 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.4" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anyhow" -version = "1.0.89" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" +checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" [[package]] name = "ark-bn254" @@ -543,7 +543,7 @@ dependencies = [ "proc-macro2", "quote", "syn 1.0.109", - "synstructure", + "synstructure 0.12.6", ] [[package]] @@ -576,9 +576,9 @@ dependencies = [ [[package]] name = "async-compression" -version = "0.4.12" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fec134f64e2bc57411226dfc4e52dec859ddfc7e711fc5e07b612584f000e4aa" +checksum = "df895a515f70646414f4b45c0b79082783b80552b373a68283012928df56f522" dependencies = [ "brotli", "flate2", @@ -599,9 +599,9 @@ dependencies = [ [[package]] name = "async-stream" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" dependencies = [ "async-stream-impl", "futures-core", @@ -610,13 +610,13 @@ dependencies = [ [[package]] name = "async-stream-impl" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -627,7 +627,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -650,6 +650,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "atty" version = "0.2.14" @@ -669,18 +675,19 @@ dependencies = [ "anchor-lang-idl", "anyhow", "async-stream", - "axum 0.7.7", + "axum 0.7.9", "axum-extra", "axum-macros", "axum-prometheus", "axum-streams", "base64 0.22.1", "bincode", - "borsh 1.5.1", - "clap 4.5.18", + "borsh 1.5.3", + "clap 4.5.23", "email_address", "ethers", "express-relay", + "express-relay-api-types", "futures", "gas-oracle", "litesvm", @@ -688,11 +695,11 @@ dependencies = [ "opentelemetry-otlp", "opentelemetry_sdk", "rand 0.8.5", - "reqwest", + "reqwest 0.11.27", "serde", "serde_json", "serde_path_to_error", - "serde_with 3.9.0", + "serde_with 3.11.0", "serde_yaml", "solana-client", "solana-rpc-client", @@ -709,7 +716,7 @@ dependencies = [ "tracing-subscriber", "utoipa", "utoipa-redoc", - "uuid 1.10.0", + "uuid 1.11.0", ] [[package]] @@ -720,7 +727,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -742,7 +749,7 @@ dependencies = [ "futures-util", "http 0.2.12", "http-body 0.4.6", - "hyper 0.14.30", + "hyper 0.14.31", "itoa", "matchit", "memchr", @@ -763,19 +770,19 @@ dependencies = [ [[package]] name = "axum" -version = "0.7.7" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "504e3947307ac8326a5437504c517c4b56716c9d98fac0028c2acc7ca47d70ae" +checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" dependencies = [ "async-trait", "axum-core 0.4.5", "base64 0.22.1", "bytes", "futures-util", - "http 1.1.0", + "http 1.2.0", "http-body 1.0.1", "http-body-util", - "hyper 1.4.1", + "hyper 1.5.1", "hyper-util", "itoa", "matchit", @@ -789,7 +796,7 @@ dependencies = [ "serde_path_to_error", "serde_urlencoded", "sha1", - "sync_wrapper 1.0.1", + "sync_wrapper 1.0.2", "tokio", "tokio-tungstenite 0.24.0", "tower 0.5.1", @@ -824,13 +831,13 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http 1.1.0", + "http 1.2.0", "http-body 1.0.1", "http-body-util", "mime", "pin-project-lite", "rustversion", - "sync_wrapper 1.0.1", + "sync_wrapper 1.0.2", "tower-layer", "tower-service", "tracing", @@ -838,25 +845,26 @@ dependencies = [ [[package]] name = "axum-extra" -version = "0.9.4" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73c3220b188aea709cf1b6c5f9b01c3bd936bb08bd2b5184a12b35ac8131b1f9" +checksum = "c794b30c904f0a1c2fb7740f7df7f7972dfaa14ef6f57cb6178dc63e5dca2f04" dependencies = [ - "axum 0.7.7", + "axum 0.7.9", "axum-core 0.4.5", "bytes", + "fastrand", "futures-util", "headers", - "http 1.1.0", + "http 1.2.0", "http-body 1.0.1", "http-body-util", "mime", + "multer", "pin-project-lite", "serde", "tower 0.5.1", "tower-layer", "tower-service", - "tracing", ] [[package]] @@ -867,7 +875,7 @@ checksum = "57d123550fa8d071b7255cb0cc04dc302baa6c8c4a79f55701552684d8399bce" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -876,11 +884,11 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b683cbc43010e9a3d72c2f31ca464155ff4f95819e88a32924b0f47a43898978" dependencies = [ - "axum 0.7.7", + "axum 0.7.9", "bytes", "futures", "futures-core", - "http 1.1.0", + "http 1.2.0", "http-body 1.0.1", "matchit", "metrics", @@ -1042,9 +1050,9 @@ dependencies = [ [[package]] name = "blake3" -version = "1.5.1" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30cca6d3674597c30ddf2c587bf8d9d65c9a84d2326d941cc79c9842dfe0ef52" +checksum = "b8ee0c1824c4dea5b5f81736aff91bae041d2c07ee1192bec91054e10e3e601e" dependencies = [ "arrayref", "arrayvec", @@ -1101,11 +1109,11 @@ dependencies = [ [[package]] name = "borsh" -version = "1.5.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6362ed55def622cddc70a4746a68554d7b687713770de539e59a739b249f8ed" +checksum = "2506947f73ad44e344215ccd6403ac2ae18cd8e046e581a441bf8d199f257f03" dependencies = [ - "borsh-derive 1.5.1", + "borsh-derive 1.5.3", "cfg_aliases 0.2.1", ] @@ -1137,16 +1145,15 @@ dependencies = [ [[package]] name = "borsh-derive" -version = "1.5.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ef8005764f53cd4dca619f5bf64cafd4664dada50ece25e4d81de54c80cc0b" +checksum = "c2593a3b8b938bd68373196c9832f516be11fa487ef4ae745eb282e6a56a7244" dependencies = [ "once_cell", "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.79", - "syn_derive", + "syn 2.0.90", ] [[package]] @@ -1195,9 +1202,9 @@ dependencies = [ [[package]] name = "brotli" -version = "6.0.0" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b" +checksum = "cc97b8f16f944bba54f0433f07e30be199b6dc2bd25937444bbad560bcea29bd" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -1254,22 +1261,22 @@ checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" [[package]] name = "bytemuck" -version = "1.18.0" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae" +checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" -version = "1.7.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc8b54b395f2fcfbb3d90c47b01c7f444d94d05bdeb775811dec868ac3bbc26" +checksum = "bcfcc3cd946cb52f0bbfdbbcfa2f4e24f75ebb6c0e1002f7c25904fada18b9ec" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -1280,9 +1287,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" dependencies = [ "serde", ] @@ -1335,9 +1342,9 @@ checksum = "7b02b629252fe8ef6460461409564e2c21d0c8e77e0944f3d189ff06c4e932ad" [[package]] name = "cargo-platform" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" +checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" dependencies = [ "serde", ] @@ -1358,9 +1365,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.24" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812acba72f0a070b003d3697490d2b55b837230ae7c6c6497f05cc2ddbb8d938" +checksum = "f34d93e62b03caf570cccc334cbc6c2fceca82f39211051345108adcba3eebdc" dependencies = [ "jobserver", "libc", @@ -1421,7 +1428,7 @@ dependencies = [ "bitflags 1.3.2", "strsim 0.8.0", "textwrap 0.11.0", - "unicode-width", + "unicode-width 0.1.14", "vec_map", ] @@ -1443,9 +1450,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.18" +version = "4.5.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0956a43b323ac1afaffc053ed5c4b7c1f1800bacd1683c353aabbb752515dd3" +checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84" dependencies = [ "clap_builder", "clap_derive", @@ -1453,13 +1460,13 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.18" +version = "4.5.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d72166dd41634086d5803a47eb71ae740e61d84709c36f3c34110173db3961b" +checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838" dependencies = [ "anstream", "anstyle", - "clap_lex 0.7.2", + "clap_lex 0.7.4", "strsim 0.11.1", ] @@ -1472,7 +1479,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -1486,9 +1493,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "coins-bip32" @@ -1544,9 +1551,9 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "combine" @@ -1579,7 +1586,7 @@ dependencies = [ "encode_unicode", "lazy_static", "libc", - "unicode-width", + "unicode-width 0.1.14", "windows-sys 0.52.0", ] @@ -1605,9 +1612,9 @@ dependencies = [ [[package]] name = "const-hex" -version = "1.13.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0121754e84117e65f9d90648ee6aa4882a6e63110307ab73967a4c5e7e69e586" +checksum = "4b0485bab839b018a8f1723fc5391819fea5f8f0f32288ef8a735fd096b6160c" dependencies = [ "cfg-if", "cpufeatures", @@ -1652,9 +1659,9 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.14" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" dependencies = [ "libc", ] @@ -1808,7 +1815,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -1819,7 +1826,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -1895,13 +1902,22 @@ dependencies = [ [[package]] name = "derive_more" -version = "0.99.18" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -1987,7 +2003,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -2010,7 +2026,7 @@ checksum = "a6cbae11b3de8fce2a456e8ea3dada226b35fe791f0dc1d360c0941f0bb681f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -2134,9 +2150,9 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding_rs" -version = "0.8.34" +version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ "cfg-if", ] @@ -2176,7 +2192,7 @@ checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -2200,12 +2216,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -2348,14 +2364,14 @@ dependencies = [ "ethers-core", "ethers-etherscan", "eyre", - "prettyplease 0.2.22", + "prettyplease 0.2.25", "proc-macro2", "quote", "regex", - "reqwest", + "reqwest 0.11.27", "serde", "serde_json", - "syn 2.0.79", + "syn 2.0.90", "toml 0.8.19", "walkdir", ] @@ -2373,7 +2389,7 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -2399,7 +2415,7 @@ dependencies = [ "serde", "serde_json", "strum", - "syn 2.0.79", + "syn 2.0.90", "tempfile", "thiserror", "tiny-keccak", @@ -2414,7 +2430,7 @@ checksum = "e79e5973c26d4baf0ce55520bd732314328cabe53193286671b47144145b9649" dependencies = [ "chrono", "ethers-core", - "reqwest", + "reqwest 0.11.27", "semver", "serde", "serde_json", @@ -2439,7 +2455,7 @@ dependencies = [ "futures-locks", "futures-util", "instant", - "reqwest", + "reqwest 0.11.27", "serde", "serde_json", "thiserror", @@ -2472,7 +2488,7 @@ dependencies = [ "jsonwebtoken", "once_cell", "pin-project", - "reqwest", + "reqwest 0.11.27", "serde", "serde_json", "thiserror", @@ -2551,6 +2567,55 @@ dependencies = [ "anchor-lang", ] +[[package]] +name = "express-relay-api-types" +version = "0.1.0" +dependencies = [ + "base64 0.22.1", + "bincode", + "email_address", + "ethers", + "http 1.2.0", + "serde", + "serde_json", + "serde_with 3.11.0", + "solana-sdk", + "strum", + "time", + "utoipa", + "uuid 1.11.0", +] + +[[package]] +name = "express-relay-client" +version = "0.2.0" +dependencies = [ + "ethers", + "express-relay-api-types", + "futures-util", + "reqwest 0.12.9", + "serde", + "serde_json", + "solana-sdk", + "tokio", + "tokio-stream", + "tokio-tungstenite 0.24.0", + "url", +] + +[[package]] +name = "express-relay-simple-searcher" +version = "0.1.0" +dependencies = [ + "anyhow", + "clap 4.5.23", + "express-relay-client", + "rand 0.8.5", + "time", + "tokio", + "tokio-stream", +] + [[package]] name = "eyre" version = "0.6.12" @@ -2563,9 +2628,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" +checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" [[package]] name = "feature-probe" @@ -2603,9 +2668,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.34" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" +checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" dependencies = [ "crc32fast", "miniz_oxide", @@ -2613,9 +2678,9 @@ dependencies = [ [[package]] name = "flume" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" dependencies = [ "futures-core", "futures-sink", @@ -2670,9 +2735,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -2685,9 +2750,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -2695,15 +2760,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -2723,9 +2788,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-locks" @@ -2739,26 +2804,26 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-timer" @@ -2772,9 +2837,9 @@ dependencies = [ [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", @@ -2855,9 +2920,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.31.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "glob" @@ -2911,7 +2976,26 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.6.0", + "indexmap 2.7.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "h2" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.2.0", + "indexmap 2.7.0", "slab", "tokio", "tokio-util", @@ -2963,9 +3047,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.1" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" [[package]] name = "hashers" @@ -2994,7 +3078,7 @@ dependencies = [ "base64 0.21.7", "bytes", "headers-core", - "http 1.1.0", + "http 1.2.0", "httpdate", "mime", "sha1", @@ -3006,7 +3090,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4" dependencies = [ - "http 1.1.0", + "http 1.2.0", ] [[package]] @@ -3121,9 +3205,9 @@ dependencies = [ [[package]] name = "http" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" dependencies = [ "bytes", "fnv", @@ -3148,7 +3232,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.1.0", + "http 1.2.0", ] [[package]] @@ -3159,7 +3243,7 @@ checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", "futures-util", - "http 1.1.0", + "http 1.2.0", "http-body 1.0.1", "pin-project-lite", ] @@ -3184,15 +3268,15 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.30" +version = "0.14.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" +checksum = "8c08302e8fa335b151b788c775ff56e7a03ae64ff85c548ee820fecb70356e85" dependencies = [ "bytes", "futures-channel", "futures-core", "futures-util", - "h2", + "h2 0.3.26", "http 0.2.12", "http-body 0.4.6", "httparse", @@ -3208,14 +3292,15 @@ dependencies = [ [[package]] name = "hyper" -version = "1.4.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" +checksum = "97818827ef4f364230e16705d4706e2897df2bb60617d6ca15d598025a3c481f" dependencies = [ "bytes", "futures-channel", "futures-util", - "http 1.1.0", + "h2 0.4.7", + "http 1.2.0", "http-body 1.0.1", "httparse", "httpdate", @@ -3223,6 +3308,7 @@ dependencies = [ "pin-project-lite", "smallvec", "tokio", + "want", ] [[package]] @@ -3233,10 +3319,27 @@ checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", "http 0.2.12", - "hyper 0.14.30", - "rustls", + "hyper 0.14.31", + "rustls 0.21.12", + "tokio", + "tokio-rustls 0.24.1", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" +dependencies = [ + "futures-util", + "http 1.2.0", + "hyper 1.5.1", + "hyper-util", + "rustls 0.23.19", + "rustls-pki-types", "tokio", - "tokio-rustls", + "tokio-rustls 0.26.1", + "tower-service", ] [[package]] @@ -3245,7 +3348,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" dependencies = [ - "hyper 0.14.30", + "hyper 0.14.31", "pin-project-lite", "tokio", "tokio-io-timeout", @@ -3258,26 +3361,45 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes", - "hyper 0.14.30", + "hyper 0.14.31", "native-tls", "tokio", "tokio-native-tls", ] +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper 1.5.1", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + [[package]] name = "hyper-util" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b" +checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" dependencies = [ "bytes", + "futures-channel", "futures-util", - "http 1.1.0", + "http 1.2.0", "http-body 1.0.1", - "hyper 1.4.1", + "hyper 1.5.1", "pin-project-lite", + "socket2", "tokio", "tower-service", + "tracing", ] [[package]] @@ -3303,6 +3425,124 @@ dependencies = [ "cc", ] +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -3311,12 +3551,23 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.5.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", ] [[package]] @@ -3364,13 +3615,13 @@ dependencies = [ [[package]] name = "impl-trait-for-tuples" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.90", ] [[package]] @@ -3392,26 +3643,26 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" dependencies = [ "equivalent", - "hashbrown 0.15.1", + "hashbrown 0.15.2", "serde", ] [[package]] name = "indicatif" -version = "0.17.8" +version = "0.17.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" +checksum = "cbf675b85ed934d3c67b5c5469701eec7db22689d0a2139d856e0925fa28b281" dependencies = [ "console", - "instant", "number_prefix", "portable-atomic", - "unicode-width", + "unicode-width 0.2.0", + "web-time", ] [[package]] @@ -3434,9 +3685,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.10.0" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4" +checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" [[package]] name = "is_terminal_polyfill" @@ -3473,9 +3724,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "jobserver" @@ -3488,10 +3739,11 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.70" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +checksum = "a865e038f7f6ed956f788f0d7d60c541fff74c7bd74272c5d4cf15c63743e705" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -3574,7 +3826,7 @@ version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "507460a910eb7b32ee961886ff48539633b788a36b65692b95f225b844c82553" dependencies = [ - "regex-automata 0.4.8", + "regex-automata 0.4.9", ] [[package]] @@ -3588,15 +3840,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.159" +version = "0.2.167" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" +checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc" [[package]] name = "libm" -version = "0.2.8" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" [[package]] name = "libredox" @@ -3685,6 +3937,12 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "litemap" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" + [[package]] name = "litesvm" version = "0.3.0" @@ -3692,7 +3950,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9cbd70cde50f7b729040472450d3be61c5dd6b8066022e438634de66df13cba9" dependencies = [ "bincode", - "indexmap 2.6.0", + "indexmap 2.7.0", "itertools 0.12.1", "log", "solana-address-lookup-table-program", @@ -3701,7 +3959,7 @@ dependencies = [ "solana-compute-budget-program", "solana-config-program", "solana-loader-v4-program", - "solana-program 2.0.13", + "solana-program 2.0.18", "solana-program-runtime", "solana-runtime-transaction", "solana-sdk", @@ -3806,8 +4064,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bf4e7146e30ad172c42c39b3246864bd2d3c6396780711a1baf749cfe423e21" dependencies = [ "base64 0.21.7", - "hyper 0.14.30", - "indexmap 2.6.0", + "hyper 0.14.31", + "indexmap 2.7.0", "ipnet", "metrics", "metrics-util", @@ -3864,16 +4122,32 @@ dependencies = [ [[package]] name = "mio" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ - "hermit-abi 0.3.9", "libc", "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.52.0", ] +[[package]] +name = "multer" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b" +dependencies = [ + "bytes", + "encoding_rs", + "futures-util", + "http 1.2.0", + "httparse", + "memchr", + "mime", + "spin 0.9.8", + "version_check", +] + [[package]] name = "multimap" version = "0.8.3" @@ -4012,7 +4286,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -4085,7 +4359,7 @@ dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -4096,9 +4370,9 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "object" -version = "0.36.4" +version = "0.36.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ "memchr", ] @@ -4114,12 +4388,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.1" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1" -dependencies = [ - "portable-atomic", -] +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "opaque-debug" @@ -4154,9 +4425,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.66" +version = "0.10.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" +checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" dependencies = [ "bitflags 2.6.0", "cfg-if", @@ -4175,7 +4446,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -4186,9 +4457,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.103" +version = "0.9.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" +checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" dependencies = [ "cc", "libc", @@ -4270,9 +4541,9 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "ordered-float" -version = "4.3.0" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d501f1a72f71d3c063a6bbc8f7271fa73aa09fe5d6283b6571e2ed176a2537" +checksum = "c65ee1f9701bf938026630b455d5315f490640234259037edb259798b3bcf85e" dependencies = [ "num-traits", ] @@ -4432,7 +4703,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.6.0", + "indexmap 2.7.0", ] [[package]] @@ -4475,7 +4746,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -4498,29 +4769,29 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.5" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.5" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" [[package]] name = "pin-utils" @@ -4575,9 +4846,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" +checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" [[package]] name = "powerfmt" @@ -4612,12 +4883,12 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.22" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba" +checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" dependencies = [ "proc-macro2", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -4678,9 +4949,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] @@ -4766,7 +5037,7 @@ dependencies = [ "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -4795,7 +5066,7 @@ checksum = "9e2e25ee72f5b24d773cae88422baddefff7714f97aab68d96fe2b6fc4a28fb2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -4824,7 +5095,7 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash", - "rustls", + "rustls 0.21.12", "thiserror", "tokio", "tracing", @@ -4840,7 +5111,7 @@ dependencies = [ "rand 0.8.5", "ring 0.16.20", "rustc-hash", - "rustls", + "rustls 0.21.12", "rustls-native-certs", "slab", "thiserror", @@ -4967,9 +5238,9 @@ dependencies = [ [[package]] name = "raw-cpuid" -version = "11.1.0" +version = "11.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb9ee317cfe3fbd54b36a511efc1edd42e216903c9cd575e686dd68a2ba90d8d" +checksum = "1ab240315c661615f2ee9f0f2cd32d5a7343a84d5ebcccb99d46e6637565e7b0" dependencies = [ "bitflags 2.6.0", ] @@ -5016,13 +5287,13 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.8", + "regex-automata 0.4.9", "regex-syntax 0.8.5", ] @@ -5037,9 +5308,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -5070,12 +5341,12 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2", + "h2 0.3.26", "http 0.2.12", "http-body 0.4.6", - "hyper 0.14.30", - "hyper-rustls", - "hyper-tls", + "hyper 0.14.31", + "hyper-rustls 0.24.2", + "hyper-tls 0.5.0", "ipnet", "js-sys", "log", @@ -5085,16 +5356,16 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls", - "rustls-pemfile", + "rustls 0.21.12", + "rustls-pemfile 1.0.4", "serde", "serde_json", "serde_urlencoded", "sync_wrapper 0.1.2", - "system-configuration", + "system-configuration 0.5.1", "tokio", "tokio-native-tls", - "tokio-rustls", + "tokio-rustls 0.24.1", "tokio-util", "tower-service", "url", @@ -5105,6 +5376,49 @@ dependencies = [ "winreg", ] +[[package]] +name = "reqwest" +version = "0.12.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f" +dependencies = [ + "base64 0.22.1", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2 0.4.7", + "http 1.2.0", + "http-body 1.0.1", + "http-body-util", + "hyper 1.5.1", + "hyper-rustls 0.27.3", + "hyper-tls 0.6.0", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile 2.2.0", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 1.0.2", + "system-configuration 0.6.1", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows-registry", +] + [[package]] name = "reqwest-middleware" version = "0.2.5" @@ -5114,7 +5428,7 @@ dependencies = [ "anyhow", "async-trait", "http 0.2.12", - "reqwest", + "reqwest 0.11.27", "serde", "task-local-extensions", "thiserror", @@ -5204,9 +5518,9 @@ dependencies = [ [[package]] name = "rsa" -version = "0.9.6" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" +checksum = "47c75d7c5c6b673e58bf54d8544a9f432e3a925b0e80f7cd3602ab5c50c55519" dependencies = [ "const-oid", "digest 0.10.7", @@ -5270,9 +5584,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.37" +version = "0.38.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" dependencies = [ "bitflags 2.6.0", "errno", @@ -5289,10 +5603,23 @@ checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ "log", "ring 0.17.8", - "rustls-webpki", + "rustls-webpki 0.101.7", "sct", ] +[[package]] +name = "rustls" +version = "0.23.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "934b404430bb06b3fae2cba809eb45a1ab1aecd64491213d7c3301b88393f8d1" +dependencies = [ + "once_cell", + "rustls-pki-types", + "rustls-webpki 0.102.8", + "subtle", + "zeroize", +] + [[package]] name = "rustls-native-certs" version = "0.6.3" @@ -5300,7 +5627,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ "openssl-probe", - "rustls-pemfile", + "rustls-pemfile 1.0.4", "schannel", "security-framework", ] @@ -5314,6 +5641,21 @@ dependencies = [ "base64 0.21.7", ] +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" + [[package]] name = "rustls-webpki" version = "0.101.7" @@ -5324,11 +5666,22 @@ dependencies = [ "untrusted 0.9.0", ] +[[package]] +name = "rustls-webpki" +version = "0.102.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +dependencies = [ + "ring 0.17.8", + "rustls-pki-types", + "untrusted 0.9.0", +] + [[package]] name = "rustversion" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" [[package]] name = "ryu" @@ -5356,9 +5709,9 @@ dependencies = [ [[package]] name = "scale-info" -version = "2.11.3" +version = "2.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca070c12893629e2cc820a9761bedf6ce1dcddc9852984d1dc734b8bd9bd024" +checksum = "346a3b32eba2640d17a9cb5927056b08f3de90f65b72fe09402c2ad07d684d0b" dependencies = [ "cfg-if", "derive_more", @@ -5368,21 +5721,21 @@ dependencies = [ [[package]] name = "scale-info-derive" -version = "2.11.3" +version = "2.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d35494501194174bda522a32605929eefc9ecf7e0a326c26db1fdd85881eb62" +checksum = "c6630024bf739e2179b91fb424b28898baf819414262c5d376677dbff1fe7ebf" dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.90", ] [[package]] name = "schannel" -version = "0.1.24" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9aaafd5a2b6e3d657ff009d82fbd630b6bd54dd4eb06f21693925cdf80f9b8b" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" dependencies = [ "windows-sys 0.59.0", ] @@ -5410,7 +5763,7 @@ checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -5464,9 +5817,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.12.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea4a292869320c0272d7bc55a5a6aafaff59b4f63404a003887b679a2e05b4b6" +checksum = "fa39c7303dc58b5543c94d22c1766b0d31f2ee58306363ea622b10bbc075eaa2" dependencies = [ "core-foundation-sys", "libc", @@ -5495,9 +5848,9 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.210" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] @@ -5513,20 +5866,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.210" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] name = "serde_json" -version = "1.0.128" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", "memchr", @@ -5577,19 +5930,19 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.9.0" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cecfa94848272156ea67b2b1a53f20fc7bc638c4a46d2f8abde08f05f4b857" +checksum = "8e28bdad6db2b8340e449f7108f020b3b092e8583a9e3fb82713e1d4e71fe817" dependencies = [ "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.6.0", + "indexmap 2.7.0", "serde", "serde_derive", "serde_json", - "serde_with_macros 3.9.0", + "serde_with_macros 3.11.0", "time", ] @@ -5602,19 +5955,19 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] name = "serde_with_macros" -version = "3.9.0" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8fee4991ef4f274617a51ad4af30519438dacb2f56ac773b08a1922ff743350" +checksum = "9d846214a9854ef724f3da161b426242d8de7c1fc7de2f89bb1efcb154dca79d" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -5623,7 +5976,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.7.0", "itoa", "ryu", "serde", @@ -5784,9 +6137,9 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" dependencies = [ "libc", "windows-sys 0.52.0", @@ -5794,9 +6147,9 @@ dependencies = [ [[package]] name = "solana-account-decoder" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d87c6ef8c13eb759fa8d887e12c67afd851799050b6afd501a27726551f52e" +checksum = "5c4e77c6e0b4e1557e738239cfbc18e92412ad393707bfa3f0861a7dd39cbc43" dependencies = [ "Inflector", "base64 0.22.1", @@ -5819,9 +6172,9 @@ dependencies = [ [[package]] name = "solana-address-lookup-table-program" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cfb847bf375f662ecad6082eaad747980416de6d74c4137f434a830f935ce7b" +checksum = "ef57ef3fc089244b13e6264adc6bf41debf009b00c9abd7e966c8146438f6a16" dependencies = [ "bincode", "bytemuck", @@ -5829,7 +6182,7 @@ dependencies = [ "num-derive", "num-traits", "rustc_version", - "solana-program 2.0.13", + "solana-program 2.0.18", "solana-program-runtime", "solana-sdk", "thiserror", @@ -5837,9 +6190,9 @@ dependencies = [ [[package]] name = "solana-bpf-loader-program" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d08fcde4e079069484b54aa7f1d2ec10763b1b271a7166f1ce363db318ff8ed2" +checksum = "d457443290682cbedd67658a88b14cff0cbe5397b3965cce4d2dd1114a4fd1f2" dependencies = [ "bincode", "byteorder", @@ -5859,9 +6212,9 @@ dependencies = [ [[package]] name = "solana-clap-utils" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f9709683a4d480a0185827292405cad0b6f414abaa479c7d1dfe5e2194aeec8" +checksum = "5bf1b072aaa7a8dff7ca2bf9c3282709f9073e91b6f37893dc6b7fef00c255ee" dependencies = [ "chrono", "clap 2.34.0", @@ -5876,16 +6229,16 @@ dependencies = [ [[package]] name = "solana-client" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67169e4f1faabb717ce81b5ca93960da21e3ac5c9b75cb6792f9b3ce38db459f" +checksum = "f917c11704664034e014be907f6521b4043de3d99e0070a54b6973d2917608ae" dependencies = [ "async-trait", "bincode", "dashmap", "futures", "futures-util", - "indexmap 2.6.0", + "indexmap 2.7.0", "indicatif", "log", "quinn", @@ -5909,9 +6262,9 @@ dependencies = [ [[package]] name = "solana-compute-budget" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5acde49a883ca3e099a8050ad8321ea56b02041995dadcf84b0dab14561cc34a" +checksum = "9c04e01f296142c78d36be3f53da362b71a605d2f7a3c3d98f1c943403ce5581" dependencies = [ "rustc_version", "solana-sdk", @@ -5919,9 +6272,9 @@ dependencies = [ [[package]] name = "solana-compute-budget-program" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d9a4850f254e23a6306a8eafa7bf8ecaf05d907d18b31ff096ea63f4c5ab32" +checksum = "5a249ea7d82e7b57080b6aea8f00a51b888fb4d4c597979dbc9ee5fa6adc1ed4" dependencies = [ "solana-program-runtime", "solana-sdk", @@ -5929,9 +6282,9 @@ dependencies = [ [[package]] name = "solana-config-program" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f638e44fb308bdc1ce99eb0fee194b2cb212917b258999cdb4a8b056d48973d4" +checksum = "71169087810ede13cf2bd58f59293b45efbff7ea272a8b726dfa6c0c355d63da" dependencies = [ "bincode", "chrono", @@ -5943,15 +6296,15 @@ dependencies = [ [[package]] name = "solana-connection-cache" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fd01a4d43b780996970cb3669946b002f71d34e6a26a19bd6d2a74513ecc0aa" +checksum = "10ac7233d608907a23f24dff56561e40f684332c24255e47b3d0fa11ddafd1b8" dependencies = [ "async-trait", "bincode", "crossbeam-channel", "futures-util", - "indexmap 2.6.0", + "indexmap 2.7.0", "log", "rand 0.8.5", "rayon", @@ -5964,22 +6317,22 @@ dependencies = [ [[package]] name = "solana-curve25519" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44b61d8eda3319deca3627e3eb3970ce2ad179ad39c106d6c003d06c90e3031d" +checksum = "c94998b7dd9eb9e356e2fbe57955dcaaeca8f22f62de50bff9c3c73bcc700f57" dependencies = [ "bytemuck", "bytemuck_derive", "curve25519-dalek", - "solana-program 2.0.13", + "solana-program 2.0.18", "thiserror", ] [[package]] name = "solana-frozen-abi" -version = "1.18.23" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bfcde2fc6946c99c7e3400fadd04d1628d675bfd66cb34d461c0f3224bd27d1" +checksum = "03ab2c30c15311b511c0d1151e4ab6bc9a3e080a37e7c6e7c2d96f5784cf9434" dependencies = [ "block-buffer 0.10.4", "bs58 0.4.0", @@ -6002,21 +6355,21 @@ dependencies = [ [[package]] name = "solana-frozen-abi-macro" -version = "1.18.23" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5024d241425f4e99f112ee03bfa89e526c86c7ca9bd7e13448a7f2dffb7e060" +checksum = "c142f779c3633ac83c84d04ff06c70e1f558c876f13358bed77ba629c7417932" dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] name = "solana-inline-spl" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6614014b976112fb6c9bf259f87c6659b8fdea628c656639e02211324d2b34" +checksum = "501e25b91ebb2c1ab7360111be8c0ff8c70e17609a1c2e58c9762ffd29d88f28" dependencies = [ "bytemuck", "rustc_version", @@ -6025,9 +6378,9 @@ dependencies = [ [[package]] name = "solana-loader-v4-program" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7866a1140ceb81de5b82bd779b0c63f888904574da128dd40bc17795be6f084" +checksum = "18bd1e3fc63c7863dc507e41bf44175ff61945de4aa7dbcd12c3b8a688f1983f" dependencies = [ "log", "solana-compute-budget", @@ -6040,9 +6393,9 @@ dependencies = [ [[package]] name = "solana-logger" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6b996befdb2bdbd816524fc7afe0e158fced33ff61c36ab29ae803c0462455d" +checksum = "dcc155d62e0639b392216d33ce0382e5cd53a855cfaf3a988c0a72fdfc721b2d" dependencies = [ "env_logger", "lazy_static", @@ -6051,9 +6404,9 @@ dependencies = [ [[package]] name = "solana-measure" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79d44cdbcf9e1489564cdae1cd92b8806b0ee89d05d36a58fef8c0d293ea7c2a" +checksum = "1d8d2d32b3ea5dd96af0c5201bb2b139eee3fb8a7a42a614e0d4a09715a36527" dependencies = [ "log", "solana-sdk", @@ -6061,24 +6414,24 @@ dependencies = [ [[package]] name = "solana-metrics" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68979964a3a004f1af4f1571814817e7e050ef4c1b2a1bdaa3ff35e980072d69" +checksum = "6e174b0ee130287ede3caf28de3f6cd2f527d113ed7ccb1ccbbae716d1a3dda8" dependencies = [ "crossbeam-channel", "gethostname", "lazy_static", "log", - "reqwest", + "reqwest 0.11.27", "solana-sdk", "thiserror", ] [[package]] name = "solana-net-utils" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44bb419eb9293a277982cf14a58772e9b9ab30ff6f9421bc4ac0826d40122760" +checksum = "37a483ec43bb378872f9039b4918d5b9f54958d08c36d08b570b37dc856b2fd6" dependencies = [ "bincode", "clap 3.2.25", @@ -6099,9 +6452,9 @@ dependencies = [ [[package]] name = "solana-perf" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00c4128122787a61d8f94fdaa04cb71b3dbb017d9939ac4d632264c55ec345de" +checksum = "9dacc3f47906dc79daf87d13b0410d04348feef19731ce4605a76151c1d47513" dependencies = [ "ahash 0.8.11", "bincode", @@ -6126,9 +6479,9 @@ dependencies = [ [[package]] name = "solana-poseidon" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16cd1ecbbefa2e160f4c82734c2f38315005e1d8c3ddbdb20bfa50ea92264fdc" +checksum = "83562578a9f967e05886400598ca99b8e0c3a14f12337009bbc02954c7cff097" dependencies = [ "ark-bn254", "light-poseidon", @@ -6137,9 +6490,9 @@ dependencies = [ [[package]] name = "solana-program" -version = "1.18.23" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76056fecde0fe0ece8b457b719729c17173333471c72ad41969982975a10d6e0" +checksum = "c10f4588cefd716b24a1a40dd32c278e43a560ab8ce4de6b5805c9d113afdfa1" dependencies = [ "ark-bn254", "ark-ec", @@ -6151,7 +6504,7 @@ dependencies = [ "blake3", "borsh 0.10.4", "borsh 0.9.3", - "borsh 1.5.1", + "borsh 1.5.3", "bs58 0.4.0", "bv", "bytemuck", @@ -6183,7 +6536,7 @@ dependencies = [ "sha3 0.10.8", "solana-frozen-abi", "solana-frozen-abi-macro", - "solana-sdk-macro 1.18.23", + "solana-sdk-macro 1.18.26", "thiserror", "tiny-bip39", "wasm-bindgen", @@ -6192,9 +6545,9 @@ dependencies = [ [[package]] name = "solana-program" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29249ce5b5c7bd018013adbb97439b0b1b986f16bb07c54db28f82e97baaa2f1" +checksum = "549e1d73169e3b55ca832d498de82590df9a19a486318841c7ccddf755abdc00" dependencies = [ "ark-bn254", "ark-ec", @@ -6205,7 +6558,7 @@ dependencies = [ "bitflags 2.6.0", "blake3", "borsh 0.10.4", - "borsh 1.5.1", + "borsh 1.5.3", "bs58 0.5.1", "bv", "bytemuck", @@ -6231,16 +6584,16 @@ dependencies = [ "serde_derive", "sha2 0.10.8", "sha3 0.10.8", - "solana-sdk-macro 2.0.13", + "solana-sdk-macro 2.0.18", "thiserror", "wasm-bindgen", ] [[package]] name = "solana-program-runtime" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "948bfeb10ba38b55a8b2db2de8ccfa8f57b44b6d73c98e8e0de8b10f10ce043b" +checksum = "d8650cd041818feffda703dd174db3d17b25f2fdb658017ede33e30ff37f2eff" dependencies = [ "base64 0.22.1", "bincode", @@ -6267,14 +6620,14 @@ dependencies = [ [[package]] name = "solana-pubsub-client" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ce9fa94ef00f7dfec749fc6835a4c36e8cfa2166c4a80736af1b49ef5bcd8e" +checksum = "31ec53c4242da7ebf1b5ae9e45d0873b8b8211a1e7844b96cf506de9a719e1b6" dependencies = [ "crossbeam-channel", "futures-util", "log", - "reqwest", + "reqwest 0.11.27", "semver", "serde", "serde_derive", @@ -6292,9 +6645,9 @@ dependencies = [ [[package]] name = "solana-quic-client" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00764a5e5e36a94515d05f771e869c920671f5753cfc71ebf366546c891450b4" +checksum = "6a4cb1dcaad54f04f7f7c646f6498c282fe70dbd9a1dc0fed7d3fbf3e80962c5" dependencies = [ "async-mutex", "async-trait", @@ -6304,7 +6657,7 @@ dependencies = [ "log", "quinn", "quinn-proto", - "rustls", + "rustls 0.21.12", "solana-connection-cache", "solana-measure", "solana-metrics", @@ -6318,9 +6671,9 @@ dependencies = [ [[package]] name = "solana-rayon-threadlimit" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33119350281687a17a8321f897dfd27009fc862711ee6555c26beb5b84d6c08c" +checksum = "8a204511aa5d584bdee09d3cb07d09e357a3ecaf088cbadd24884ffc0b2969f7" dependencies = [ "lazy_static", "num_cpus", @@ -6328,9 +6681,9 @@ dependencies = [ [[package]] name = "solana-remote-wallet" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aba8725448426110b9ac20d7256f43aad1ea46458fe35c63d174cf962af4a9d0" +checksum = "d79f371cf119bc23ab78176256a2f18de72a7ebda83d28730e85ae46009768b8" dependencies = [ "console", "dialoguer", @@ -6347,9 +6700,9 @@ dependencies = [ [[package]] name = "solana-rpc-client" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd96f6a505a492544ee2459b608af3fe07da6c8ffc0bd842489e836ac2c3fce6" +checksum = "350c5b759e03eced58de2ac44c2bba5e56f6a07c1f28a50db56bfdd5a0899718" dependencies = [ "async-trait", "base64 0.22.1", @@ -6357,7 +6710,7 @@ dependencies = [ "bs58 0.5.1", "indicatif", "log", - "reqwest", + "reqwest 0.11.27", "reqwest-middleware", "semver", "serde", @@ -6374,15 +6727,15 @@ dependencies = [ [[package]] name = "solana-rpc-client-api" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d04f79b88c53b675d5d885d498e7a7e6a4fdd60ffe56e543faddb5d94c6094ba" +checksum = "59b44d991c6c9235adc436f545dad56a90b3bfa78dc831e17823685203f5dd8d" dependencies = [ "anyhow", "base64 0.22.1", "bs58 0.5.1", "jsonrpc-core", - "reqwest", + "reqwest 0.11.27", "reqwest-middleware", "semver", "serde", @@ -6398,9 +6751,9 @@ dependencies = [ [[package]] name = "solana-rpc-client-nonce-utils" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d46d162566cbf7d6eb2ae369fbb8a934bc846906cbe959aed9123c1ac92b85" +checksum = "1ef45103503bbc500dfe74fdc15a8f39cc2238d8888adb60fc6c482322ba3114" dependencies = [ "clap 2.34.0", "solana-clap-utils", @@ -6411,9 +6764,9 @@ dependencies = [ [[package]] name = "solana-runtime-transaction" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109f2151838ae4b6264857d06b0eaff55392690f24796d4468fbd7126a843a75" +checksum = "4e4b5dc04c2b9bcb4fed862da1b3bb9c1b2edfc7f2002b0c2de9e450f42e38ad" dependencies = [ "log", "rustc_version", @@ -6424,13 +6777,13 @@ dependencies = [ [[package]] name = "solana-sdk" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24dae5bda29858add4df3a6c5eaf71c0d2042ca3317a9fd81d7e9f436278a1fe" +checksum = "eb4f2423204dc2ce50d0d17a7594bab1f247351699d7ad6b3cf562c76b92139a" dependencies = [ "bincode", "bitflags 2.6.0", - "borsh 1.5.1", + "borsh 1.5.3", "bs58 0.5.1", "bytemuck", "bytemuck_derive", @@ -6464,8 +6817,8 @@ dependencies = [ "sha2 0.10.8", "sha3 0.10.8", "siphasher", - "solana-program 2.0.13", - "solana-sdk-macro 2.0.13", + "solana-program 2.0.18", + "solana-sdk-macro 2.0.18", "thiserror", "uriparse", "wasm-bindgen", @@ -6473,28 +6826,28 @@ dependencies = [ [[package]] name = "solana-sdk-macro" -version = "1.18.23" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a8613ca80150f7e277e773620ba65d2c5fcc3a08eb8026627d601421ab43aef" +checksum = "1b75d0f193a27719257af19144fdaebec0415d1c9e9226ae4bd29b791be5e9bd" dependencies = [ "bs58 0.4.0", "proc-macro2", "quote", "rustversion", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] name = "solana-sdk-macro" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "704c9cacc61a5b9b6f717773cf4b3b45a4239dc7fa8c585258fceaf9b8e1cb94" +checksum = "879caa7c8d816376bc9d11a76d7897c243d865d51cb03653e2e1dd5f5245d457" dependencies = [ "bs58 0.5.1", "proc-macro2", "quote", "rustversion", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -6505,9 +6858,9 @@ checksum = "468aa43b7edb1f9b7b7b686d5c3aeb6630dc1708e86e31343499dd5c4d775183" [[package]] name = "solana-stake-program" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4601cba95c3aaebc3e3698d69c21fe128dcfb6ed08c98f0a6ee5184f25dd239" +checksum = "ce125d4309f59e64186dbc2927654f88ecd2974f566a15bcfe33e2a52179bb20" dependencies = [ "bincode", "log", @@ -6521,9 +6874,9 @@ dependencies = [ [[package]] name = "solana-streamer" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cf77ab19483dce4b4307c9e6f195a8c52f0c219026b78af3a9fae1e63ba9222" +checksum = "b20abcd941eb5d5c3f517eb92689eb74e2dfdd717886e004cd57d0441566c5f9" dependencies = [ "async-channel", "bytes", @@ -6531,7 +6884,7 @@ dependencies = [ "dashmap", "futures-util", "histogram", - "indexmap 2.6.0", + "indexmap 2.7.0", "itertools 0.12.1", "libc", "log", @@ -6541,7 +6894,7 @@ dependencies = [ "quinn", "quinn-proto", "rand 0.8.5", - "rustls", + "rustls 0.21.12", "smallvec", "solana-measure", "solana-metrics", @@ -6555,9 +6908,9 @@ dependencies = [ [[package]] name = "solana-svm" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3881ad0f09d36146d3eebb625b36f8b823dd9ced9f93e8c72f9fdc8b4b09dc76" +checksum = "f963d95b10176c792abecc311e52a26fb0710bf1e96fff4193870287c33c5556" dependencies = [ "itertools 0.12.1", "log", @@ -6581,9 +6934,9 @@ dependencies = [ [[package]] name = "solana-system-program" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f582c0c7b64b7ddeac4d0623d793823ff661865af67b2100ad6ad8bdadeb1f5" +checksum = "5fb6c6c1b1f11e43c34d3487aa2928581088c08bd1d4b336b3c15cc33947c517" dependencies = [ "bincode", "log", @@ -6596,9 +6949,9 @@ dependencies = [ [[package]] name = "solana-thin-client" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8c880be4e50ff473b3e82b600162244b6eb28cb5a616dc90ee9232d34998680" +checksum = "e73c21e4a598c7ccee358e99cacf85552020a8be3d108fff4f1897991092defc" dependencies = [ "bincode", "log", @@ -6611,14 +6964,14 @@ dependencies = [ [[package]] name = "solana-tpu-client" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e65c01edbca303273e735ae383dde54bd5c5b8a051c51162c0ff886b0939ec6" +checksum = "891ebe7ce4376a7c9d61947381bfea4edecf8571f5e9eb916c875e64228daefd" dependencies = [ "async-trait", "bincode", "futures-util", - "indexmap 2.6.0", + "indexmap 2.7.0", "indicatif", "log", "rayon", @@ -6635,9 +6988,9 @@ dependencies = [ [[package]] name = "solana-transaction-metrics-tracker" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44727bef1f8c57a6ed9a74761d8b7ddfcf4b4e2237cbcc5dc7f8f59985e07755" +checksum = "74b9f313515f868e99636ced0ad7be2cb9c018b08dd760a5d3a958e8da736413" dependencies = [ "Inflector", "base64 0.22.1", @@ -6651,14 +7004,14 @@ dependencies = [ [[package]] name = "solana-transaction-status" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51d9d4a6004708f9563a29aa87fdf9960c1e7420b69dd82e8b817cf8f02430b" +checksum = "04f45de90e145dcce7b99922e1d35de88612211b7d616e3c57baa64e7c7af9b6" dependencies = [ "Inflector", "base64 0.22.1", "bincode", - "borsh 1.5.1", + "borsh 1.5.3", "bs58 0.5.1", "lazy_static", "log", @@ -6678,9 +7031,9 @@ dependencies = [ [[package]] name = "solana-type-overrides" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab21276d6296965dc7181d785075b20e97b6789c76e8376cf363b3e2f7439b6" +checksum = "b381201d14e9677e11ae61fae614da4765e9a59f078b9c46c3e6c3dc1cd903f9" dependencies = [ "lazy_static", "rand 0.8.5", @@ -6688,9 +7041,9 @@ dependencies = [ [[package]] name = "solana-udp-client" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10e902d4dc29cafc0794073805a2db1b48b818251480a9fbaec3959df72aec2f" +checksum = "d26a1dc0a1aea6da11be7774f1c4ad240b89045600c95437a9f34c48eac758cd" dependencies = [ "async-trait", "solana-connection-cache", @@ -6703,9 +7056,9 @@ dependencies = [ [[package]] name = "solana-version" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bcbc570264e5a61a8f84439dfc254931460769fedfb91ff16253acfc3644c9d" +checksum = "815b3a6d5411f06ab5b9cfc4c9a3b983537c7f0b5c3b560e71305f493ddc6999" dependencies = [ "log", "rustc_version", @@ -6717,9 +7070,9 @@ dependencies = [ [[package]] name = "solana-vote" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fa1401a42023379f14af9165954f44ad02888a327dfd2a4abce0f18fa7cfab9" +checksum = "ac76c326bb4e8a73df482a9afa88bbaafa0a78a307835ffa1e5c2fe09bf839f5" dependencies = [ "itertools 0.12.1", "log", @@ -6732,9 +7085,9 @@ dependencies = [ [[package]] name = "solana-vote-program" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfd8e539a9963c2914ff8426dfe92351a902892aea465cd507e36d638ca0b7d6" +checksum = "ce6857a073f5a3563919d0301600e47d7b62259f3fae76bf08c16703e105b77c" dependencies = [ "bincode", "log", @@ -6744,7 +7097,7 @@ dependencies = [ "serde", "serde_derive", "solana-metrics", - "solana-program 2.0.13", + "solana-program 2.0.18", "solana-program-runtime", "solana-sdk", "thiserror", @@ -6752,9 +7105,9 @@ dependencies = [ [[package]] name = "solana-zk-token-sdk" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1dd7a8d6843cb3de4c13c2cfec1994519735ea4110b7f36b80b41d57bea1c07" +checksum = "818713988d1257168a84cf2c3cda06df7b092da7e84192a7fb88f9c86756366d" dependencies = [ "aes-gcm-siv", "base64 0.22.1", @@ -6774,7 +7127,7 @@ dependencies = [ "serde_json", "sha3 0.9.1", "solana-curve25519", - "solana-program 2.0.13", + "solana-program 2.0.18", "solana-sdk", "subtle", "thiserror", @@ -6846,10 +7199,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68034596cf4804880d265f834af1ff2f821ad5293e41fa0f8f59086c181fc38e" dependencies = [ "assert_matches", - "borsh 1.5.1", + "borsh 1.5.3", "num-derive", "num-traits", - "solana-program 2.0.13", + "solana-program 2.0.18", "spl-token", "spl-token-2022", "thiserror", @@ -6862,7 +7215,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a38ea8b6dedb7065887f12d62ed62c1743aa70749e8558f963609793f6fb12bc" dependencies = [ "bytemuck", - "solana-program 2.0.13", + "solana-program 2.0.18", "spl-discriminator-derive", ] @@ -6874,7 +7227,7 @@ checksum = "d9e8418ea6269dcfb01c712f0444d2c75542c04448b480e87de59d2865edc750" dependencies = [ "quote", "spl-discriminator-syn", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -6886,7 +7239,7 @@ dependencies = [ "proc-macro2", "quote", "sha2 0.10.8", - "syn 2.0.79", + "syn 2.0.90", "thiserror", ] @@ -6896,7 +7249,7 @@ version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0dba2f2bb6419523405d21c301a32c9f9568354d4742552e7972af801f4bdb3" dependencies = [ - "solana-program 2.0.13", + "solana-program 2.0.18", ] [[package]] @@ -6905,10 +7258,10 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c704c88fc457fa649ba3aabe195c79d885c3f26709efaddc453c8de352c90b87" dependencies = [ - "borsh 1.5.1", + "borsh 1.5.3", "bytemuck", "bytemuck_derive", - "solana-program 2.0.13", + "solana-program 2.0.18", "solana-zk-token-sdk", "spl-program-error", ] @@ -6921,7 +7274,7 @@ checksum = "d7b28bed65356558133751cc32b48a7a5ddfc59ac4e941314630bbed1ac10532" dependencies = [ "num-derive", "num-traits", - "solana-program 2.0.13", + "solana-program 2.0.18", "spl-program-error-derive", "thiserror", ] @@ -6935,7 +7288,7 @@ dependencies = [ "proc-macro2", "quote", "sha2 0.10.8", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -6945,7 +7298,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37a75a5f0fcc58126693ed78a17042e9dc53f07e357d6be91789f7d62aff61a4" dependencies = [ "bytemuck", - "solana-program 2.0.13", + "solana-program 2.0.18", "spl-discriminator", "spl-pod", "spl-program-error", @@ -6963,7 +7316,7 @@ dependencies = [ "num-derive", "num-traits", "num_enum", - "solana-program 2.0.13", + "solana-program 2.0.18", "thiserror", ] @@ -6978,7 +7331,7 @@ dependencies = [ "num-derive", "num-traits", "num_enum", - "solana-program 2.0.13", + "solana-program 2.0.18", "solana-security-txt", "solana-zk-token-sdk", "spl-memo", @@ -6998,7 +7351,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df8752b85a5ecc1d9f3a43bce3dd9a6a053673aacf5deb513d1cbb88d3534ffd" dependencies = [ "bytemuck", - "solana-program 2.0.13", + "solana-program 2.0.18", "spl-discriminator", "spl-pod", "spl-program-error", @@ -7010,8 +7363,8 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6c2318ddff97e006ed9b1291ebec0750a78547f870f62a69c56fe3b46a5d8fc" dependencies = [ - "borsh 1.5.1", - "solana-program 2.0.13", + "borsh 1.5.3", + "solana-program 2.0.18", "spl-discriminator", "spl-pod", "spl-program-error", @@ -7026,7 +7379,7 @@ checksum = "a110f33d941275d9f868b96daaa993f1e73b6806cc8836e43075b4d3ad8338a7" dependencies = [ "arrayref", "bytemuck", - "solana-program 2.0.13", + "solana-program 2.0.18", "spl-discriminator", "spl-pod", "spl-program-error", @@ -7041,7 +7394,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bdcd73ec187bc409464c60759232e309f83b52a18a9c5610bf281c9c6432918c" dependencies = [ "bytemuck", - "solana-program 2.0.13", + "solana-program 2.0.18", "spl-discriminator", "spl-pod", "spl-program-error", @@ -7092,7 +7445,7 @@ dependencies = [ "futures-util", "hashlink", "hex", - "indexmap 2.6.0", + "indexmap 2.7.0", "log", "memchr", "native-tls", @@ -7110,7 +7463,7 @@ dependencies = [ "tokio-stream", "tracing", "url", - "uuid 1.10.0", + "uuid 1.11.0", ] [[package]] @@ -7193,7 +7546,7 @@ dependencies = [ "thiserror", "time", "tracing", - "uuid 1.10.0", + "uuid 1.11.0", "whoami", ] @@ -7235,7 +7588,7 @@ dependencies = [ "thiserror", "time", "tracing", - "uuid 1.10.0", + "uuid 1.11.0", "whoami", ] @@ -7261,9 +7614,15 @@ dependencies = [ "tracing", "url", "urlencoding", - "uuid 1.10.0", + "uuid 1.11.0", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "static_assertions" version = "1.1.0" @@ -7331,7 +7690,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -7350,7 +7709,7 @@ dependencies = [ "fs2", "hex", "once_cell", - "reqwest", + "reqwest 0.11.27", "semver", "serde", "serde_json", @@ -7373,27 +7732,15 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.79" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] -[[package]] -name = "syn_derive" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" -dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.79", -] - [[package]] name = "sync_wrapper" version = "0.1.2" @@ -7402,9 +7749,12 @@ checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] name = "sync_wrapper" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] [[package]] name = "synstructure" @@ -7418,6 +7768,17 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + [[package]] name = "system-configuration" version = "0.5.1" @@ -7426,7 +7787,18 @@ checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ "bitflags 1.3.2", "core-foundation", - "system-configuration-sys", + "system-configuration-sys 0.5.0", +] + +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags 2.6.0", + "core-foundation", + "system-configuration-sys 0.6.0", ] [[package]] @@ -7439,6 +7811,16 @@ dependencies = [ "libc", ] +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "tap" version = "1.0.1" @@ -7456,9 +7838,9 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.13.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" dependencies = [ "cfg-if", "fastrand", @@ -7493,7 +7875,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" dependencies = [ - "unicode-width", + "unicode-width 0.1.14", ] [[package]] @@ -7504,22 +7886,22 @@ checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" [[package]] name = "thiserror" -version = "1.0.64" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.64" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -7534,9 +7916,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.36" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" dependencies = [ "deranged", "itoa", @@ -7555,9 +7937,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" dependencies = [ "num-conv", "time-core", @@ -7591,6 +7973,16 @@ dependencies = [ "crunchy", ] +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tinyvec" version = "1.8.0" @@ -7608,9 +8000,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.40.0" +version = "1.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" +checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551" dependencies = [ "backtrace", "bytes", @@ -7642,7 +8034,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -7661,7 +8053,17 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls", + "rustls 0.21.12", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37" +dependencies = [ + "rustls 0.23.19", "tokio", ] @@ -7674,6 +8076,7 @@ dependencies = [ "futures-core", "pin-project-lite", "tokio", + "tokio-util", ] [[package]] @@ -7684,9 +8087,9 @@ checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" dependencies = [ "futures-util", "log", - "rustls", + "rustls 0.21.12", "tokio", - "tokio-rustls", + "tokio-rustls 0.24.1", "tungstenite 0.20.1", "webpki-roots 0.25.4", ] @@ -7699,15 +8102,17 @@ checksum = "edc5f74e248dc973e0dbb7b74c7e0d6fcc301c694ff50049504004ef4d0cdcd9" dependencies = [ "futures-util", "log", + "native-tls", "tokio", + "tokio-native-tls", "tungstenite 0.24.0", ] [[package]] name = "tokio-util" -version = "0.7.12" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" +checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" dependencies = [ "bytes", "futures-core", @@ -7754,7 +8159,7 @@ version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.7.0", "serde", "serde_spanned", "toml_datetime", @@ -7772,10 +8177,10 @@ dependencies = [ "axum 0.6.20", "base64 0.21.7", "bytes", - "h2", + "h2 0.3.26", "http 0.2.12", "http-body 0.4.6", - "hyper 0.14.30", + "hyper 0.14.31", "hyper-timeout", "percent-encoding", "pin-project", @@ -7832,7 +8237,7 @@ checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" dependencies = [ "bitflags 2.6.0", "bytes", - "http 1.1.0", + "http 1.2.0", "http-body 1.0.1", "http-body-util", "pin-project-lite", @@ -7854,9 +8259,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "log", "pin-project-lite", @@ -7866,20 +8271,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", @@ -7926,9 +8331,9 @@ dependencies = [ [[package]] name = "tracing-serde" -version = "0.1.3" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" +checksum = "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1" dependencies = [ "serde", "tracing-core", @@ -7936,9 +8341,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ "matchers", "nu-ansi-term", @@ -7974,7 +8379,7 @@ dependencies = [ "httparse", "log", "rand 0.8.5", - "rustls", + "rustls 0.21.12", "sha1", "thiserror", "url", @@ -7991,9 +8396,10 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http 1.1.0", + "http 1.2.0", "httparse", "log", + "native-tls", "rand 0.8.5", "sha1", "thiserror", @@ -8026,24 +8432,21 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unicase" -version = "2.7.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" -dependencies = [ - "version_check", -] +checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" [[package]] name = "unicode-bidi" -version = "0.3.15" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" [[package]] name = "unicode-ident" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "unicode-normalization" @@ -8072,6 +8475,12 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" +[[package]] +name = "unicode-width" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" + [[package]] name = "unicode-xid" version = "0.2.6" @@ -8133,9 +8542,9 @@ dependencies = [ [[package]] name = "url" -version = "2.5.2" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna", @@ -8154,6 +8563,18 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.2" @@ -8166,7 +8587,7 @@ version = "4.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c5afb1a60e207dca502682537fefcfd9921e71d0b83e9576060f09abc6efab23" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.7.0", "serde", "serde_json", "utoipa-gen", @@ -8174,15 +8595,15 @@ dependencies = [ [[package]] name = "utoipa-gen" -version = "4.3.0" +version = "4.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bf0e16c02bc4bf5322ab65f10ab1149bdbcaa782cba66dc7057370a3f8190be" +checksum = "20c24e8ab68ff9ee746aad22d39b5535601e6416d1b0feeabf78be986a5c4392" dependencies = [ "proc-macro-error", "proc-macro2", "quote", "regex", - "syn 2.0.79", + "syn 2.0.90", ] [[package]] @@ -8191,7 +8612,7 @@ version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca44a24600ba6bead97e455954d2f01b062af9eff5facba4266fd3d62687ef0f" dependencies = [ - "axum 0.7.7", + "axum 0.7.9", "serde", "serde_json", "utoipa", @@ -8209,9 +8630,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" +checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" dependencies = [ "getrandom 0.2.15", "serde", @@ -8286,9 +8707,9 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.93" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +checksum = "d15e63b4482863c109d70a7b8706c1e364eb6ea449b201a76c5b89cedcec2d5c" dependencies = [ "cfg-if", "once_cell", @@ -8297,36 +8718,37 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.93" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +checksum = "8d36ef12e3aaca16ddd3f67922bc63e48e953f126de60bd33ccc0101ef9998cd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.43" +version = "0.4.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" +checksum = "9dfaf8f50e5f293737ee323940c7d8b08a66a95a419223d9f41610ca08b0833d" dependencies = [ "cfg-if", "js-sys", + "once_cell", "wasm-bindgen", "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.93" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +checksum = "705440e08b42d3e4b36de7d66c944be628d579796b8090bfa3471478a2260051" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -8334,28 +8756,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.93" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +checksum = "98c9ae5a76e46f4deecd0f0255cc223cfa18dc9b261213b8aa0c7b36f61b3f1d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.93" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" +checksum = "6ee99da9c5ba11bd675621338ef6fa52296b76b83305e9b6e5c77d4c286d6d49" [[package]] name = "web-sys" -version = "0.3.70" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" +checksum = "a98bc3c33f0fe7e59ad7cd041b89034fa82a7c2d4365ca538dda6cdaf513863c" dependencies = [ "js-sys", "wasm-bindgen", @@ -8377,7 +8799,7 @@ version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b291546d5d9d1eab74f069c77749f2cb8504a12caa20f0f2de93ddbf6f411888" dependencies = [ - "rustls-webpki", + "rustls-webpki 0.101.7", ] [[package]] @@ -8448,6 +8870,36 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-registry" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +dependencies = [ + "windows-result", + "windows-strings", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -8615,6 +9067,18 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + [[package]] name = "ws_stream_wasm" version = "0.7.4" @@ -8667,6 +9131,30 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" +[[package]] +name = "yoke" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", + "synstructure 0.13.1", +] + [[package]] name = "zerocopy" version = "0.7.35" @@ -8685,7 +9173,28 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", +] + +[[package]] +name = "zerofrom" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", + "synstructure 0.13.1", ] [[package]] @@ -8705,7 +9214,29 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.90", +] + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 00000000..4bd5c0d4 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,38 @@ +[workspace] +resolver = "2" + +members = [ + "auction-server", + "gas-oracle", + "sdk/rust/simple-searcher", + "sdk/rust", +] +exclude = ["vault-simulator", "contracts/svm"] + +[workspace.dependencies] +time = "0.3.36" +base64 = "0.22.1" +bincode = "1.3.3" +utoipa = "4.2.3" +uuid = "1.1.2" +serde = "1.0" +serde_json = "1.0" +serde_with = "3.9.0" +ethers = "2.0.14" +solana-sdk = "2.0.13" +solana-rpc-client = "2.0.13" +solana-transaction-status = "2.0.13" +solana-client = "2.0.13" +email_address = "0.2.4" +anyhow = "1.0.75" +strum = "0.26.3" +tokio-stream = "0.1.14" +tokio = "1.28" + +# The curve25519-dalek crate is a dependency of solana-sdk. +# This crate relies on a specific version of zeroize that is incompatible with many other packages. +# You can find more details in this issue https://github.com/solana-labs/solana/issues/26688 +# Solana Labs has provided a solution for some of these package incompatibilities, which can be found here https://github.com/solana-labs/solana/blob/27eff8408b7223bb3c4ab70523f8a8dca3ca6645/Cargo.toml#L514 +[patch.crates-io.curve25519-dalek] +git = "https://github.com/solana-labs/curve25519-dalek.git" +rev = "b500cdc2a920cd5bff9e2dd974d7b97349d61464" diff --git a/Dockerfile b/Dockerfile index b28da6dc..93ab7dcd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -ARG RUST_VERSION=1.66.1 +ARG RUST_VERSION=1.83.0 # Get the solidity dependencies using npm FROM node:21-alpine3.18 AS npm_build @@ -45,8 +45,7 @@ RUN forge install nomad-xyz/ExcessivelySafeCall@be417ab0c26233578b8d8f3a37b87bd1 # Build auction-server WORKDIR /src -COPY auction-server auction-server -COPY gas-oracle gas-oracle +COPY . . WORKDIR /src/auction-server RUN --mount=type=cache,target=/root/.cargo/registry cargo build --release diff --git a/auction-server/Cargo.toml b/auction-server/Cargo.toml index 497d539a..473aee6e 100644 --- a/auction-server/Cargo.toml +++ b/auction-server/Cargo.toml @@ -8,32 +8,32 @@ license-file = "license.txt" anchor-lang-idl = { version = "0.1.1", features = ["convert"] } [dependencies] -tokio = { version = "1.28", features = ["macros", "sync", "rt-multi-thread", "signal"] } -tokio-stream = "0.1.14" +tokio = { workspace = true, features = ["macros", "sync", "rt-multi-thread", "signal"] } +tokio-stream = { workspace = true } tower-http = { version = "0.5.2", features = ["cors"] } -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" +serde = { workspace = true, features = ["derive"] } +serde_json = { workspace = true } futures = { version = "0.3", default-features = false } -uuid = { version = "1.1.2", features = ["serde", "v4"] } +uuid = { workspace = true, features = ["serde", "v4"] } axum = { version = "0.7.5", features = ["ws", "tracing"] } axum-streams = { version = "0.10.0", features = ["json", "text"] } clap = { version = "4.4.4", features = ["derive", "env", "cargo"] } tracing = { version = "0.1.40", features = ["log"] } -anyhow = "1.0.75" +anyhow = { workspace = true } tracing-subscriber = { version = "0.3.18", features = ["env-filter", "json"] } async-stream = "0.3.5" -utoipa = { version = "4.2.3", features = ["axum_extras"] } +utoipa = { workspace = true, features = ["axum_extras"] } utoipa-redoc = { version = "4", features = ["axum"] } serde_yaml = "0.9.25" -ethers = { version = "2.0.14", features = ["ws"] } +ethers = { workspace = true, features = ["ws"] } axum-macros = "0.4.0" sqlx = { version = "0.7.4", features = [ "runtime-tokio", "tls-native-tls", "postgres", "time", "uuid", "bigdecimal", "json" ] } tokio-util = { version = "0.7.10", features = ["rt"] } axum-extra = { version = "0.9.3", features = ["typed-header"] } -email_address = "0.2.4" +email_address = { workspace = true } rand = "0.8.5" -base64 = "0.22.1" -time = { version = "0.3.36", features = ["serde"] } +base64 = { workspace = true } +time = { workspace = true, features = ["serde"] } axum-prometheus = "0.6.1" reqwest = { version = "0.11.27" } tracing-opentelemetry = "0.24.0" @@ -42,21 +42,14 @@ opentelemetry_sdk = { version = "0.23.0", features = ["rt-tokio"] } opentelemetry-otlp = { version = "0.16.0" } gas-oracle = { path = "../gas-oracle" } serde_path_to_error = "0.1.16" -solana-sdk = "2.0.7" -solana-client = "2.0.13" -bincode = "1.3.3" -serde_with = { version = "3.9.0", features = ["base64"] } +solana-sdk = { workspace = true } +solana-client = { workspace = true } +bincode = { workspace = true } +serde_with = { workspace = true, features = ["base64"] } anchor-lang = "0.30.1" express-relay = { path = "../contracts/svm/programs/express_relay" } -solana-rpc-client = "2.0.13" -solana-transaction-status = "2.0.13" +solana-rpc-client ={ workspace = true } +solana-transaction-status = { workspace = true } borsh = "1.5.1" litesvm = "0.3.0" - -# The curve25519-dalek crate is a dependency of solana-sdk. -# This crate relies on a specific version of zeroize that is incompatible with many other packages. -# You can find more details in this issue https://github.com/solana-labs/solana/issues/26688 -# Solana Labs has provided a solution for some of these package incompatibilities, which can be found here https://github.com/solana-labs/solana/blob/27eff8408b7223bb3c4ab70523f8a8dca3ca6645/Cargo.toml#L514 -[patch.crates-io.curve25519-dalek] -git = "https://github.com/solana-labs/curve25519-dalek.git" -rev = "b500cdc2a920cd5bff9e2dd974d7b97349d61464" +express-relay-api-types = { path = "api-types" } diff --git a/auction-server/api-types/Cargo.toml b/auction-server/api-types/Cargo.toml new file mode 100644 index 00000000..745f13cc --- /dev/null +++ b/auction-server/api-types/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "express-relay-api-types" +version = "0.1.0" +edition = "2021" +description = "Pyth Express Relay api types" +repository = "https://github.com/pyth-network/per" +license = "Apache-2.0" + +[dependencies] +serde = { workspace = true, features = ["derive"] } +utoipa = { workspace = true, features = ["axum_extras"] } +uuid = { workspace = true, features = ["serde", "v4"] } +serde_json = { workspace = true } +serde_with = { workspace = true, features = ["base64"] } +solana-sdk = { workspace = true } +ethers = { workspace = true } +time = { workspace = true, features = ["serde"] } +base64 = { workspace = true } +bincode = { workspace = true } +email_address = { workspace = true } +strum = { workspace = true } +http = "1.2.0" diff --git a/auction-server/api-types/src/bid.rs b/auction-server/api-types/src/bid.rs new file mode 100644 index 00000000..0483bc47 --- /dev/null +++ b/auction-server/api-types/src/bid.rs @@ -0,0 +1,402 @@ +use { + crate::{ + profile::ProfileId, + AccessLevel, + ChainId, + PermissionKeyEvm, + PermissionKeySvm, + Routable, + }, + ethers::types::{ + Address, + Bytes, + H256, + U256, + }, + serde::{ + Deserialize, + Serialize, + }, + serde_with::{ + serde_as, + DisplayFromStr, + }, + solana_sdk::{ + signature::Signature, + transaction::VersionedTransaction, + }, + strum::AsRefStr, + time::OffsetDateTime, + utoipa::{ + IntoParams, + ToResponse, + ToSchema, + }, + uuid::Uuid, +}; + +pub type BidId = Uuid; +pub type BidAmountSvm = u64; +pub type BidAmountEvm = U256; + +#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] +#[serde(tag = "type", rename_all = "snake_case")] +pub enum BidStatusEvm { + /// The temporary state which means the auction for this bid is pending. + /// It will be updated to Lost or Submitted after the auction takes place. + #[schema(title = "Pending")] + Pending, + /// The bid is submitted to the chain, which is placed at the given index of the transaction with the given hash. + /// This state is temporary and will be updated to either lost or won after conclusion of the auction. + #[schema(title = "Submitted")] + Submitted { + #[schema(example = "0x103d4fbd777a36311b5161f2062490f761f25b67406badb2bace62bb170aa4e3", value_type = String)] + result: H256, + #[schema(example = 1, value_type = u32)] + index: u32, + }, + /// The bid lost the auction, which is concluded with the transaction with the given hash and index. + /// The result will be None if the auction was concluded off-chain and no auction was submitted to the chain. + /// The index will be None if the bid was not submitted to the chain and lost the auction by off-chain calculation. + /// There are cases where the result is not None and the index is None. + /// It is because other bids were selected for submission to the chain, but not this one. + #[schema(title = "Lost")] + Lost { + #[schema(example = "0x103d4fbd777a36311b5161f2062490f761f25b67406badb2bace62bb170aa4e3", value_type = Option)] + result: Option, + #[schema(example = 1, value_type = Option)] + index: Option, + }, + /// The bid won the auction, which is concluded with the transaction with the given hash and index. + #[schema(title = "Won")] + Won { + #[schema(example = "0x103d4fbd777a36311b5161f2062490f761f25b67406badb2bace62bb170aa4e3", value_type = String)] + result: H256, + #[schema(example = 1, value_type = u32)] + index: u32, + }, +} + +#[serde_as] +#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] +#[serde(tag = "type", rename_all = "snake_case")] +pub enum BidStatusSvm { + /// The temporary state which means the auction for this bid is pending. + /// It will be updated to Lost or Submitted after the auction takes place. + #[schema(title = "Pending")] + Pending, + /// The bid lost the auction. + /// This bid status will have a result field containing the signature of the transaction corresponding to the winning bid, + /// unless the auction had no winner (because all bids were found to be invalid). + #[schema(title = "Lost")] + Lost { + #[schema(example = "Jb2urXPyEh4xiBgzYvwEFe4q1iMxG1DNxWGGQg94AmKgqFTwLAiTiHrYiYxwHUB4DV8u5ahNEVtMMDm3sNSRdTg", value_type = Option)] + #[serde(with = "crate::serde::nullable_signature_svm")] + result: Option, + }, + /// The bid won the auction and was submitted to the chain, with the signature of the corresponding transaction provided in the result field. + /// This state is temporary and will be updated to either Won or Failed after the transaction is included in a block, or Expired if the transaction expires before it is included. + #[schema(title = "Submitted")] + Submitted { + #[schema(example = "Jb2urXPyEh4xiBgzYvwEFe4q1iMxG1DNxWGGQg94AmKgqFTwLAiTiHrYiYxwHUB4DV8u5ahNEVtMMDm3sNSRdTg", value_type = String)] + #[serde_as(as = "DisplayFromStr")] + result: Signature, + }, + /// The bid won the auction and was included in a block successfully. + #[schema(title = "Won")] + Won { + #[schema(example = "Jb2urXPyEh4xiBgzYvwEFe4q1iMxG1DNxWGGQg94AmKgqFTwLAiTiHrYiYxwHUB4DV8u5ahNEVtMMDm3sNSRdTg", value_type = String)] + #[serde_as(as = "DisplayFromStr")] + result: Signature, + }, + /// The bid was submitted on-chain, was included in a block, but resulted in a failed transaction. + #[schema(title = "Failed")] + Failed { + #[schema(example = "Jb2urXPyEh4xiBgzYvwEFe4q1iMxG1DNxWGGQg94AmKgqFTwLAiTiHrYiYxwHUB4DV8u5ahNEVtMMDm3sNSRdTg", value_type = String)] + #[serde_as(as = "DisplayFromStr")] + result: Signature, + }, + /// The bid was submitted on-chain but expired before it was included in a block. + #[schema(title = "Expired")] + Expired { + #[schema(example = "Jb2urXPyEh4xiBgzYvwEFe4q1iMxG1DNxWGGQg94AmKgqFTwLAiTiHrYiYxwHUB4DV8u5ahNEVtMMDm3sNSRdTg", value_type = String)] + #[serde_as(as = "DisplayFromStr")] + result: Signature, + }, +} + +#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] +#[serde(untagged)] +pub enum BidStatus { + Evm(BidStatusEvm), + Svm(BidStatusSvm), +} + +#[derive(Serialize, Deserialize, ToResponse, ToSchema, Clone)] +pub struct BidResult { + /// The status of the request. If the bid was placed successfully, the status will be "OK". + #[schema(example = "OK")] + pub status: String, + /// The unique id created to identify the bid. This id can be used to query the status of the bid. + #[schema(example = "beedbeed-58cc-4372-a567-0e02b2c3d479", value_type=String)] + pub id: BidId, +} + +#[derive(Clone, Debug, ToSchema, Serialize, Deserialize)] +pub struct BidCoreFields { + /// The unique id for bid. + #[schema(example = "obo3ee3e-58cc-4372-a567-0e02b2c3d479", value_type = String)] + pub id: BidId, + /// The chain id for bid. + #[schema(example = "op_sepolia", value_type = String)] + pub chain_id: ChainId, + /// The time server received the bid formatted in rfc3339. + #[schema(example = "2024-05-23T21:26:57.329954Z", value_type = String)] + #[serde(with = "time::serde::rfc3339")] + pub initiation_time: OffsetDateTime, + /// The profile id for the bid owner. + #[schema(example = "obo3ee3e-58cc-4372-a567-0e02b2c3d479", value_type = String)] + pub profile_id: Option, +} + +#[derive(Clone, Debug, ToSchema, Serialize, Deserialize)] +pub struct BidSvm { + #[serde(flatten)] + #[schema(inline)] + pub core_fields: BidCoreFields, + /// The latest status for bid. + pub status: BidStatusSvm, + /// The transaction of the bid. + #[schema(example = "SGVsbG8sIFdvcmxkIQ==", value_type = String)] + #[serde(with = "crate::serde::transaction_svm")] + pub transaction: VersionedTransaction, + /// Amount of bid in lamports. + #[schema(example = "1000", value_type = u64)] + pub bid_amount: BidAmountSvm, + /// The permission key for bid in base64 format. + /// This is the concatenation of the permission account and the router account. + #[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)] + pub permission_key: PermissionKeySvm, +} + +#[derive(Clone, Debug, ToSchema, Serialize, Deserialize)] +pub struct BidEvm { + #[serde(flatten)] + #[schema(inline)] + pub core_fields: BidCoreFields, + /// The latest status for bid. + pub status: BidStatusEvm, + /// The contract address to call. + #[schema(example = "0xcA11bde05977b3631167028862bE2a173976CA11", value_type = String)] + pub target_contract: Address, + /// Calldata for the contract call. + #[schema(example = "0xdeadbeef", value_type = String)] + pub target_calldata: Bytes, + /// The gas limit for the contract call. + #[schema(example = "2000000", value_type = String)] + #[serde(with = "crate::serde::u256")] + pub gas_limit: U256, + /// Amount of bid in wei. + #[schema(example = "10", value_type = String)] + #[serde(with = "crate::serde::u256")] + pub bid_amount: BidAmountEvm, + /// The permission key for bid. + #[schema(example = "0xdeadbeef", value_type = String)] + pub permission_key: PermissionKeyEvm, +} + +#[derive(Clone, Debug, ToSchema, Serialize, Deserialize)] +#[serde(untagged)] +#[allow(clippy::large_enum_variant)] +pub enum Bid { + Evm(BidEvm), + Svm(BidSvm), +} + +impl Bid { + pub fn get_initiation_time(&self) -> OffsetDateTime { + match self { + Bid::Evm(bid) => bid.core_fields.initiation_time, + Bid::Svm(bid) => bid.core_fields.initiation_time, + } + } + + pub fn get_status(&self) -> BidStatus { + match self { + Bid::Evm(bid) => BidStatus::Evm(bid.status.clone()), + Bid::Svm(bid) => BidStatus::Svm(bid.status.clone()), + } + } +} + +#[derive(Serialize, Deserialize, ToSchema, Clone, Debug)] +pub struct BidCreateEvm { + /// The permission key to bid on. + #[schema(example = "0xdeadbeef", value_type = String)] + pub permission_key: PermissionKeyEvm, + /// The chain id to bid on. + #[schema(example = "op_sepolia", value_type = String)] + pub chain_id: ChainId, + /// The contract address to call. + #[schema(example = "0xcA11bde05977b3631167028862bE2a173976CA11", value_type = String)] + pub target_contract: Address, + /// Calldata for the contract call. + #[schema(example = "0xdeadbeef", value_type = String)] + pub target_calldata: Bytes, + /// Amount of bid in wei. + #[schema(example = "10", value_type = String)] + #[serde(with = "crate::serde::u256")] + pub amount: BidAmountEvm, +} + +#[derive(Serialize, Deserialize, ToSchema, Clone, Debug)] +pub struct BidCreateSvm { + /// The chain id to bid on. + #[schema(example = "solana", value_type = String)] + pub chain_id: ChainId, + /// The transaction for bid. + #[schema(example = "SGVsbG8sIFdvcmxkIQ==", value_type = String)] + #[serde(with = "crate::serde::transaction_svm")] + pub transaction: VersionedTransaction, +} + +#[derive(Serialize, Deserialize, ToSchema, Debug, Clone)] +#[serde(untagged)] // Remove tags to avoid key-value wrapping +pub enum BidCreate { + Evm(BidCreateEvm), + Svm(BidCreateSvm), +} + +#[derive(Serialize, Clone, ToSchema, ToResponse, Deserialize, Debug)] +pub struct BidStatusWithId { + #[schema(value_type = String)] + pub id: BidId, + pub bid_status: BidStatus, +} + +#[derive(Serialize, Deserialize, IntoParams, Clone)] +pub struct GetBidStatusParams { + #[param(example="op_sepolia", value_type = String)] + pub chain_id: ChainId, + + #[param(example="obo3ee3e-58cc-4372-a567-0e02b2c3d479", value_type = String)] + pub bid_id: BidId, +} + +#[derive(Serialize, Deserialize, ToResponse, ToSchema, Clone)] +pub struct Bids { + pub items: Vec, +} + +#[derive(Serialize, Deserialize, IntoParams)] +pub struct GetBidsByTimeQueryParams { + #[param(example="2024-05-23T21:26:57.329954Z", value_type = Option)] + #[serde(default, with = "crate::serde::nullable_datetime")] + pub from_time: Option, +} + +impl BidCreate { + pub fn get_chain_id(&self) -> ChainId { + match self { + BidCreate::Evm(bid_create_evm) => bid_create_evm.chain_id.clone(), + BidCreate::Svm(bid_create_svm) => bid_create_svm.chain_id.clone(), + } + } +} + +// We get clippy warning when we use AsRefStr macro with deprecated. +// Disabled the strum for deprecated routes to avoid clippy warnings. +#[derive(AsRefStr, Clone)] +#[strum(prefix = "/")] +pub enum Route { + #[strum(serialize = "")] + PostBid, + #[strum(serialize = "")] + GetBidsByTime, + #[strum(serialize = ":bid_id")] + GetBidStatus, +} + +#[derive(Clone)] +#[deprecated = "Use Route instead"] +pub enum DeprecatedRoute { + DeprecatedGetBidsByTime, + DeprecatedGetBidStatus, +} + +impl Routable for Route { + fn properties(&self) -> crate::RouteProperties { + let full_path = format!( + "{}{}{}", + crate::Route::V1.as_ref(), + crate::Route::Bid.as_ref(), + self.as_ref() + ) + .trim_end_matches('/') + .to_string(); + + let full_path_with_chain = format!( + "{}{}{}", + crate::Route::V1.as_ref(), + crate::Route::Bid.as_ref(), + self.as_ref() + ) + .trim_end_matches('/') + .to_string(); + + match self { + Route::PostBid => crate::RouteProperties { + method: http::Method::POST, + access_level: AccessLevel::Public, + full_path, + }, + Route::GetBidsByTime => crate::RouteProperties { + method: http::Method::GET, + access_level: AccessLevel::LoggedIn, + full_path: full_path_with_chain, + }, + Route::GetBidStatus => crate::RouteProperties { + method: http::Method::GET, + access_level: AccessLevel::Public, + full_path: full_path_with_chain, + }, + } + } +} + +#[allow(deprecated)] +impl AsRef for DeprecatedRoute { + fn as_ref(&self) -> &str { + match self { + DeprecatedRoute::DeprecatedGetBidStatus => "/:bid_id", + DeprecatedRoute::DeprecatedGetBidsByTime => "/", + } + } +} + +#[allow(deprecated)] +impl Routable for DeprecatedRoute { + fn properties(&self) -> crate::RouteProperties { + let full_path = format!( + "{}{}{}", + crate::Route::V1.as_ref(), + crate::Route::Bid.as_ref(), + self.as_ref(), + ) + .trim_end_matches('/') + .to_string(); + + match self { + DeprecatedRoute::DeprecatedGetBidsByTime => crate::RouteProperties { + method: http::Method::GET, + access_level: AccessLevel::LoggedIn, + full_path, + }, + DeprecatedRoute::DeprecatedGetBidStatus => crate::RouteProperties { + method: http::Method::GET, + access_level: AccessLevel::Public, + full_path, + }, + } + } +} diff --git a/auction-server/api-types/src/lib.rs b/auction-server/api-types/src/lib.rs new file mode 100644 index 00000000..d29c1c46 --- /dev/null +++ b/auction-server/api-types/src/lib.rs @@ -0,0 +1,113 @@ +use { + ::serde::{ + Deserialize, + Serialize, + }, + ethers::types::Bytes, + serde_with::{ + base64::{ + Base64, + Standard, + }, + formats::Padded, + serde_as, + DeserializeAs, + DisplayFromStr, + SerializeAs, + }, + solana_sdk::hash::Hash, + strum::AsRefStr, + utoipa::{ + ToResponse, + ToSchema, + }, +}; + +pub mod bid; +pub mod opportunity; +pub mod profile; +pub mod serde; +pub mod ws; + +pub type MicroLamports = u64; +pub type ChainId = String; +pub type PermissionKeyEvm = Bytes; +#[derive(Clone, Debug)] +pub struct PermissionKeySvm(pub [u8; 64]); +impl Serialize for PermissionKeySvm { + fn serialize(&self, serializer: S) -> Result + where + S: ::serde::Serializer, + { + Base64::::serialize_as(&self.0, serializer) + } +} + +impl<'de> Deserialize<'de> for PermissionKeySvm { + fn deserialize(deserializer: D) -> Result + where + D: ::serde::Deserializer<'de>, + { + let bytes = Base64::::deserialize_as(deserializer)?; + Ok(PermissionKeySvm(bytes)) + } +} + +#[serde_as] +#[derive(Serialize, Clone, ToSchema, ToResponse, Deserialize, Debug)] +pub struct SvmChainUpdate { + #[schema(example = "solana", value_type = String)] + pub chain_id: ChainId, + #[serde_as(as = "DisplayFromStr")] + #[schema(example = "SLxp9LxX1eE9Z5v99Y92DaYEwyukFgMUF6zRerCF12j", value_type = String)] + pub blockhash: Hash, + /// The prioritization fee that the server suggests to use for the next transaction + #[schema(example = "1000", value_type = u64)] + pub latest_prioritization_fee: MicroLamports, +} + +#[derive(ToResponse, ToSchema, Serialize, Deserialize)] +#[response(description = "An error occurred processing the request")] +pub struct ErrorBodyResponse { + pub error: String, +} + +#[derive(AsRefStr)] +#[strum(prefix = "/")] +pub enum Route { + #[strum(serialize = "v1")] + V1, + #[strum(serialize = "v1/:chain_id")] + V1Chain, + #[strum(serialize = "bids")] + Bid, + #[strum(serialize = "opportunities")] + Opportunity, + #[strum(serialize = "profiles")] + Profile, + #[strum(serialize = "")] + Root, + #[strum(serialize = "live")] + Liveness, + #[strum(serialize = "docs")] + Docs, + #[strum(serialize = "docs/openapi.json")] + OpenApi, +} + +#[derive(PartialEq)] +pub enum AccessLevel { + Admin, + LoggedIn, + Public, +} + +pub struct RouteProperties { + pub access_level: AccessLevel, + pub method: http::Method, + pub full_path: String, +} + +pub trait Routable: AsRef + Clone { + fn properties(&self) -> RouteProperties; +} diff --git a/auction-server/api-types/src/opportunity.rs b/auction-server/api-types/src/opportunity.rs new file mode 100644 index 00000000..c5814c9e --- /dev/null +++ b/auction-server/api-types/src/opportunity.rs @@ -0,0 +1,662 @@ +use { + crate::{ + bid::BidId, + AccessLevel, + ChainId, + PermissionKeyEvm, + Routable, + }, + ethers::types::{ + Address, + Bytes, + Signature, + U256, + }, + serde::{ + de, + Deserialize, + Serialize, + }, + serde_with::{ + base64::Base64, + serde_as, + DisplayFromStr, + }, + solana_sdk::{ + clock::Slot, + pubkey::Pubkey, + transaction::VersionedTransaction, + }, + strum::AsRefStr, + time::OffsetDateTime, + utoipa::{ + IntoParams, + ToResponse, + ToSchema, + }, + uuid::Uuid, +}; + +// Base types +pub type UnixTimestampMicros = i128; +pub type OpportunityId = Uuid; + +#[derive(Debug, Serialize, Deserialize, ToSchema, Clone)] +#[serde(rename_all = "lowercase")] +pub enum OpportunityMode { + Live, + Historical, +} + +#[derive(Serialize, Deserialize, ToResponse, ToSchema, Clone)] +pub struct OpportunityBidResult { + #[schema(example = "OK")] + pub status: String, + /// The unique id created to identify the bid. This id can be used to query the status of the bid. + #[schema(example = "beedbeed-58cc-4372-a567-0e02b2c3d479", value_type=String)] + pub id: BidId, +} + +#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] +#[serde(rename_all = "lowercase")] +pub enum ProgramSvm { + Phantom, + Limo, +} + +/// Opportunity parameters needed for deleting live opportunities. +#[serde_as] +#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] +pub struct OpportunityDeleteV1Svm { + /// The permission account for the opportunity. + #[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)] + #[serde_as(as = "DisplayFromStr")] + pub permission_account: Pubkey, + /// The router account for the opportunity. + #[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)] + #[serde_as(as = "DisplayFromStr")] + pub router: Pubkey, + /// The chain id for the opportunity. + #[schema(example = "solana", value_type = String)] + pub chain_id: ChainId, + /// The program for the opportunity. + #[schema(example = "limo", value_type = ProgramSvm)] + pub program: ProgramSvm, +} + +/// Opportunity parameters needed for deleting live opportunities. +#[serde_as] +#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] +pub struct OpportunityDeleteV1Evm { + /// The permission key of the opportunity. + #[schema(example = "0xdeadbeefcafe", value_type = String)] + pub permission_key: PermissionKeyEvm, + /// The chain id for the opportunity. + #[schema(example = "solana", value_type = String)] + pub chain_id: ChainId, +} + +#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] +#[serde(tag = "version")] +pub enum OpportunityDeleteSvm { + #[serde(rename = "v1")] + #[schema(title = "v1")] + V1(OpportunityDeleteV1Svm), +} + +#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] +#[serde(tag = "version")] +pub enum OpportunityDeleteEvm { + #[serde(rename = "v1")] + #[schema(title = "v1")] + V1(OpportunityDeleteV1Evm), +} + +/// The input type for deleting opportunities. +#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] +#[serde(tag = "chain_type")] +pub enum OpportunityDelete { + #[serde(rename = "svm")] + #[schema(title = "svm")] + Svm(OpportunityDeleteSvm), + #[serde(rename = "evm")] + #[schema(title = "evm")] + Evm(OpportunityDeleteEvm), +} + +#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug, ToResponse)] +pub struct TokenAmountEvm { + /// The token contract address. + #[schema(example = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", value_type = String)] + pub token: Address, + /// The token amount. + #[schema(example = "1000", value_type = String)] + #[serde(with = "crate::serde::u256")] + pub amount: U256, +} + +/// Opportunity parameters needed for on-chain execution. +/// If a searcher signs the opportunity and have approved enough tokens to opportunity adapter, +/// by calling this target contract with the given target calldata and structures, they will +/// send the tokens specified in the `sell_tokens` field and receive the tokens specified in the `buy_tokens` field. +#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug, ToResponse)] +pub struct OpportunityCreateV1Evm { + /// The permission key required for successful execution of the opportunity. + #[schema(example = "0xdeadbeefcafe", value_type = String)] + pub permission_key: PermissionKeyEvm, + /// The chain id where the opportunity will be executed. + #[schema(example = "op_sepolia", value_type = String)] + pub chain_id: String, + /// The contract address to call for execution of the opportunity. + #[schema(example = "0xcA11bde05977b3631167028862bE2a173976CA11", value_type = String)] + pub target_contract: ethers::abi::Address, + /// Calldata for the target contract call. + #[schema(example = "0xdeadbeef", value_type = String)] + pub target_calldata: Bytes, + /// The value to send with the contract call. + #[schema(example = "1", value_type = String)] + #[serde(with = "crate::serde::u256")] + pub target_call_value: U256, + + pub sell_tokens: Vec, + pub buy_tokens: Vec, +} + +#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug, ToResponse)] +#[serde(tag = "version")] +pub enum OpportunityCreateEvm { + #[serde(rename = "v1")] + #[schema(title = "v1")] + V1(OpportunityCreateV1Evm), +} + +// ----- Svm types ----- +#[serde_as] +#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug, ToResponse)] +pub struct TokenAmountSvm { + /// The token contract address. + #[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)] + #[serde_as(as = "DisplayFromStr")] + pub token: Pubkey, + /// The token amount, represented in the smallest unit of the respective token: + /// - For Solana, it is measured in lamports. + /// - For other tokens, it follows the smallest denomination of that token. + #[schema(example = 1000)] + pub amount: u64, +} + +/// Program specific parameters for the opportunity. +#[serde_as] +#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] +#[serde(tag = "program")] +pub enum OpportunityCreateProgramParamsV1Svm { + /// Limo program specific parameters for the opportunity. + /// It contains the Limo order to be executed, encoded in base64. + /// SDKs will decode this order and create transaction for bidding on the opportunity. + #[serde(rename = "limo")] + #[schema(title = "limo")] + Limo { + /// The Limo order to be executed, encoded in base64. + #[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)] + #[serde_as(as = "Base64")] + order: Vec, + + /// Address of the order account. + #[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)] + #[serde_as(as = "DisplayFromStr")] + order_address: Pubkey, + }, + /// Phantom program specific parameters for the opportunity. + #[serde(rename = "phantom")] + #[schema(title = "phantom")] + Phantom { + /// The user wallet address which requested the quote from the wallet. + #[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)] + #[serde_as(as = "DisplayFromStr")] + user_wallet_address: Pubkey, + + /// The maximum slippage percentage that the user is willing to accept. + #[schema(example = 0.5, value_type = f64)] + maximum_slippage_percentage: f64, + }, +} + +/// Opportunity parameters needed for on-chain execution. +/// Parameters may differ for each program. +#[serde_as] +#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] +pub struct OpportunityCreateV1Svm { + /// The permission account to be permitted by the ER contract for the opportunity execution of the protocol. + #[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)] + #[serde_as(as = "DisplayFromStr")] + pub permission_account: Pubkey, + /// The router account to be used for the opportunity execution of the protocol. + #[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)] + #[serde_as(as = "DisplayFromStr")] + pub router: Pubkey, + /// The chain id where the opportunity will be executed. + #[schema(example = "solana", value_type = String)] + pub chain_id: ChainId, + /// The slot where the program params were fetched from using the RPC. + #[schema(example = 293106477, value_type = u64)] + pub slot: Slot, + + pub sell_tokens: Vec, + pub buy_tokens: Vec, + + #[serde(flatten)] + #[schema(inline)] + pub program_params: OpportunityCreateProgramParamsV1Svm, +} + +#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] +#[serde(tag = "version")] +pub enum OpportunityCreateSvm { + #[serde(rename = "v1")] + #[schema(title = "v1")] + V1(OpportunityCreateV1Svm), +} + +/// The input type for creating a new opportunity. +#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] +#[serde(untagged)] +pub enum OpportunityCreate { + #[schema(title = "evm")] + Evm(OpportunityCreateEvm), + #[schema(title = "svm")] + Svm(OpportunityCreateSvm), +} + +#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug, ToResponse)] +pub struct OpportunityParamsV1Evm(pub OpportunityCreateV1Evm); + +#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug, ToResponse)] +#[serde(tag = "version")] +pub enum OpportunityParamsEvm { + #[serde(rename = "v1")] + #[schema(title = "v1")] + V1(OpportunityParamsV1Evm), +} + +#[derive(Serialize, Deserialize, ToSchema, Clone, ToResponse, Debug)] +pub struct OpportunityEvm { + /// The opportunity unique id. + #[schema(example = "obo3ee3e-58cc-4372-a567-0e02b2c3d479", value_type = String)] + pub opportunity_id: OpportunityId, + /// Creation time of the opportunity (in microseconds since the Unix epoch). + #[schema(example = 1_700_000_000_000_000i128, value_type = i128)] + pub creation_time: UnixTimestampMicros, + #[serde(flatten)] + #[schema(inline)] + pub params: OpportunityParamsEvm, +} + +/// Program specific parameters for the opportunity. +#[serde_as] +#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug, ToResponse)] +#[serde(tag = "program")] +pub enum OpportunityParamsV1ProgramSvm { + /// Limo program specific parameters for the opportunity. + /// It contains the Limo order to be executed, encoded in base64. + /// SDKs will decode this order and create transaction for bidding on the opportunity. + #[serde(rename = "limo")] + #[schema(title = "limo")] + Limo { + /// The Limo order to be executed, encoded in base64. + #[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)] + #[serde_as(as = "Base64")] + order: Vec, + /// Address of the order account. + #[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)] + #[serde_as(as = "DisplayFromStr")] + order_address: Pubkey, + }, + /// Phantom program specific parameters for the opportunity. + #[serde(rename = "phantom")] + #[schema(title = "phantom")] + Phantom { + /// The user wallet address which requested the quote from the wallet. + #[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)] + #[serde_as(as = "DisplayFromStr")] + user_wallet_address: Pubkey, + + /// The maximum slippage percentage that the user is willing to accept. + #[schema(example = 0.5, value_type = f64)] + maximum_slippage_percentage: f64, + + /// The permission account to be permitted by the ER contract for the opportunity execution of the protocol. + #[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)] + #[serde_as(as = "DisplayFromStr")] + permission_account: Pubkey, + + /// The router account to be used for the opportunity execution of the protocol. + #[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)] + #[serde_as(as = "DisplayFromStr")] + router_account: Pubkey, + + /// The token searcher will send. + sell_token: TokenAmountSvm, + + /// The token searcher will receive. + buy_token: TokenAmountSvm, + }, +} + +/// Opportunity parameters needed for on-chain execution. +/// Parameters may differ for each program. +#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug, ToResponse)] +pub struct OpportunityParamsV1Svm { + #[serde(flatten)] + #[schema(inline)] + pub program: OpportunityParamsV1ProgramSvm, + #[schema(example = "solana", value_type = String)] + pub chain_id: ChainId, +} + +#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug, ToResponse)] +#[serde(tag = "version")] +pub enum OpportunityParamsSvm { + #[serde(rename = "v1")] + #[schema(title = "v1")] + V1(OpportunityParamsV1Svm), +} + +#[serde_as] +#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug, ToResponse)] +pub struct OpportunitySvm { + /// The opportunity unique id. + #[schema(example = "obo3ee3e-58cc-4372-a567-0e02b2c3d479", value_type = String)] + pub opportunity_id: OpportunityId, + /// Creation time of the opportunity (in microseconds since the Unix epoch). + #[schema(example = 1_700_000_000_000_000i128, value_type = i128)] + pub creation_time: UnixTimestampMicros, + /// The slot where the program params were fetched from using the RPC. + #[schema(example = 293106477, value_type = u64)] + pub slot: Slot, + + #[serde(flatten)] + #[schema(inline)] + pub params: OpportunityParamsSvm, +} + +#[derive(Serialize, ToResponse, ToSchema, Clone, Debug)] +#[serde(untagged)] +#[allow(clippy::large_enum_variant)] +pub enum Opportunity { + Evm(OpportunityEvm), + Svm(OpportunitySvm), +} + +// Default deserialize implementation is not working for opportunity +impl<'de> ::serde::Deserialize<'de> for Opportunity { + fn deserialize(deserializer: D) -> Result + where + D: ::serde::Deserializer<'de>, + { + let json_value = serde_json::Value::deserialize(deserializer)?; + let value: Result = + serde_json::from_value(json_value.clone()); + match value { + Ok(opportunity) => Ok(Opportunity::Evm(opportunity)), + Err(evm_error) => serde_json::from_value(json_value) + .map(Opportunity::Svm) + .map_err(|svm_error| { + de::Error::custom(format!( + "Failed to deserialize opportunity as EVM: {:?}, as SVM: {:?}", + evm_error, svm_error + )) + }), + } + } +} + +fn default_opportunity_mode() -> OpportunityMode { + OpportunityMode::Live +} +fn default_limit() -> usize { + 20 +} + +#[derive(Clone, Serialize, Deserialize, IntoParams)] +pub struct GetOpportunitiesQueryParams { + #[param(example = "op_sepolia", value_type = Option < String >)] + pub chain_id: Option, + /// Get opportunities in live or historical mode. + #[param(default = "live")] + #[serde(default = "default_opportunity_mode")] + pub mode: OpportunityMode, + /// The permission key to filter the opportunities by. Used only in historical mode. + #[param(example = "0xdeadbeef", value_type = Option< String >)] + pub permission_key: Option, + /// The time to get the opportunities from. + #[param(example="2024-05-23T21:26:57.329954Z", value_type = Option)] + #[serde(default, with = "crate::serde::nullable_datetime")] + pub from_time: Option, + /// The maximum number of opportunities to return. Capped at 100; if more than 100 requested, at most 100 will be returned. + #[param(example = "20", value_type = usize, maximum = 100)] + #[serde(default = "default_limit")] + pub limit: usize, +} + +#[derive(Serialize, Deserialize, ToSchema, Clone)] +pub struct OpportunityBidEvm { + /// The opportunity permission key. + #[schema(example = "0xdeadbeefcafe", value_type=String)] + pub permission_key: PermissionKeyEvm, + /// The bid amount in wei. + #[schema(example = "1000000000000000000", value_type=String)] + #[serde(with = "crate::serde::u256")] + pub amount: U256, + /// The latest unix timestamp in seconds until which the bid is valid. + #[schema(example = "1000000000000000000", value_type=String)] + #[serde(with = "crate::serde::u256")] + pub deadline: U256, + /// The nonce of the bid permit signature. + #[schema(example = "123", value_type=String)] + #[serde(with = "crate::serde::u256")] + pub nonce: U256, + /// The executor address. + #[schema(example = "0x5FbDB2315678afecb367f032d93F642f64180aa2", value_type=String)] + pub executor: Address, + #[schema( + example = "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef12", + value_type=String + )] + #[serde(with = "crate::serde::signature")] + pub signature: Signature, +} + +/// Parameters needed to create a new opportunity from the Phantom wallet. +/// Auction server will extract the output token price for the auction. +#[serde_as] +#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] +pub struct QuoteCreatePhantomV1Svm { + /// The user wallet address which requested the quote from the wallet. + #[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)] + #[serde_as(as = "DisplayFromStr")] + pub user_wallet_address: Pubkey, + /// The token mint address of the input token. + #[schema(example = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", value_type = String)] + #[serde_as(as = "DisplayFromStr")] + pub input_token_mint: Pubkey, + /// The token mint address of the output token. + #[schema(example = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", value_type = String)] + #[serde_as(as = "DisplayFromStr")] + pub output_token_mint: Pubkey, + /// The input token amount that the user wants to swap. + #[schema(example = 100)] + pub input_token_amount: u64, + /// The maximum slippage percentage that the user is willing to accept. + #[schema(example = 0.5)] + pub maximum_slippage_percentage: f64, + /// The chain id for creating the quote. + #[schema(example = "solana", value_type = String)] + pub chain_id: ChainId, +} + +#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] +#[serde(tag = "program")] +pub enum QuoteCreateV1Svm { + #[serde(rename = "phantom")] + #[schema(title = "phantom")] + Phantom(QuoteCreatePhantomV1Svm), +} + +#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] +#[serde(tag = "version")] +pub enum QuoteCreateSvm { + #[serde(rename = "v1")] + #[schema(title = "v1")] + V1(QuoteCreateV1Svm), +} + +#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] +#[serde(untagged)] +pub enum QuoteCreate { + #[schema(title = "svm")] + Svm(QuoteCreateSvm), +} + +#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] +pub struct QuoteV1Svm { + /// The signed transaction for the quote to be executed on chain which is valid until the expiration time. + #[schema(example = "SGVsbG8sIFdvcmxkIQ==", value_type = String)] + #[serde(with = "crate::serde::transaction_svm")] + pub transaction: VersionedTransaction, + /// The expiration time of the quote (in seconds since the Unix epoch). + #[schema(example = 1_700_000_000_000_000i64, value_type = i64)] + pub expiration_time: i64, + /// The input token amount that the user wants to swap. + pub input_token: TokenAmountSvm, + /// The output token amount that the user will receive. + pub output_token: TokenAmountSvm, + /// The maximum slippage percentage that the user is willing to accept. + #[schema(example = 0.5)] + pub maximum_slippage_percentage: f64, + /// The chain id for the quote. + #[schema(example = "solana", value_type = String)] + pub chain_id: ChainId, +} + +#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] +#[serde(tag = "version")] +pub enum QuoteSvm { + #[serde(rename = "v1")] + #[schema(title = "v1")] + V1(QuoteV1Svm), +} + +#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] +#[serde(untagged)] +pub enum Quote { + #[schema(title = "svm")] + Svm(QuoteSvm), +} + +impl OpportunityCreateSvm { + pub fn get_program(&self) -> ProgramSvm { + match self { + OpportunityCreateSvm::V1(params) => match ¶ms.program_params { + OpportunityCreateProgramParamsV1Svm::Limo { .. } => ProgramSvm::Limo, + OpportunityCreateProgramParamsV1Svm::Phantom { .. } => ProgramSvm::Phantom, + }, + } + } +} + +// ----- Implementations ----- +impl OpportunityEvm { + pub fn get_chain_id(&self) -> &ChainId { + match &self.params { + OpportunityParamsEvm::V1(params) => ¶ms.0.chain_id, + } + } +} + +impl OpportunitySvm { + pub fn get_chain_id(&self) -> &ChainId { + match &self.params { + OpportunityParamsSvm::V1(params) => ¶ms.chain_id, + } + } +} + +impl Opportunity { + pub fn get_chain_id(&self) -> &ChainId { + match self { + Opportunity::Evm(opportunity) => opportunity.get_chain_id(), + Opportunity::Svm(opportunity) => opportunity.get_chain_id(), + } + } + + pub fn creation_time(&self) -> UnixTimestampMicros { + match self { + Opportunity::Evm(opportunity) => opportunity.creation_time, + Opportunity::Svm(opportunity) => opportunity.creation_time, + } + } +} + +impl OpportunityDelete { + pub fn get_chain_id(&self) -> &ChainId { + match self { + OpportunityDelete::Svm(OpportunityDeleteSvm::V1(params)) => ¶ms.chain_id, + OpportunityDelete::Evm(OpportunityDeleteEvm::V1(params)) => ¶ms.chain_id, + } + } +} + +#[derive(AsRefStr, Clone)] +#[strum(prefix = "/")] +pub enum Route { + #[strum(serialize = "")] + PostOpportunity, + #[strum(serialize = "quote")] + PostQuote, + #[strum(serialize = "")] + GetOpportunities, + #[strum(serialize = ":opportunity_id/bids")] + OpportunityBid, + #[strum(serialize = "")] + DeleteOpportunities, +} + +impl Routable for Route { + fn properties(&self) -> crate::RouteProperties { + let full_path = format!( + "{}{}{}", + crate::Route::V1.as_ref(), + crate::Route::Opportunity.as_ref(), + self.as_ref() + ) + .trim_end_matches("/") + .to_string(); + match self { + Route::PostOpportunity => crate::RouteProperties { + access_level: AccessLevel::Public, + method: http::Method::POST, + full_path, + }, + Route::PostQuote => crate::RouteProperties { + access_level: AccessLevel::Public, + method: http::Method::POST, + full_path, + }, + Route::GetOpportunities => crate::RouteProperties { + access_level: AccessLevel::Public, + method: http::Method::GET, + full_path, + }, + Route::OpportunityBid => crate::RouteProperties { + access_level: AccessLevel::Public, + method: http::Method::POST, + full_path, + }, + Route::DeleteOpportunities => crate::RouteProperties { + access_level: AccessLevel::LoggedIn, + method: http::Method::DELETE, + full_path, + }, + } + } +} diff --git a/auction-server/api-types/src/profile.rs b/auction-server/api-types/src/profile.rs new file mode 100644 index 00000000..f85c181a --- /dev/null +++ b/auction-server/api-types/src/profile.rs @@ -0,0 +1,123 @@ +use { + crate::{ + AccessLevel, + Routable, + }, + email_address::EmailAddress, + serde::{ + Deserialize, + Serialize, + }, + strum::AsRefStr, + utoipa::{ + IntoParams, + ToResponse, + ToSchema, + }, + uuid::Uuid, +}; + +pub type ProfileId = Uuid; + +#[derive(Serialize, Deserialize, ToSchema, Clone, ToResponse, Debug)] +#[serde(rename_all = "lowercase")] +pub enum ProfileRole { + Searcher, + Protocol, +} + +#[derive(Serialize, Deserialize, ToSchema, Clone, ToResponse, Debug)] +pub struct CreateProfile { + /// The name of the profile to create. + #[schema(example = "John Doe")] + pub name: String, + /// The email of the profile to create. + #[schema(example = "example@example.com", value_type = String)] + pub email: String, + /// The role of the profile to create. + pub role: ProfileRole, +} + +#[derive(Serialize, Deserialize, Clone, Debug, IntoParams)] +pub struct GetProfile { + /// The email of the profile to fetch. + #[param(example = "example@example.com", value_type = String)] + pub email: String, +} + +#[derive(Serialize, Deserialize, ToSchema, Clone, ToResponse)] +pub struct Profile { + /// The id of the profile. + #[schema(example = "obo3ee3e-58cc-4372-a567-0e02b2c3d479", value_type = String)] + pub id: ProfileId, + /// The name of the profile. + #[schema(example = "John Doe")] + pub name: String, + /// The email of the profile. + #[schema(example = "example@example.com", value_type = String)] + pub email: EmailAddress, + /// The role of the profile. + pub role: ProfileRole, +} + +#[derive(Serialize, Deserialize, ToSchema, Clone, ToResponse)] +pub struct CreateAccessToken { + /// The id of the profile to create token for. + #[schema(example = "obo3ee3e-58cc-4372-a567-0e02b2c3d479", value_type = String)] + pub profile_id: ProfileId, +} + +#[derive(Serialize, Deserialize, ToSchema, Clone, ToResponse)] +pub struct AccessToken { + /// The token for later use. + #[schema(example = "_q9zUYP-tQg8F7kQi2Rfl5c6sSy7xcc2yWh2H-nI-iI", value_type = String)] + pub token: String, +} + +#[derive(AsRefStr, Clone)] +#[strum(prefix = "/")] +pub enum Route { + #[strum(serialize = "")] + PostProfile, + #[strum(serialize = "")] + GetProfile, + #[strum(serialize = "access_tokens")] + PostProfileAccessToken, + #[strum(serialize = "access_tokens")] + DeleteProfileAccessToken, +} + +impl Routable for Route { + fn properties(&self) -> crate::RouteProperties { + let full_path = format!( + "{}{}{}", + crate::Route::V1.as_ref(), + crate::Route::Profile.as_ref(), + self.as_ref() + ) + .trim_end_matches("/") + .to_string(); + match self { + Route::PostProfile => crate::RouteProperties { + access_level: AccessLevel::Admin, + method: http::Method::POST, + full_path, + }, + Route::GetProfile => crate::RouteProperties { + access_level: AccessLevel::Admin, + method: http::Method::GET, + full_path, + }, + Route::PostProfileAccessToken => crate::RouteProperties { + access_level: AccessLevel::Admin, + method: http::Method::POST, + full_path, + }, + Route::DeleteProfileAccessToken => crate::RouteProperties { + access_level: AccessLevel::LoggedIn, + method: http::Method::DELETE, + full_path, + }, + } + } +} diff --git a/auction-server/src/serde.rs b/auction-server/api-types/src/serde.rs similarity index 92% rename from auction-server/src/serde.rs rename to auction-server/api-types/src/serde.rs index 5e760851..b64c417a 100644 --- a/auction-server/src/serde.rs +++ b/auction-server/api-types/src/serde.rs @@ -56,6 +56,7 @@ pub mod nullable_datetime { use { serde::{ de::Error, + ser, Deserialize, Deserializer, Serializer, @@ -71,7 +72,11 @@ pub mod nullable_datetime { S: Serializer, { match b { - Some(b) => s.serialize_str(b.to_string().as_str()), + Some(b) => { + // This formatting is critical because the server expects incoming date-time values in the Rfc3339 format for deserialization. + let formatted = b.format(&Rfc3339).map_err(ser::Error::custom)?; + s.serialize_str(formatted.as_str()) + } None => s.serialize_none(), } } diff --git a/auction-server/api-types/src/ws.rs b/auction-server/api-types/src/ws.rs new file mode 100644 index 00000000..f3f53e3b --- /dev/null +++ b/auction-server/api-types/src/ws.rs @@ -0,0 +1,118 @@ +use { + crate::{ + bid::{ + BidCreate, + BidResult, + BidStatusWithId, + }, + opportunity::{ + Opportunity, + OpportunityBidEvm, + OpportunityDelete, + OpportunityId, + }, + ChainId, + Routable, + SvmChainUpdate, + }, + http::Method, + serde::{ + Deserialize, + Serialize, + }, + strum::AsRefStr, + utoipa::ToSchema, +}; + + +#[derive(Deserialize, Clone, ToSchema, Serialize)] +#[serde(tag = "method", content = "params")] +pub enum ClientMessage { + #[serde(rename = "subscribe")] + Subscribe { + #[schema(value_type = Vec)] + chain_ids: Vec, + }, + #[serde(rename = "unsubscribe")] + Unsubscribe { + #[schema(value_type = Vec)] + chain_ids: Vec, + }, + #[serde(rename = "post_bid")] + PostBid { bid: BidCreate }, + + #[serde(rename = "post_opportunity_bid")] + PostOpportunityBid { + #[schema(value_type = String)] + opportunity_id: OpportunityId, + opportunity_bid: OpportunityBidEvm, + }, +} + +#[derive(Deserialize, Clone, ToSchema, Serialize)] +pub struct ClientRequest { + pub id: String, + #[serde(flatten)] + pub msg: ClientMessage, +} + +/// This enum is used to send an update to the client for any subscriptions made. +#[derive(Serialize, Clone, ToSchema, Deserialize, Debug)] +#[serde(tag = "type")] +pub enum ServerUpdateResponse { + #[serde(rename = "new_opportunity")] + NewOpportunity { opportunity: Opportunity }, + #[serde(rename = "bid_status_update")] + BidStatusUpdate { status: BidStatusWithId }, + #[serde(rename = "svm_chain_update")] + SvmChainUpdate { update: SvmChainUpdate }, + #[serde(rename = "remove_opportunities")] + RemoveOpportunities { + opportunity_delete: OpportunityDelete, + }, +} + +#[derive(Serialize, Clone, ToSchema, Deserialize)] +#[serde(untagged)] +pub enum APIResponse { + BidResult(BidResult), +} +#[derive(Serialize, Clone, ToSchema, Deserialize)] +#[serde(tag = "status", content = "result")] +pub enum ServerResultMessage { + #[serde(rename = "success")] + Success(Option), + #[serde(rename = "error")] + Err(String), +} + +/// This enum is used to send the result for a specific client request with the same id. +/// Id is only None when the client message is invalid. +#[derive(Serialize, ToSchema, Deserialize)] +pub struct ServerResultResponse { + pub id: Option, + #[serde(flatten)] + pub result: ServerResultMessage, +} + +#[derive(AsRefStr, Clone)] +#[strum(prefix = "/")] +pub enum Route { + #[strum(serialize = "ws")] + Ws, +} + +impl Routable for Route { + fn properties(&self) -> crate::RouteProperties { + let full_path = format!("{}{}", crate::Route::V1.as_ref(), self.as_ref()) + .trim_end_matches('/') + .to_string(); + match self { + Route::Ws => crate::RouteProperties { + access_level: crate::AccessLevel::Public, + method: Method::GET, + full_path, + }, + } + } +} diff --git a/auction-server/build.rs b/auction-server/build.rs index 1407dafc..55d8d001 100644 --- a/auction-server/build.rs +++ b/auction-server/build.rs @@ -36,7 +36,6 @@ fn build_evm_contracts() { } } - const SUBMIT_BID_INSTRUCTION_SVM: &str = "submit_bid"; const PERMISSION_ACCOUNT_SVM: &str = "permission"; const ROUTER_ACCOUNT_SVM: &str = "router"; diff --git a/auction-server/rust-toolchain.toml b/auction-server/rust-toolchain.toml deleted file mode 100644 index 292fe499..00000000 --- a/auction-server/rust-toolchain.toml +++ /dev/null @@ -1,2 +0,0 @@ -[toolchain] -channel = "stable" diff --git a/auction-server/src/api.rs b/auction-server/src/api.rs index 5680d1ff..ce2a1423 100644 --- a/auction-server/src/api.rs +++ b/auction-server/src/api.rs @@ -1,17 +1,6 @@ use { crate::{ - api::ws::{ - APIResponse, - ClientMessage, - ClientRequest, - ServerResultMessage, - ServerResultResponse, - ServerUpdateResponse, - }, - auction::api::{ - self as bid, - SvmChainUpdate, - }, + auction::api as bid, config::RunOptions, models, opportunity::api as opportunity, @@ -29,8 +18,10 @@ use { FromRef, FromRequestParts, }, + handler::Handler, http::{ request::Parts, + Method, StatusCode, }, middleware, @@ -41,7 +32,9 @@ use { routing::{ delete, get, + patch, post, + put, }, Json, Router, @@ -59,7 +52,14 @@ use { }, clap::crate_version, ethers::types::Bytes, - serde::Serialize, + express_relay_api_types::{ + self as api_types, + profile::Route as ProfileRoute, + AccessLevel, + ErrorBodyResponse, + Routable, + Route, + }, std::sync::{ atomic::Ordering, Arc, @@ -73,8 +73,6 @@ use { }, Modify, OpenApi, - ToResponse, - ToSchema, }, utoipa_redoc::{ Redoc, @@ -165,12 +163,6 @@ impl RestError { } } -#[derive(ToResponse, ToSchema, Serialize)] -#[response(description = "An error occurred processing the request")] -pub struct ErrorBodyResponse { - error: String, -} - impl IntoResponse for RestError { fn into_response(self) -> Response { let (status, msg) = self.to_status_and_message(); @@ -271,6 +263,47 @@ fn remove_discriminators(doc: &mut serde_json::Value) { } } +pub struct WrappedRouter { + store: Arc, + pub router: Router>, +} + +impl WrappedRouter { + pub fn new(store: Arc) -> Self { + Self { + store, + router: Router::new(), + } + } + + pub fn route(self, path: impl Routable, handler: H) -> Self + where + H: Handler>, + T: 'static, + { + let properties = path.properties(); + let router = match properties.method { + Method::GET => get(handler), + Method::POST => post(handler), + Method::DELETE => delete(handler), + Method::PUT => put(handler), + Method::PATCH => patch(handler), + _ => panic!("Unsupported method"), + }; + + let router = match properties.access_level { + AccessLevel::Admin => admin_only!(self.store, router), + AccessLevel::LoggedIn => login_required!(self.store, router), + AccessLevel::Public => router, + }; + + Self { + store: self.store, + router: self.router.route(&properties.full_path, router), + } + } +} + pub async fn start_api(run_options: RunOptions, store: Arc) -> Result<()> { // Make sure functions included in the paths section have distinct names, otherwise some api generators will fail #[derive(OpenApi)] @@ -292,65 +325,65 @@ pub async fn start_api(run_options: RunOptions, store: Arc) -> Result< ), components( schemas( - APIResponse, - bid::BidCreate, - bid::BidCreateEvm, - bid::BidCreateSvm, - bid::BidStatus, - bid::BidStatusEvm, - bid::BidStatusSvm, - bid::BidStatusWithId, - bid::BidResult, - bid::Bid, - bid::BidEvm, - bid::BidSvm, - bid::Bids, - SvmChainUpdate, - - opportunity::OpportunityBidEvm, - opportunity::OpportunityBidResult, - opportunity::OpportunityMode, - opportunity::OpportunityCreate, - opportunity::OpportunityCreateEvm, - opportunity::OpportunityCreateSvm, - opportunity::OpportunityCreateV1Evm, - opportunity::OpportunityCreateV1Svm, - opportunity::OpportunityCreateProgramParamsV1Svm, - opportunity::Opportunity, - opportunity::OpportunityEvm, - opportunity::OpportunitySvm, - opportunity::TokenAmountEvm, - opportunity::TokenAmountSvm, - opportunity::OpportunityParamsSvm, - opportunity::OpportunityParamsEvm, - opportunity::OpportunityParamsV1Svm, - opportunity::OpportunityParamsV1Evm, - opportunity::QuoteCreate, - opportunity::QuoteCreateSvm, - opportunity::QuoteCreateV1Svm, - opportunity::QuoteCreatePhantomV1Svm, - opportunity::Quote, - opportunity::QuoteSvm, - opportunity::QuoteV1Svm, - opportunity::OpportunityDelete, - opportunity::OpportunityDeleteSvm, - opportunity::OpportunityDeleteEvm, - opportunity::OpportunityDeleteV1Svm, - opportunity::OpportunityDeleteV1Evm, - opportunity::ProgramSvm, + api_types::ws::APIResponse, + api_types::bid::BidCreate, + api_types::bid::BidCreateEvm, + api_types::bid::BidCreateSvm, + api_types::bid::BidStatus, + api_types::bid::BidStatusEvm, + api_types::bid::BidStatusSvm, + api_types::bid::BidStatusWithId, + api_types::bid::BidResult, + api_types::bid::Bid, + api_types::bid::BidEvm, + api_types::bid::BidSvm, + api_types::bid::Bids, + api_types::SvmChainUpdate, + + api_types::opportunity::OpportunityBidEvm, + api_types::opportunity::OpportunityBidResult, + api_types::opportunity::OpportunityMode, + api_types::opportunity::OpportunityCreate, + api_types::opportunity::OpportunityCreateEvm, + api_types::opportunity::OpportunityCreateSvm, + api_types::opportunity::OpportunityCreateV1Evm, + api_types::opportunity::OpportunityCreateV1Svm, + api_types::opportunity::OpportunityCreateProgramParamsV1Svm, + api_types::opportunity::Opportunity, + api_types::opportunity::OpportunityEvm, + api_types::opportunity::OpportunitySvm, + api_types::opportunity::TokenAmountEvm, + api_types::opportunity::TokenAmountSvm, + api_types::opportunity::OpportunityParamsSvm, + api_types::opportunity::OpportunityParamsEvm, + api_types::opportunity::OpportunityParamsV1Svm, + api_types::opportunity::OpportunityParamsV1Evm, + api_types::opportunity::QuoteCreate, + api_types::opportunity::QuoteCreateSvm, + api_types::opportunity::QuoteCreateV1Svm, + api_types::opportunity::QuoteCreatePhantomV1Svm, + api_types::opportunity::Quote, + api_types::opportunity::QuoteSvm, + api_types::opportunity::QuoteV1Svm, + api_types::opportunity::OpportunityDelete, + api_types::opportunity::OpportunityDeleteSvm, + api_types::opportunity::OpportunityDeleteEvm, + api_types::opportunity::OpportunityDeleteV1Svm, + api_types::opportunity::OpportunityDeleteV1Evm, + api_types::opportunity::ProgramSvm, ErrorBodyResponse, - ClientRequest, - ClientMessage, - ServerResultMessage, - ServerUpdateResponse, - ServerResultResponse, + api_types::ws::ClientRequest, + api_types::ws::ClientMessage, + api_types::ws::ServerResultMessage, + api_types::ws::ServerUpdateResponse, + api_types::ws::ServerResultResponse, ), responses( ErrorBodyResponse, - opportunity::Opportunity, - bid::BidResult, - bid::Bids, + api_types::opportunity::Opportunity, + api_types::bid::BidResult, + api_types::bid::Bids, ), ), tags( @@ -376,31 +409,24 @@ pub async fn start_api(run_options: RunOptions, store: Arc) -> Result< } } - let profile_routes = Router::new() - .route("/", admin_only!(store, post(profile::post_profile))) - .route("/", admin_only!(store, get(profile::get_profile))) + let profile_routes = WrappedRouter::new(store.clone()) + .route(ProfileRoute::PostProfile, profile::post_profile) + .route(ProfileRoute::GetProfile, profile::get_profile) .route( - "/access_tokens", - admin_only!(store, post(profile::post_profile_access_token)), + ProfileRoute::PostProfileAccessToken, + profile::post_profile_access_token, ) .route( - "/access_tokens", - login_required!(store, delete(profile::delete_profile_access_token)), - ); - - let v1_routes = Router::new().nest( - "/v1", - Router::new() - .nest("/bids", bid::get_routes(store.clone())) - .nest("/opportunities", opportunity::get_routes(store.clone())) - .nest("/profiles", profile_routes) - .route("/ws", get(ws::ws_route_handler)), - ); - - let v1_routes_with_chain_id = Router::new().nest( - "/v1/:chain_id", - Router::new().nest("/bids", bid::get_routes_with_chain_id(store.clone())), - ); + ProfileRoute::DeleteProfileAccessToken, + profile::delete_profile_access_token, + ) + .router; + + let routes = Router::new() + .merge(bid::get_routes(store.clone())) + .merge(opportunity::get_routes(store.clone())) + .merge(profile_routes) + .merge(ws::get_routes(store.clone())); let (prometheus_layer, _) = PrometheusMetricLayerBuilder::new() .with_metrics_from_fn(|| store.store.metrics_recorder.clone()) @@ -417,12 +443,11 @@ pub async fn start_api(run_options: RunOptions, store: Arc) -> Result< remove_discriminators(&mut redoc_doc); let app: Router<()> = Router::new() - .merge(Redoc::with_url("/docs", redoc_doc.clone())) - .merge(v1_routes) - .merge(v1_routes_with_chain_id) - .route("/", get(root)) - .route("/live", get(live)) - .route("/docs/openapi.json", get(original_doc.to_string())) + .merge(Redoc::with_url(Route::Docs.as_ref(), redoc_doc.clone())) + .merge(routes) + .route(Route::Root.as_ref(), get(root)) + .route(Route::Liveness.as_ref(), get(live)) + .route(Route::OpenApi.as_ref(), get(original_doc.to_string())) .layer(CorsLayer::permissive()) .layer(middleware::from_extractor_with_state::>(store.clone())) .layer(prometheus_layer) diff --git a/auction-server/src/api/profile.rs b/auction-server/src/api/profile.rs index da4c5416..29ca1ed6 100644 --- a/auction-server/src/api/profile.rs +++ b/auction-server/src/api/profile.rs @@ -15,26 +15,17 @@ use { }, Json, }, - email_address::EmailAddress, - serde::{ - Deserialize, - Serialize, + express_relay_api_types::profile::{ + AccessToken, + CreateAccessToken, + CreateProfile, + GetProfile, + Profile, + ProfileRole, }, std::sync::Arc, - utoipa::{ - IntoParams, - ToResponse, - ToSchema, - }, }; -#[derive(Serialize, Deserialize, ToSchema, Clone, ToResponse, Debug)] -#[serde(rename_all = "lowercase")] -pub enum ProfileRole { - Searcher, - Protocol, -} - impl From for ProfileRole { fn from(role: models::ProfileRole) -> Self { match role { @@ -53,54 +44,6 @@ impl From for models::ProfileRole { } } -#[derive(Serialize, Deserialize, ToSchema, Clone, ToResponse, Debug)] -pub struct CreateProfile { - /// The name of the profile to create. - #[schema(example = "John Doe")] - pub name: String, - /// The email of the profile to create. - #[schema(example = "example@example.com", value_type = String)] - pub email: String, - /// The role of the profile to create. - pub role: ProfileRole, -} - -#[derive(Serialize, Deserialize, Clone, Debug, IntoParams)] -pub struct GetProfile { - /// The email of the profile to fetch. - #[param(example = "example@example.com", value_type = String)] - pub email: String, -} - -#[derive(Serialize, Deserialize, ToSchema, Clone, ToResponse)] -pub struct Profile { - /// The id of the profile. - #[schema(example = "obo3ee3e-58cc-4372-a567-0e02b2c3d479", value_type = String)] - id: models::ProfileId, - /// The name of the profile. - #[schema(example = "John Doe")] - name: String, - /// The email of the profile. - #[schema(example = "example@example.com", value_type = String)] - email: EmailAddress, - /// The role of the profile. - pub role: ProfileRole, -} - -#[derive(Serialize, Deserialize, ToSchema, Clone, ToResponse)] -pub struct CreateAccessToken { - /// The id of the profile to create token for. - #[schema(example = "obo3ee3e-58cc-4372-a567-0e02b2c3d479", value_type = String)] - profile_id: models::ProfileId, -} - -#[derive(Serialize, Deserialize, ToSchema, Clone, ToResponse)] -pub struct AccessToken { - /// The token for later use. - #[schema(example = "_q9zUYP-tQg8F7kQi2Rfl5c6sSy7xcc2yWh2H-nI-iI", value_type = String)] - token: String, -} - /// Create a new profile. /// /// Returns the created profile object. diff --git a/auction-server/src/api/ws.rs b/auction-server/src/api/ws.rs index 17852166..8b20fadd 100644 --- a/auction-server/src/api/ws.rs +++ b/auction-server/src/api/ws.rs @@ -1,26 +1,15 @@ use { - super::Auth, + super::{ + Auth, + WrappedRouter, + }, crate::{ auction::{ - api::{ - process_bid, - BidCreate, - BidResult, - BidStatusWithId, - SvmChainUpdate, - }, + api::process_bid, entities::BidId, }, config::ChainId, - opportunity::{ - api::{ - Opportunity, - OpportunityBidEvm, - OpportunityDelete, - OpportunityId, - }, - service::handle_opportunity_bid::HandleOpportunityBidInput, - }, + opportunity::service::handle_opportunity_bid::HandleOpportunityBidInput, server::{ EXIT_CHECK_INTERVAL, SHOULD_EXIT, @@ -41,6 +30,30 @@ use { WebSocketUpgrade, }, response::IntoResponse, + Router, + }, + express_relay_api_types::{ + bid::{ + BidCreate, + BidResult, + BidStatusWithId, + }, + opportunity::{ + Opportunity, + OpportunityBidEvm, + OpportunityDelete, + OpportunityId, + }, + ws::{ + APIResponse, + ClientMessage, + ClientRequest, + Route, + ServerResultMessage, + ServerResultResponse, + ServerUpdateResponse, + }, + SvmChainUpdate, }, futures::{ stream::{ @@ -50,10 +63,6 @@ use { SinkExt, StreamExt, }, - serde::{ - Deserialize, - Serialize, - }, std::{ collections::HashSet, sync::{ @@ -71,7 +80,6 @@ use { instrument, Instrument, }, - utoipa::ToSchema, }; pub struct WsState { @@ -80,76 +88,6 @@ pub struct WsState { pub broadcast_receiver: broadcast::Receiver, } -#[derive(Deserialize, Clone, ToSchema)] -#[serde(tag = "method", content = "params")] -pub enum ClientMessage { - #[serde(rename = "subscribe")] - Subscribe { - #[schema(value_type = Vec)] - chain_ids: Vec, - }, - #[serde(rename = "unsubscribe")] - Unsubscribe { - #[schema(value_type = Vec)] - chain_ids: Vec, - }, - #[serde(rename = "post_bid")] - PostBid { bid: BidCreate }, - - #[serde(rename = "post_opportunity_bid")] - PostOpportunityBid { - #[schema(value_type = String)] - opportunity_id: OpportunityId, - opportunity_bid: OpportunityBidEvm, - }, -} - -#[derive(Deserialize, Clone, ToSchema)] -pub struct ClientRequest { - id: String, - #[serde(flatten)] - msg: ClientMessage, -} - -/// This enum is used to send an update to the client for any subscriptions made. -#[derive(Serialize, Clone, ToSchema)] -#[serde(tag = "type")] -pub enum ServerUpdateResponse { - #[serde(rename = "new_opportunity")] - NewOpportunity { opportunity: Opportunity }, - #[serde(rename = "bid_status_update")] - BidStatusUpdate { status: BidStatusWithId }, - #[serde(rename = "svm_chain_update")] - SvmChainUpdate { update: SvmChainUpdate }, - #[serde(rename = "remove_opportunities")] - RemoveOpportunities { - opportunity_delete: OpportunityDelete, - }, -} - -#[derive(Serialize, Clone, ToSchema)] -#[serde(untagged)] -pub enum APIResponse { - BidResult(BidResult), -} -#[derive(Serialize, Clone, ToSchema)] -#[serde(tag = "status", content = "result")] -pub enum ServerResultMessage { - #[serde(rename = "success")] - Success(Option), - #[serde(rename = "error")] - Err(String), -} - -/// This enum is used to send the result for a specific client request with the same id. -/// Id is only None when the client message is invalid. -#[derive(Serialize, Clone, ToSchema)] -pub struct ServerResultResponse { - id: Option, - #[serde(flatten)] - result: ServerResultMessage, -} - pub async fn ws_route_handler( auth: Auth, ws: WebSocketUpgrade, @@ -533,3 +471,10 @@ impl Subscriber { Ok(()) } } + + +pub fn get_routes(store: Arc) -> Router> { + WrappedRouter::new(store) + .route(Route::Ws, ws_route_handler) + .router +} diff --git a/auction-server/src/auction/api.rs b/auction-server/src/auction/api.rs index f4c6f9fd..41673306 100644 --- a/auction-server/src/auction/api.rs +++ b/auction-server/src/auction/api.rs @@ -4,7 +4,6 @@ use { self, BidChainData, }, - repository::MicroLamports, service::{ get_bid::GetBidInput, get_bids::GetBidsInput, @@ -17,19 +16,15 @@ use { }, crate::{ api::{ - require_login_middleware, Auth, - ErrorBodyResponse, RestError, + WrappedRouter, }, kernel::entities::{ ChainId, Evm, - PermissionKey, - PermissionKeySvm, Svm, }, - login_required, models, state::StoreNew, }, @@ -40,297 +35,37 @@ use { Query, State, }, - middleware, - routing::{ - get, - post, - }, Json, Router, }, - ethers::types::{ - Address, - Bytes, - H256, - U256, - }, - serde::{ - Deserialize, - Serialize, - }, - serde_with::{ - serde_as, - DisplayFromStr, - }, - solana_sdk::{ - hash::Hash, - signature::Signature, - transaction::VersionedTransaction, + express_relay_api_types::{ + bid::{ + Bid, + BidCoreFields, + BidCreate, + BidCreateEvm, + BidCreateSvm, + BidEvm, + BidId, + BidResult, + BidStatus, + BidStatusEvm, + BidStatusSvm, + BidSvm, + Bids, + GetBidStatusParams, + GetBidsByTimeQueryParams, + Route, + }, + ErrorBodyResponse, }, sqlx::types::time::OffsetDateTime, std::{ fmt::Debug, sync::Arc, }, - utoipa::{ - IntoParams, - ToResponse, - ToSchema, - }, - uuid::Uuid, }; -// TODO move it to kernel? - -#[serde_as] -#[derive(Serialize, Clone, ToSchema, ToResponse)] -pub struct SvmChainUpdate { - #[schema(example = "solana", value_type = String)] - pub chain_id: ChainId, - #[serde_as(as = "DisplayFromStr")] - #[schema(example = "SLxp9LxX1eE9Z5v99Y92DaYEwyukFgMUF6zRerCF12j", value_type = String)] - pub blockhash: Hash, - /// The prioritization fee that the server suggests to use for the next transaction - #[schema(example = "1000", value_type = u64)] - pub latest_prioritization_fee: MicroLamports, -} - -pub type BidId = Uuid; - -#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] -#[serde(tag = "type", rename_all = "snake_case")] -pub enum BidStatusEvm { - /// The temporary state which means the auction for this bid is pending. - #[schema(title = "Pending")] - Pending, - /// The bid is submitted to the chain, which is placed at the given index of the transaction with the given hash. - /// This state is temporary and will be updated to either lost or won after conclusion of the auction. - #[schema(title = "Submitted")] - Submitted { - #[schema(example = "0x103d4fbd777a36311b5161f2062490f761f25b67406badb2bace62bb170aa4e3", value_type = String)] - result: H256, - #[schema(example = 1, value_type = u32)] - index: u32, - }, - /// The bid lost the auction, which is concluded with the transaction with the given hash and index. - /// The result will be None if the auction was concluded off-chain and no auction was submitted to the chain. - /// The index will be None if the bid was not submitted to the chain and lost the auction by off-chain calculation. - /// There are cases where the result is not None and the index is None. - /// It is because other bids were selected for submission to the chain, but not this one. - #[schema(title = "Lost")] - Lost { - #[schema(example = "0x103d4fbd777a36311b5161f2062490f761f25b67406badb2bace62bb170aa4e3", value_type = Option)] - result: Option, - #[schema(example = 1, value_type = Option)] - index: Option, - }, - /// The bid won the auction, which is concluded with the transaction with the given hash and index. - #[schema(title = "Won")] - Won { - #[schema(example = "0x103d4fbd777a36311b5161f2062490f761f25b67406badb2bace62bb170aa4e3", value_type = String)] - result: H256, - #[schema(example = 1, value_type = u32)] - index: u32, - }, -} - -#[serde_as] -#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] -#[serde(tag = "type", rename_all = "snake_case")] -pub enum BidStatusSvm { - /// The temporary state which means the auction for this bid is pending. - /// It will be updated to Lost or Submitted after the auction takes place. - #[schema(title = "Pending")] - Pending, - /// The bid lost the auction. - /// This bid status will have a result field containing the signature of the transaction corresponding to the winning bid, - /// unless the auction had no winner (because all bids were found to be invalid). - #[schema(title = "Lost")] - Lost { - #[schema(example = "Jb2urXPyEh4xiBgzYvwEFe4q1iMxG1DNxWGGQg94AmKgqFTwLAiTiHrYiYxwHUB4DV8u5ahNEVtMMDm3sNSRdTg", value_type = Option)] - #[serde(with = "crate::serde::nullable_signature_svm")] - result: Option, - }, - /// The bid won the auction and was submitted to the chain, with the signature of the corresponding transaction provided in the result field. - /// This state is temporary and will be updated to either Won or Failed after the transaction is included in a block, or Expired if the transaction expires before it is included. - #[schema(title = "Submitted")] - Submitted { - #[schema(example = "Jb2urXPyEh4xiBgzYvwEFe4q1iMxG1DNxWGGQg94AmKgqFTwLAiTiHrYiYxwHUB4DV8u5ahNEVtMMDm3sNSRdTg", value_type = String)] - #[serde_as(as = "DisplayFromStr")] - result: Signature, - }, - /// The bid won the auction and was included in a block successfully. - #[schema(title = "Won")] - Won { - #[schema(example = "Jb2urXPyEh4xiBgzYvwEFe4q1iMxG1DNxWGGQg94AmKgqFTwLAiTiHrYiYxwHUB4DV8u5ahNEVtMMDm3sNSRdTg", value_type = String)] - #[serde_as(as = "DisplayFromStr")] - result: Signature, - }, - /// The bid was submitted on-chain, was included in a block, but resulted in a failed transaction. - #[schema(title = "Failed")] - Failed { - #[schema(example = "Jb2urXPyEh4xiBgzYvwEFe4q1iMxG1DNxWGGQg94AmKgqFTwLAiTiHrYiYxwHUB4DV8u5ahNEVtMMDm3sNSRdTg", value_type = String)] - #[serde_as(as = "DisplayFromStr")] - result: Signature, - }, - /// The bid was submitted on-chain but expired before it was included in a block. - #[schema(title = "Expired")] - Expired { - #[schema(example = "Jb2urXPyEh4xiBgzYvwEFe4q1iMxG1DNxWGGQg94AmKgqFTwLAiTiHrYiYxwHUB4DV8u5ahNEVtMMDm3sNSRdTg", value_type = String)] - #[serde_as(as = "DisplayFromStr")] - result: Signature, - }, -} - -#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] -#[serde(untagged)] -pub enum BidStatus { - Evm(BidStatusEvm), - Svm(BidStatusSvm), -} - -#[derive(Serialize, Deserialize, ToResponse, ToSchema, Clone)] -pub struct BidResult { - /// The status of the request. If the bid was placed successfully, the status will be "OK". - #[schema(example = "OK")] - pub status: String, - /// The unique id created to identify the bid. This id can be used to query the status of the bid. - #[schema(example = "beedbeed-58cc-4372-a567-0e02b2c3d479", value_type=String)] - pub id: BidId, -} - -#[derive(Clone, Debug, ToSchema, Serialize, Deserialize)] -pub struct BidCoreFields { - /// The unique id for bid. - #[schema(example = "obo3ee3e-58cc-4372-a567-0e02b2c3d479", value_type = String)] - pub id: BidId, - /// The chain id for bid. - #[schema(example = "op_sepolia", value_type = String)] - pub chain_id: ChainId, - /// The time server received the bid formatted in rfc3339. - #[schema(example = "2024-05-23T21:26:57.329954Z", value_type = String)] - #[serde(with = "time::serde::rfc3339")] - pub initiation_time: OffsetDateTime, - /// The profile id for the bid owner. - #[schema(example = "obo3ee3e-58cc-4372-a567-0e02b2c3d479", value_type = String)] - pub profile_id: Option, -} - -#[derive(Clone, Debug, ToSchema, Serialize, Deserialize)] -pub struct BidSvm { - #[serde(flatten)] - #[schema(inline)] - pub core_fields: BidCoreFields, - /// The latest status for bid. - pub status: BidStatusSvm, - /// The transaction of the bid. - #[schema(example = "SGVsbG8sIFdvcmxkIQ==", value_type = String)] - #[serde(with = "crate::serde::transaction_svm")] - pub transaction: VersionedTransaction, - /// Amount of bid in lamports. - #[schema(example = "1000", value_type = u64)] - pub bid_amount: entities::BidAmountSvm, - /// The permission key for bid in base64 format. - /// This is the concatenation of the permission account and the router account. - #[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)] - pub permission_key: PermissionKeySvm, -} - -#[derive(Clone, Debug, ToSchema, Serialize, Deserialize)] -pub struct BidEvm { - #[serde(flatten)] - #[schema(inline)] - pub core_fields: BidCoreFields, - /// The latest status for bid. - pub status: BidStatusEvm, - /// The contract address to call. - #[schema(example = "0xcA11bde05977b3631167028862bE2a173976CA11", value_type = String)] - pub target_contract: Address, - /// Calldata for the contract call. - #[schema(example = "0xdeadbeef", value_type = String)] - pub target_calldata: Bytes, - /// The gas limit for the contract call. - #[schema(example = "2000000", value_type = String)] - #[serde(with = "crate::serde::u256")] - pub gas_limit: U256, - /// Amount of bid in wei. - #[schema(example = "10", value_type = String)] - #[serde(with = "crate::serde::u256")] - pub bid_amount: entities::BidAmountEvm, - /// The permission key for bid. - #[schema(example = "0xdeadbeef", value_type = String)] - pub permission_key: PermissionKey, -} - -#[derive(Clone, Debug, ToSchema, Serialize, Deserialize)] -#[serde(untagged)] -#[allow(clippy::large_enum_variant)] -pub enum Bid { - Evm(BidEvm), - Svm(BidSvm), -} - -impl Bid { - pub fn get_initiation_time(&self) -> OffsetDateTime { - match self { - Bid::Evm(bid) => bid.core_fields.initiation_time, - Bid::Svm(bid) => bid.core_fields.initiation_time, - } - } - - pub fn get_status(&self) -> BidStatus { - match self { - Bid::Evm(bid) => BidStatus::Evm(bid.status.clone()), - Bid::Svm(bid) => BidStatus::Svm(bid.status.clone()), - } - } -} - -#[derive(Serialize, Deserialize, ToSchema, Clone, Debug)] -pub struct BidCreateEvm { - /// The permission key to bid on. - #[schema(example = "0xdeadbeef", value_type = String)] - pub permission_key: Bytes, - /// The chain id to bid on. - #[schema(example = "op_sepolia", value_type = String)] - pub chain_id: ChainId, - /// The contract address to call. - #[schema(example = "0xcA11bde05977b3631167028862bE2a173976CA11", value_type = String)] - pub target_contract: Address, - /// Calldata for the contract call. - #[schema(example = "0xdeadbeef", value_type = String)] - pub target_calldata: Bytes, - /// Amount of bid in wei. - #[schema(example = "10", value_type = String)] - #[serde(with = "crate::serde::u256")] - pub amount: entities::BidAmountEvm, -} - -#[derive(Serialize, Deserialize, ToSchema, Clone, Debug)] -pub struct BidCreateSvm { - /// The chain id to bid on. - #[schema(example = "solana", value_type = String)] - pub chain_id: ChainId, - /// The transaction for bid. - #[schema(example = "SGVsbG8sIFdvcmxkIQ==", value_type = String)] - #[serde(with = "crate::serde::transaction_svm")] - pub transaction: VersionedTransaction, -} - -#[derive(Serialize, Deserialize, ToSchema, Debug, Clone)] -#[serde(untagged)] // Remove tags to avoid key-value wrapping -pub enum BidCreate { - Evm(BidCreateEvm), - Svm(BidCreateSvm), -} - -#[derive(Serialize, Clone, ToSchema, ToResponse)] -pub struct BidStatusWithId { - #[schema(value_type = String)] - pub id: BidId, - pub bid_status: BidStatus, -} - /// Bid on a specific permission key for a specific chain. /// /// Your bid will be verified by the server. Depending on the outcome of the auction, a transaction @@ -363,15 +98,6 @@ pub async fn process_bid( } } -#[derive(Serialize, Deserialize, IntoParams, Clone)] -pub struct GetBidStatusParams { - #[param(example="op_sepolia", value_type = String)] - pub chain_id: ChainId, - - #[param(example="obo3ee3e-58cc-4372-a567-0e02b2c3d479", value_type = String)] - pub bid_id: BidId, -} - /// Query the status of a specific bid. #[utoipa::path(get, path = "/v1/{chain_id}/bids/{bid_id}", responses( @@ -421,18 +147,6 @@ pub async fn get_bid_status_deprecated( Err(RestError::BidNotFound) } -#[derive(Serialize, Deserialize, ToResponse, ToSchema, Clone)] -pub struct Bids { - pub items: Vec, -} - -#[derive(Serialize, Deserialize, IntoParams)] -pub struct GetBidsByTimeQueryParams { - #[param(example="2024-05-23T21:26:57.329954Z", value_type = Option)] - #[serde(default, with = "crate::serde::nullable_datetime")] - pub from_time: Option, -} - /// Returns at most 20 bids which were submitted after a specific time and chain. /// If no time is provided, the server will return the first bids. #[utoipa::path(get, path = "/v1/{chain_id}/bids", @@ -515,19 +229,19 @@ pub async fn get_bids_by_time_deprecated( pub fn get_routes(store: Arc) -> Router> { #[allow(deprecated)] - Router::new() - .route("/", post(post_bid)) + WrappedRouter::new(store) + .route(Route::PostBid, post_bid) + .route(Route::GetBidsByTime, get_bids_by_time) + .route(Route::GetBidStatus, get_bid_status) .route( - "/", - login_required!(store, get(get_bids_by_time_deprecated)), + express_relay_api_types::bid::DeprecatedRoute::DeprecatedGetBidsByTime, + get_bids_by_time_deprecated, ) - .route("/:bid_id", get(get_bid_status_deprecated)) -} - -pub fn get_routes_with_chain_id(store: Arc) -> Router> { - Router::new() - .route("/", login_required!(store, get(get_bids_by_time))) - .route("/:bid_id", get(get_bid_status)) + .route( + express_relay_api_types::bid::DeprecatedRoute::DeprecatedGetBidStatus, + get_bid_status_deprecated, + ) + .router } impl From for BidStatusEvm { @@ -573,22 +287,19 @@ impl From for BidStatusSvm { } } -// TODO switch to generic structure format -impl BidCoreFields { - pub fn from_bid(bid: &entities::Bid) -> Self { - BidCoreFields { - id: bid.id, - chain_id: bid.chain_id.clone(), - initiation_time: bid.initiation_time, - profile_id: bid.profile_id, - } +fn get_core_fields(bid: &entities::Bid) -> BidCoreFields { + BidCoreFields { + id: bid.id, + chain_id: bid.chain_id.clone(), + initiation_time: bid.initiation_time, + profile_id: bid.profile_id, } } impl From> for Bid { fn from(bid: entities::Bid) -> Self { Bid::Evm(BidEvm { - core_fields: BidCoreFields::from_bid(&bid), + core_fields: get_core_fields(&bid), status: bid.status.into(), permission_key: bid.chain_data.get_permission_key(), target_contract: bid.chain_data.target_contract, @@ -602,8 +313,10 @@ impl From> for Bid { impl From> for Bid { fn from(bid: entities::Bid) -> Self { Bid::Svm(BidSvm { - core_fields: BidCoreFields::from_bid(&bid), - permission_key: bid.chain_data.get_permission_key(), + core_fields: get_core_fields(&bid), + permission_key: express_relay_api_types::PermissionKeySvm( + bid.chain_data.get_permission_key().0, + ), status: bid.status.into(), transaction: bid.chain_data.transaction, bid_amount: bid.amount, @@ -611,15 +324,6 @@ impl From> for Bid { } } -impl BidCreate { - fn get_chain_id(&self) -> ChainId { - match self { - BidCreate::Evm(bid_create_evm) => bid_create_evm.chain_id.clone(), - BidCreate::Svm(bid_create_svm) => bid_create_svm.chain_id.clone(), - } - } -} - impl From for BidStatus { fn from(bid: entities::BidStatusEvm) -> Self { BidStatus::Evm(bid.into()) diff --git a/auction-server/src/auction/entities/bid.rs b/auction-server/src/auction/entities/bid.rs index 04a09a54..a6cd2c13 100644 --- a/auction-server/src/auction/entities/bid.rs +++ b/auction-server/src/auction/entities/bid.rs @@ -1,10 +1,7 @@ use { super::AuctionId, crate::{ - auction::{ - api, - service::ChainTrait, - }, + auction::service::ChainTrait, kernel::{ contracts::MulticallData, entities::{ @@ -26,6 +23,7 @@ use { H256, U256, }, + express_relay_api_types::bid as api, solana_sdk::{ pubkey::Pubkey, signature::Signature, diff --git a/auction-server/src/auction/repository/models.rs b/auction-server/src/auction/repository/models.rs index 2777cede..f5d6233a 100644 --- a/auction-server/src/auction/repository/models.rs +++ b/auction-server/src/auction/repository/models.rs @@ -103,7 +103,7 @@ pub struct BidMetadataEvm { #[derive(Clone, Debug, Serialize, Deserialize)] pub struct BidMetadataSvm { - #[serde(with = "crate::serde::transaction_svm")] + #[serde(with = "express_relay_api_types::serde::transaction_svm")] pub transaction: VersionedTransaction, } diff --git a/auction-server/src/auction/service/auction_manager.rs b/auction-server/src/auction/service/auction_manager.rs index 0e85fe30..0bd30d91 100644 --- a/auction-server/src/auction/service/auction_manager.rs +++ b/auction-server/src/auction/service/auction_manager.rs @@ -127,7 +127,6 @@ pub trait AuctionManager { ) -> T::BidStatusType; } - // While we are submitting bids together, increasing this number will have the following effects: // 1. There will be more gas required for the transaction, which will result in a higher minimum bid amount. // 2. The transaction size limit will be reduced for each bid. @@ -536,7 +535,6 @@ impl AuctionManager for Service { }) .collect(); - Ok(res) } diff --git a/auction-server/src/auction/service/simulator.rs b/auction-server/src/auction/service/simulator.rs index 7e5f75ea..ded482ad 100644 --- a/auction-server/src/auction/service/simulator.rs +++ b/auction-server/src/auction/service/simulator.rs @@ -109,7 +109,6 @@ impl Simulator { pending_txs.iter().map(|(tx, _)| tx.clone()).collect() } - /// Adds a pending transaction to the simulator to be considered in the next simulations /// This function should be called when a transaction is submitted to the chain pub async fn add_pending_transaction(&self, tx: &VersionedTransaction) { diff --git a/auction-server/src/auction/service/update_bid_status.rs b/auction-server/src/auction/service/update_bid_status.rs index 78c5fb5b..85d1a910 100644 --- a/auction-server/src/auction/service/update_bid_status.rs +++ b/auction-server/src/auction/service/update_bid_status.rs @@ -8,11 +8,9 @@ use { ws::UpdateEvent, RestError, }, - auction::{ - api::BidStatusWithId, - entities, - }, + auction::entities, }, + express_relay_api_types::bid::BidStatusWithId, }; pub struct UpdateBidStatusInput { diff --git a/auction-server/src/auction/service/workers.rs b/auction-server/src/auction/service/workers.rs index 204d50ce..f95524e5 100644 --- a/auction-server/src/auction/service/workers.rs +++ b/auction-server/src/auction/service/workers.rs @@ -7,7 +7,6 @@ use { crate::{ api::ws::UpdateEvent, auction::{ - api::SvmChainUpdate, entities, service::conclude_auction::ConcludeAuctionWithStatusesInput, }, @@ -26,6 +25,7 @@ use { }, axum_prometheus::metrics, ethers::providers::Middleware, + express_relay_api_types::SvmChainUpdate, futures::future::join_all, solana_client::{ rpc_config::{ diff --git a/auction-server/src/kernel/entities.rs b/auction-server/src/kernel/entities.rs index 00759b9e..c9b37478 100644 --- a/auction-server/src/kernel/entities.rs +++ b/auction-server/src/kernel/entities.rs @@ -3,19 +3,6 @@ use { base64::Engine, bincode::serialized_size, ethers::types::Bytes, - serde::{ - Deserialize, - Serialize, - }, - serde_with::{ - base64::{ - Base64, - Standard, - }, - formats::Padded, - DeserializeAs, - SerializeAs, - }, solana_sdk::{ packet::PACKET_DATA_SIZE, transaction::VersionedTransaction, @@ -28,16 +15,6 @@ pub type PermissionKey = Bytes; #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct PermissionKeySvm(pub [u8; 64]); - -impl Serialize for PermissionKeySvm { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - Base64::::serialize_as(&self.0, serializer) - } -} - impl Display for PermissionKeySvm { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!( @@ -48,16 +25,6 @@ impl Display for PermissionKeySvm { } } -impl<'de> Deserialize<'de> for PermissionKeySvm { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - let bytes = Base64::::deserialize_as(deserializer)?; - Ok(PermissionKeySvm(bytes)) - } -} - #[derive(Debug, PartialEq, Clone)] pub enum ChainType { Evm, @@ -67,7 +34,6 @@ pub enum ChainType { #[derive(Clone, Debug, PartialEq)] pub struct Evm; - #[derive(Clone, Debug, PartialEq)] pub struct Svm; diff --git a/auction-server/src/main.rs b/auction-server/src/main.rs index d4e00ecf..a44d1c5f 100644 --- a/auction-server/src/main.rs +++ b/auction-server/src/main.rs @@ -36,7 +36,6 @@ mod kernel; mod models; mod opportunity; mod per_metrics; -mod serde; mod server; mod state; mod subwallet; @@ -55,7 +54,6 @@ async fn main() -> Result<()> { .with_target(true) .with_ansi(std::io::stderr().is_terminal()); - // Will use env variable OTEL_EXPORTER_OTLP_ENDPOINT or defaults to 127.0.0.1:4317 let otlp_exporter = opentelemetry_otlp::new_exporter() .tonic() diff --git a/auction-server/src/models.rs b/auction-server/src/models.rs index 037f3ae4..d39eeb4b 100644 --- a/auction-server/src/models.rs +++ b/auction-server/src/models.rs @@ -7,7 +7,6 @@ use { uuid::Uuid, }; - #[derive(Clone, Debug)] pub struct EmailAddress(pub email_address::EmailAddress); diff --git a/auction-server/src/opportunity/api.rs b/auction-server/src/opportunity/api.rs index a285aa70..6ef3c3a8 100644 --- a/auction-server/src/opportunity/api.rs +++ b/auction-server/src/opportunity/api.rs @@ -11,17 +11,10 @@ use { }, crate::{ api::{ - require_login_middleware, Auth, - ErrorBodyResponse, RestError, + WrappedRouter, }, - auction::api::BidId, - kernel::entities::{ - ChainId, - PermissionKey, - }, - login_required, models, state::StoreNew, }, @@ -32,450 +25,30 @@ use { State, }, http::StatusCode, - middleware, - routing::{ - delete, - get, - post, - }, Json, Router, }, - ethers::types::{ - Address, - Bytes, - Signature, - U256, - }, - serde::{ - Deserialize, - Serialize, - }, - serde_with::{ - base64::Base64, - serde_as, - DisplayFromStr, - }, - solana_sdk::{ - clock::Slot, - pubkey::Pubkey, - transaction::VersionedTransaction, + express_relay_api_types::{ + opportunity::{ + GetOpportunitiesQueryParams, + Opportunity, + OpportunityBidEvm, + OpportunityBidResult, + OpportunityCreate, + OpportunityDelete, + OpportunityDeleteSvm, + OpportunityId, + ProgramSvm, + Quote, + QuoteCreate, + Route, + }, + ErrorBodyResponse, }, std::sync::Arc, time::OffsetDateTime, - utoipa::{ - schema, - IntoParams, - ToResponse, - ToSchema, - }, - uuid::Uuid, }; -// Base types -pub type UnixTimestampMicros = i128; -pub type OpportunityId = Uuid; - -#[derive(Debug, Serialize, Deserialize, ToSchema, Clone)] -#[serde(rename_all = "lowercase")] -pub enum OpportunityMode { - Live, - Historical, -} - -#[derive(Serialize, Deserialize, ToResponse, ToSchema, Clone)] -pub struct OpportunityBidResult { - #[schema(example = "OK")] - pub status: String, - /// The unique id created to identify the bid. This id can be used to query the status of the bid. - #[schema(example = "beedbeed-58cc-4372-a567-0e02b2c3d479", value_type=String)] - pub id: BidId, -} - -/// Opportunity parameters needed for deleting live opportunities. -#[serde_as] -#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] -pub struct OpportunityDeleteV1Svm { - /// The permission account for the opportunity. - #[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)] - #[serde_as(as = "DisplayFromStr")] - pub permission_account: Pubkey, - /// The router account for the opportunity. - #[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)] - #[serde_as(as = "DisplayFromStr")] - pub router: Pubkey, - /// The chain id for the opportunity. - #[schema(example = "solana", value_type = String)] - pub chain_id: ChainId, - /// The program for the opportunity. - #[schema(example = "limo", value_type = ProgramSvm)] - pub program: ProgramSvm, -} - -/// Opportunity parameters needed for deleting live opportunities. -#[serde_as] -#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] -pub struct OpportunityDeleteV1Evm { - /// The permission key of the opportunity. - #[schema(example = "0xdeadbeefcafe", value_type = String)] - pub permission_key: Bytes, - /// The chain id for the opportunity. - #[schema(example = "solana", value_type = String)] - pub chain_id: ChainId, -} - -#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] -#[serde(tag = "version")] -pub enum OpportunityDeleteSvm { - #[serde(rename = "v1")] - #[schema(title = "v1")] - V1(OpportunityDeleteV1Svm), -} - -#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] -#[serde(tag = "version")] -pub enum OpportunityDeleteEvm { - #[serde(rename = "v1")] - #[schema(title = "v1")] - V1(OpportunityDeleteV1Evm), -} - -/// The input type for deleting opportunities. -#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] -#[serde(tag = "chain_type")] -pub enum OpportunityDelete { - #[serde(rename = "svm")] - #[schema(title = "svm")] - Svm(OpportunityDeleteSvm), - #[serde(rename = "evm")] - #[schema(title = "evm")] - Evm(OpportunityDeleteEvm), -} - -/// The input type for creating a new opportunity. -#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] -#[serde(untagged)] -pub enum OpportunityCreate { - #[schema(title = "evm")] - Evm(OpportunityCreateEvm), - #[schema(title = "svm")] - Svm(OpportunityCreateSvm), -} - -#[derive(Serialize, Deserialize, ToResponse, ToSchema, Clone)] -#[serde(untagged)] -#[allow(clippy::large_enum_variant)] -pub enum Opportunity { - Evm(OpportunityEvm), - Svm(OpportunitySvm), -} - -fn default_opportunity_mode() -> OpportunityMode { - OpportunityMode::Live -} -fn default_limit() -> usize { - 20 -} -#[derive(Clone, Serialize, Deserialize, IntoParams)] -pub struct GetOpportunitiesQueryParams { - #[param(example = "op_sepolia", value_type = Option < String >)] - pub chain_id: Option, - /// Get opportunities in live or historical mode. - #[param(default = "live")] - #[serde(default = "default_opportunity_mode")] - pub mode: OpportunityMode, - /// The permission key to filter the opportunities by. Used only in historical mode. - #[param(example = "0xdeadbeef", value_type = Option< String >)] - pub permission_key: Option, - /// The time to get the opportunities from. - #[param(example="2024-05-23T21:26:57.329954Z", value_type = Option)] - #[serde(default, with = "crate::serde::nullable_datetime")] - pub from_time: Option, - /// The maximum number of opportunities to return. Capped at 100; if more than 100 requested, at most 100 will be returned. - #[param(example = "20", value_type = usize, maximum = 100)] - #[serde(default = "default_limit")] - limit: usize, -} - -// ----- Evm types ----- -#[derive(Serialize, Deserialize, ToSchema, Clone)] -pub struct OpportunityBidEvm { - /// The opportunity permission key. - #[schema(example = "0xdeadbeefcafe", value_type=String)] - pub permission_key: PermissionKey, - /// The bid amount in wei. - #[schema(example = "1000000000000000000", value_type=String)] - #[serde(with = "crate::serde::u256")] - pub amount: U256, - /// The latest unix timestamp in seconds until which the bid is valid. - #[schema(example = "1000000000000000000", value_type=String)] - #[serde(with = "crate::serde::u256")] - pub deadline: U256, - /// The nonce of the bid permit signature. - #[schema(example = "123", value_type=String)] - #[serde(with = "crate::serde::u256")] - pub nonce: U256, - /// The executor address. - #[schema(example = "0x5FbDB2315678afecb367f032d93F642f64180aa2", value_type=String)] - pub executor: Address, - #[schema( - example = "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef12", - value_type=String - )] - #[serde(with = "crate::serde::signature")] - pub signature: Signature, -} - -#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug, ToResponse)] -pub struct TokenAmountEvm { - /// The token contract address. - #[schema(example = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", value_type = String)] - pub token: ethers::abi::Address, - /// The token amount. - #[schema(example = "1000", value_type = String)] - #[serde(with = "crate::serde::u256")] - pub amount: U256, -} - -/// Opportunity parameters needed for on-chain execution. -/// If a searcher signs the opportunity and have approved enough tokens to opportunity adapter, -/// by calling this target contract with the given target calldata and structures, they will -/// send the tokens specified in the `sell_tokens` field and receive the tokens specified in the `buy_tokens` field. -#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug, ToResponse)] -pub struct OpportunityCreateV1Evm { - /// The permission key required for successful execution of the opportunity. - #[schema(example = "0xdeadbeefcafe", value_type = String)] - pub permission_key: Bytes, - /// The chain id where the opportunity will be executed. - #[schema(example = "op_sepolia", value_type = String)] - pub chain_id: String, - /// The contract address to call for execution of the opportunity. - #[schema(example = "0xcA11bde05977b3631167028862bE2a173976CA11", value_type = String)] - pub target_contract: ethers::abi::Address, - /// Calldata for the target contract call. - #[schema(example = "0xdeadbeef", value_type = String)] - pub target_calldata: Bytes, - /// The value to send with the contract call. - #[schema(example = "1", value_type = String)] - #[serde(with = "crate::serde::u256")] - pub target_call_value: U256, - - pub sell_tokens: Vec, - pub buy_tokens: Vec, -} - -#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug, ToResponse)] -#[serde(tag = "version")] -pub enum OpportunityCreateEvm { - #[serde(rename = "v1")] - #[schema(title = "v1")] - V1(OpportunityCreateV1Evm), -} - - -#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug, ToResponse)] -pub struct OpportunityParamsV1Evm(pub OpportunityCreateV1Evm); - -#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug, ToResponse)] -#[serde(tag = "version")] -pub enum OpportunityParamsEvm { - #[serde(rename = "v1")] - #[schema(title = "v1")] - V1(OpportunityParamsV1Evm), -} - -#[derive(Serialize, Deserialize, ToSchema, Clone, ToResponse)] -pub struct OpportunityEvm { - /// The opportunity unique id. - #[schema(example = "obo3ee3e-58cc-4372-a567-0e02b2c3d479", value_type = String)] - pub opportunity_id: OpportunityId, - /// Creation time of the opportunity (in microseconds since the Unix epoch). - #[schema(example = 1_700_000_000_000_000i128, value_type = i128)] - pub creation_time: UnixTimestampMicros, - #[serde(flatten)] - #[schema(inline)] - pub params: OpportunityParamsEvm, -} - -// ----- Svm types ----- -#[serde_as] -#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug, ToResponse)] -pub struct TokenAmountSvm { - /// The token contract address. - #[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)] - #[serde_as(as = "DisplayFromStr")] - pub token: Pubkey, - /// The token amount in lamports. - #[schema(example = 1000)] - pub amount: u64, -} - -/// Parameters needed to create a new opportunity from the Phantom wallet. -/// Auction server will extract the output token price for the auction. -#[serde_as] -#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] -pub struct QuoteCreatePhantomV1Svm { - /// The user wallet address which requested the quote from the wallet. - #[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)] - #[serde_as(as = "DisplayFromStr")] - pub user_wallet_address: Pubkey, - /// The token mint address of the input token. - #[schema(example = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", value_type = String)] - #[serde_as(as = "DisplayFromStr")] - pub input_token_mint: Pubkey, - /// The token mint address of the output token. - #[schema(example = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", value_type = String)] - #[serde_as(as = "DisplayFromStr")] - pub output_token_mint: Pubkey, - /// The input token amount that the user wants to swap. - #[schema(example = 100)] - pub input_token_amount: u64, - /// The maximum slippage percentage that the user is willing to accept. - #[schema(example = 0.5)] - pub maximum_slippage_percentage: f64, - /// The chain id for creating the quote. - #[schema(example = "solana", value_type = String)] - pub chain_id: ChainId, -} - -#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] -#[serde(tag = "program")] -pub enum QuoteCreateV1Svm { - #[serde(rename = "phantom")] - #[schema(title = "phantom")] - Phantom(QuoteCreatePhantomV1Svm), -} - -#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] -#[serde(tag = "version")] -pub enum QuoteCreateSvm { - #[serde(rename = "v1")] - #[schema(title = "v1")] - V1(QuoteCreateV1Svm), -} - -#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] -#[serde(untagged)] -pub enum QuoteCreate { - #[schema(title = "svm")] - Svm(QuoteCreateSvm), -} - -#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] -pub struct QuoteV1Svm { - /// The signed transaction for the quote to be executed on chain which is valid until the expiration time. - #[schema(example = "SGVsbG8sIFdvcmxkIQ==", value_type = String)] - #[serde(with = "crate::serde::transaction_svm")] - pub transaction: VersionedTransaction, - /// The expiration time of the quote (in seconds since the Unix epoch). - #[schema(example = 1_700_000_000_000_000i64, value_type = i64)] - pub expiration_time: i64, - /// The input token amount that the user wants to swap. - pub input_token: TokenAmountSvm, - /// The output token amount that the user will receive. - pub output_token: TokenAmountSvm, - /// The maximum slippage percentage that the user is willing to accept. - #[schema(example = 0.5)] - pub maximum_slippage_percentage: f64, - /// The chain id for the quote. - #[schema(example = "solana", value_type = String)] - pub chain_id: ChainId, -} - -#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] -#[serde(tag = "version")] -pub enum QuoteSvm { - #[serde(rename = "v1")] - #[schema(title = "v1")] - V1(QuoteV1Svm), -} - -#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] -#[serde(untagged)] -pub enum Quote { - #[schema(title = "svm")] - Svm(QuoteSvm), -} - -/// Program specific parameters for the opportunity. -#[serde_as] -#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] -#[serde(tag = "program")] -pub enum OpportunityCreateProgramParamsV1Svm { - /// Limo program specific parameters for the opportunity. - /// It contains the Limo order to be executed, encoded in base64. - /// SDKs will decode this order and create transaction for bidding on the opportunity. - #[serde(rename = "limo")] - #[schema(title = "limo")] - Limo { - /// The Limo order to be executed, encoded in base64. - #[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)] - #[serde_as(as = "Base64")] - order: Vec, - - /// Address of the order account. - #[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)] - #[serde_as(as = "DisplayFromStr")] - order_address: Pubkey, - }, - /// Phantom program specific parameters for the opportunity. - #[serde(rename = "phantom")] - #[schema(title = "phantom")] - Phantom { - /// The user wallet address which requested the quote from the wallet. - #[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)] - #[serde_as(as = "DisplayFromStr")] - user_wallet_address: Pubkey, - - /// The maximum slippage percentage that the user is willing to accept. - #[schema(example = 0.5, value_type = f64)] - maximum_slippage_percentage: f64, - }, -} - -/// Opportunity parameters needed for on-chain execution. -/// Parameters may differ for each program. -#[serde_as] -#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] -pub struct OpportunityCreateV1Svm { - /// The permission account to be permitted by the ER contract for the opportunity execution of the protocol. - #[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)] - #[serde_as(as = "DisplayFromStr")] - pub permission_account: Pubkey, - /// The router account to be used for the opportunity execution of the protocol. - #[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)] - #[serde_as(as = "DisplayFromStr")] - pub router: Pubkey, - /// The chain id where the opportunity will be executed. - #[schema(example = "solana", value_type = String)] - pub chain_id: ChainId, - /// The slot where the program params were fetched from using the RPC. - #[schema(example = 293106477, value_type = u64)] - pub slot: Slot, - - pub sell_tokens: Vec, - pub buy_tokens: Vec, - - #[serde(flatten)] - #[schema(inline)] - pub program_params: OpportunityCreateProgramParamsV1Svm, -} - -#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] -#[serde(tag = "version")] -pub enum OpportunityCreateSvm { - #[serde(rename = "v1")] - #[schema(title = "v1")] - V1(OpportunityCreateV1Svm), -} - -#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)] -#[serde(rename_all = "lowercase")] -pub enum ProgramSvm { - Phantom, - Limo, -} - fn get_program(auth: &Auth) -> Result { match auth { Auth::Authorized(_, profile) => { @@ -494,148 +67,6 @@ fn get_program(auth: &Auth) -> Result { } } -impl OpportunityCreateSvm { - fn get_program(&self) -> ProgramSvm { - match self { - OpportunityCreateSvm::V1(params) => match ¶ms.program_params { - OpportunityCreateProgramParamsV1Svm::Limo { .. } => ProgramSvm::Limo, - OpportunityCreateProgramParamsV1Svm::Phantom { .. } => ProgramSvm::Phantom, - }, - } - } -} - -/// Program specific parameters for the opportunity. -#[serde_as] -#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug, ToResponse)] -#[serde(tag = "program")] -pub enum OpportunityParamsV1ProgramSvm { - /// Limo program specific parameters for the opportunity. - /// It contains the Limo order to be executed, encoded in base64. - /// SDKs will decode this order and create transaction for bidding on the opportunity. - #[serde(rename = "limo")] - #[schema(title = "limo")] - Limo { - /// The Limo order to be executed, encoded in base64. - #[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)] - #[serde_as(as = "Base64")] - order: Vec, - /// Address of the order account. - #[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)] - #[serde_as(as = "DisplayFromStr")] - order_address: Pubkey, - }, - /// Phantom program specific parameters for the opportunity. - #[serde(rename = "phantom")] - #[schema(title = "phantom")] - Phantom { - /// The user wallet address which requested the quote from the wallet. - #[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)] - #[serde_as(as = "DisplayFromStr")] - user_wallet_address: Pubkey, - - /// The maximum slippage percentage that the user is willing to accept. - #[schema(example = 0.5, value_type = f64)] - maximum_slippage_percentage: f64, - - /// The permission account to be permitted by the ER contract for the opportunity execution of the protocol. - #[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)] - #[serde_as(as = "DisplayFromStr")] - permission_account: Pubkey, - - /// The router account to be used for the opportunity execution of the protocol. - #[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)] - #[serde_as(as = "DisplayFromStr")] - router_account: Pubkey, - - /// The token searcher will send. - sell_token: TokenAmountSvm, - - /// The token searcher will receive. - buy_token: TokenAmountSvm, - }, -} - -/// Opportunity parameters needed for on-chain execution. -/// Parameters may differ for each program. -#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug, ToResponse)] -pub struct OpportunityParamsV1Svm { - #[serde(flatten)] - #[schema(inline)] - pub program: OpportunityParamsV1ProgramSvm, - #[schema(example = "solana", value_type = String)] - pub chain_id: ChainId, -} - -#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug, ToResponse)] -#[serde(tag = "version")] -pub enum OpportunityParamsSvm { - #[serde(rename = "v1")] - #[schema(title = "v1")] - V1(OpportunityParamsV1Svm), -} - -#[serde_as] -#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug, ToResponse)] -pub struct OpportunitySvm { - /// The opportunity unique id. - #[schema(example = "obo3ee3e-58cc-4372-a567-0e02b2c3d479", value_type = String)] - pub opportunity_id: OpportunityId, - /// Creation time of the opportunity (in microseconds since the Unix epoch). - #[schema(example = 1_700_000_000_000_000i128, value_type = i128)] - pub creation_time: UnixTimestampMicros, - /// The slot where the program params were fetched from using the RPC. - #[schema(example = 293106477, value_type = u64)] - pub slot: Slot, - - #[serde(flatten)] - #[schema(inline)] - pub params: OpportunityParamsSvm, -} - -// ----- Implementations ----- -impl OpportunityEvm { - pub fn get_chain_id(&self) -> &ChainId { - match &self.params { - OpportunityParamsEvm::V1(params) => ¶ms.0.chain_id, - } - } -} - -impl OpportunitySvm { - pub fn get_chain_id(&self) -> &ChainId { - match &self.params { - OpportunityParamsSvm::V1(params) => ¶ms.chain_id, - } - } -} - -impl Opportunity { - pub fn get_chain_id(&self) -> &ChainId { - match self { - Opportunity::Evm(opportunity) => opportunity.get_chain_id(), - Opportunity::Svm(opportunity) => opportunity.get_chain_id(), - } - } - - pub fn creation_time(&self) -> UnixTimestampMicros { - match self { - Opportunity::Evm(opportunity) => opportunity.creation_time, - Opportunity::Svm(opportunity) => opportunity.creation_time, - } - } -} - -impl OpportunityDelete { - pub fn get_chain_id(&self) -> &ChainId { - match self { - OpportunityDelete::Svm(OpportunityDeleteSvm::V1(params)) => ¶ms.chain_id, - OpportunityDelete::Evm(OpportunityDeleteEvm::V1(params)) => ¶ms.chain_id, - } - } -} -// ----- APIs ----- - /// Bid on opportunity. #[utoipa::path(post, path = "/v1/opportunities/{opportunity_id}/bids", request_body = OpportunityBidEvm, params(("opportunity_id" = String, description = "Opportunity id to bid on")), responses( @@ -832,10 +263,11 @@ pub async fn delete_opportunities( } pub fn get_routes(store: Arc) -> Router> { - Router::new() - .route("/", post(post_opportunity)) - .route("/quote", post(post_quote)) - .route("/", get(get_opportunities)) - .route("/:opportunity_id/bids", post(opportunity_bid)) - .route("/", login_required!(store, delete(delete_opportunities))) + WrappedRouter::new(store) + .route(Route::PostOpportunity, post_opportunity) + .route(Route::PostQuote, post_quote) + .route(Route::OpportunityBid, opportunity_bid) + .route(Route::GetOpportunities, get_opportunities) + .route(Route::DeleteOpportunities, delete_opportunities) + .router } diff --git a/auction-server/src/opportunity/entities/opportunity.rs b/auction-server/src/opportunity/entities/opportunity.rs index d236bce7..4285ec58 100644 --- a/auction-server/src/opportunity/entities/opportunity.rs +++ b/auction-server/src/opportunity/entities/opportunity.rs @@ -6,14 +6,10 @@ use { ChainId, PermissionKey, }, - opportunity::{ - api, - repository::{ - self, - }, - }, + opportunity::repository, }, ethers::types::Bytes, + express_relay_api_types::opportunity as api, std::{ fmt::Debug, ops::Deref, diff --git a/auction-server/src/opportunity/entities/opportunity_evm.rs b/auction-server/src/opportunity/entities/opportunity_evm.rs index 76d0a924..9422fb77 100644 --- a/auction-server/src/opportunity/entities/opportunity_evm.rs +++ b/auction-server/src/opportunity/entities/opportunity_evm.rs @@ -11,17 +11,13 @@ use { }, crate::{ kernel::entities::PermissionKey, - opportunity::{ - api, - repository::{ - self, - }, - }, + opportunity::repository, }, ethers::types::{ Bytes, U256, }, + express_relay_api_types::opportunity as api, std::ops::Deref, time::OffsetDateTime, }; diff --git a/auction-server/src/opportunity/entities/opportunity_svm.rs b/auction-server/src/opportunity/entities/opportunity_svm.rs index 8d850cc4..baf9ffdc 100644 --- a/auction-server/src/opportunity/entities/opportunity_svm.rs +++ b/auction-server/src/opportunity/entities/opportunity_svm.rs @@ -11,13 +11,9 @@ use { }, crate::{ kernel::entities::PermissionKey, - opportunity::{ - api, - repository::{ - self, - }, - }, + opportunity::repository, }, + express_relay_api_types::opportunity as api, solana_sdk::{ clock::Slot, pubkey::Pubkey, @@ -212,7 +208,6 @@ impl From for api::OpportunitySvm { } } - impl TryFrom> for OpportunitySvm { type Error = anyhow::Error; diff --git a/auction-server/src/opportunity/entities/quote.rs b/auction-server/src/opportunity/entities/quote.rs index 5c876388..7d4ffe11 100644 --- a/auction-server/src/opportunity/entities/quote.rs +++ b/auction-server/src/opportunity/entities/quote.rs @@ -1,9 +1,7 @@ use { super::token_amount_svm::TokenAmountSvm, - crate::{ - kernel::entities::ChainId, - opportunity::api, - }, + crate::kernel::entities::ChainId, + express_relay_api_types::opportunity as api, solana_sdk::{ pubkey::Pubkey, transaction::VersionedTransaction, diff --git a/auction-server/src/opportunity/entities/token_amount_evm.rs b/auction-server/src/opportunity/entities/token_amount_evm.rs index 88782d44..a651d8fe 100644 --- a/auction-server/src/opportunity/entities/token_amount_evm.rs +++ b/auction-server/src/opportunity/entities/token_amount_evm.rs @@ -1,10 +1,10 @@ use { super::token_amount::TokenAmount, - crate::opportunity::api, ethers::types::{ Address, U256, }, + express_relay_api_types::opportunity as api, serde::{ Deserialize, Serialize, @@ -18,7 +18,7 @@ impl TokenAmount for TokenAmountEvm { #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct TokenAmountEvm { pub token: Address, - #[serde(with = "crate::serde::u256")] + #[serde(with = "express_relay_api_types::serde::u256")] pub amount: U256, } diff --git a/auction-server/src/opportunity/entities/token_amount_svm.rs b/auction-server/src/opportunity/entities/token_amount_svm.rs index b58e0d90..31876c17 100644 --- a/auction-server/src/opportunity/entities/token_amount_svm.rs +++ b/auction-server/src/opportunity/entities/token_amount_svm.rs @@ -1,6 +1,6 @@ use { super::token_amount::TokenAmount, - crate::opportunity::api, + express_relay_api_types::opportunity as api, serde::{ Deserialize, Serialize, diff --git a/auction-server/src/opportunity/repository/models.rs b/auction-server/src/opportunity/repository/models.rs index 7ce3678b..aabcd116 100644 --- a/auction-server/src/opportunity/repository/models.rs +++ b/auction-server/src/opportunity/repository/models.rs @@ -41,7 +41,7 @@ pub enum OpportunityRemovalReason { #[derive(Clone, Debug, Serialize, Deserialize)] pub struct OpportunityMetadataEvm { pub target_contract: Address, - #[serde(with = "crate::serde::u256")] + #[serde(with = "express_relay_api_types::serde::u256")] pub target_call_value: U256, pub target_calldata: Bytes, } diff --git a/auction-server/src/opportunity/service/get_opportunities.rs b/auction-server/src/opportunity/service/get_opportunities.rs index e16278c9..4f3f050b 100644 --- a/auction-server/src/opportunity/service/get_opportunities.rs +++ b/auction-server/src/opportunity/service/get_opportunities.rs @@ -5,13 +5,11 @@ use { }, crate::{ api::RestError, - opportunity::{ - api::{ - GetOpportunitiesQueryParams, - OpportunityMode, - }, - repository::InMemoryStore, - }, + opportunity::repository::InMemoryStore, + }, + express_relay_api_types::opportunity::{ + GetOpportunitiesQueryParams, + OpportunityMode, }, }; diff --git a/auction-server/src/opportunity/service/handle_opportunity_bid.rs b/auction-server/src/opportunity/service/handle_opportunity_bid.rs index 1fb56dd2..63653176 100644 --- a/auction-server/src/opportunity/service/handle_opportunity_bid.rs +++ b/auction-server/src/opportunity/service/handle_opportunity_bid.rs @@ -23,15 +23,15 @@ use { }, entities::Evm, }, - opportunity::api::{ - OpportunityBidEvm, - OpportunityId, - }, }, ethers::{ contract::ContractRevert, types::Bytes, }, + express_relay_api_types::opportunity::{ + OpportunityBidEvm, + OpportunityId, + }, time::OffsetDateTime, uuid::Uuid, }; diff --git a/auction-server/src/opportunity/service/make_adapter_calldata.rs b/auction-server/src/opportunity/service/make_adapter_calldata.rs index 0f0a4374..fdcbbf10 100644 --- a/auction-server/src/opportunity/service/make_adapter_calldata.rs +++ b/auction-server/src/opportunity/service/make_adapter_calldata.rs @@ -7,12 +7,10 @@ use { crate::{ api::RestError, kernel::contracts::OpportunityAdapter, - opportunity::{ - api::OpportunityBidEvm, - entities, - }, + opportunity::entities, }, ethers::types::Bytes, + express_relay_api_types::opportunity::OpportunityBidEvm, std::sync::Arc, }; diff --git a/auction-server/src/opportunity/service/make_opportunity_execution_params.rs b/auction-server/src/opportunity/service/make_opportunity_execution_params.rs index 6b60b920..b3989995 100644 --- a/auction-server/src/opportunity/service/make_opportunity_execution_params.rs +++ b/auction-server/src/opportunity/service/make_opportunity_execution_params.rs @@ -12,11 +12,9 @@ use { PermitBatchTransferFrom, TokenAmount, }, - opportunity::{ - api::OpportunityBidEvm, - entities, - }, + opportunity::entities, }, + express_relay_api_types::opportunity::OpportunityBidEvm, }; pub struct MakeOpportunityExecutionParamsInput { diff --git a/auction-server/src/opportunity/service/make_permitted_tokens.rs b/auction-server/src/opportunity/service/make_permitted_tokens.rs index c62a1b04..e36fefba 100644 --- a/auction-server/src/opportunity/service/make_permitted_tokens.rs +++ b/auction-server/src/opportunity/service/make_permitted_tokens.rs @@ -6,12 +6,10 @@ use { crate::{ api::RestError, kernel::contracts::TokenPermissions, - opportunity::{ - api::OpportunityBidEvm, - entities, - }, + opportunity::entities, }, ethers::types::U256, + express_relay_api_types::opportunity::OpportunityBidEvm, }; pub struct MakePermittedTokensInput { diff --git a/auction-server/src/opportunity/service/verification.rs b/auction-server/src/opportunity/service/verification.rs index 459852e0..6f88e2ed 100644 --- a/auction-server/src/opportunity/service/verification.rs +++ b/auction-server/src/opportunity/service/verification.rs @@ -16,7 +16,6 @@ use { MulticallReturn, }, opportunity::{ - api::OpportunityBidEvm, entities, repository::InMemoryStore, token_spoof, @@ -42,6 +41,7 @@ use { }, utils::get_create2_address_from_hash, }, + express_relay_api_types::opportunity::OpportunityBidEvm, rand::Rng, std::{ collections::HashMap, diff --git a/auction-server/src/opportunity/token_spoof.rs b/auction-server/src/opportunity/token_spoof.rs index c4d3f871..10c5f0e5 100644 --- a/auction-server/src/opportunity/token_spoof.rs +++ b/auction-server/src/opportunity/token_spoof.rs @@ -16,7 +16,6 @@ use { }, anyhow::anyhow, ethers::{ - core::rand, prelude::{ spoof, Bytes, diff --git a/auction-server/src/server.rs b/auction-server/src/server.rs index 6499a20c..6fe2c9c0 100644 --- a/auction-server/src/server.rs +++ b/auction-server/src/server.rs @@ -60,7 +60,6 @@ use { }, std::{ collections::HashMap, - default::Default, sync::{ atomic::{ AtomicBool, @@ -139,7 +138,6 @@ pub fn setup_metrics_recorder() -> Result { .map_err(|err| anyhow!("Failed to set up metrics recorder: {:?}", err)) } - async fn setup_chain_store_evm(config_map: ConfigMap) -> Result> { join_all( config_map diff --git a/auction-server/src/state.rs b/auction-server/src/state.rs index 0512cbbd..1469e1d1 100644 --- a/auction-server/src/state.rs +++ b/auction-server/src/state.rs @@ -1,7 +1,6 @@ use { crate::{ api::{ - profile as ApiProfile, ws::WsState, RestError, }, @@ -35,7 +34,6 @@ use { solana_sdk::pubkey::Pubkey, std::{ collections::HashMap, - default::Default, sync::Arc, time::Duration, }, @@ -187,7 +185,7 @@ impl StoreNew { impl Store { pub async fn create_profile( &self, - create_profile: ApiProfile::CreateProfile, + create_profile: express_relay_api_types::profile::CreateProfile, ) -> Result { let id = Uuid::new_v4(); let role: models::ProfileRole = create_profile.role.clone().into(); diff --git a/contracts/svm/cli/src/main.rs b/contracts/svm/cli/src/main.rs index 035621b6..b0290ca1 100644 --- a/contracts/svm/cli/src/main.rs +++ b/contracts/svm/cli/src/main.rs @@ -33,7 +33,6 @@ use { std::str::FromStr, }; - /// CLI utility for interacting with Express Relay SVM program. #[derive(Parser, Debug)] #[command(version, about, long_about = None)] @@ -50,7 +49,6 @@ struct Args { command: Commands, } - #[derive(Debug, Parser)] struct Initialize { #[arg(long)] diff --git a/contracts/svm/programs/express_relay/src/sdk/test_helpers.rs b/contracts/svm/programs/express_relay/src/sdk/test_helpers.rs index ea344636..c168d400 100644 --- a/contracts/svm/programs/express_relay/src/sdk/test_helpers.rs +++ b/contracts/svm/programs/express_relay/src/sdk/test_helpers.rs @@ -87,7 +87,6 @@ pub fn add_express_relay_submit_bid_instruction( ixs.to_vec() } - pub fn create_submit_bid_instruction( searcher: Pubkey, relayer_signer: Pubkey, diff --git a/contracts/svm/testing/src/express_relay/helpers.rs b/contracts/svm/testing/src/express_relay/helpers.rs index 2382a1ad..62b4f0cb 100644 --- a/contracts/svm/testing/src/express_relay/helpers.rs +++ b/contracts/svm/testing/src/express_relay/helpers.rs @@ -25,17 +25,13 @@ pub fn get_express_relay_metadata(svm: litesvm::LiteSVM) -> ExpressRelayMetadata } pub fn get_config_router_key(router: Pubkey) -> Pubkey { - return Pubkey::find_program_address( - &[SEED_CONFIG_ROUTER, router.as_ref()], - &express_relay::id(), - ) - .0; + Pubkey::find_program_address(&[SEED_CONFIG_ROUTER, router.as_ref()], &express_relay::id()).0 } pub fn get_config_router(svm: litesvm::LiteSVM, router: Pubkey) -> Option { let config_router_key = get_config_router_key(router); - return svm.get_account(&config_router_key).map(|acc| { + svm.get_account(&config_router_key).map(|acc| { ConfigRouter::try_deserialize(&mut acc.data.as_ref()) .expect("Account is not of struct ConfigRouter") - }); + }) } diff --git a/contracts/svm/testing/src/express_relay/initialize.rs b/contracts/svm/testing/src/express_relay/initialize.rs index 65be5ad7..fff7c0da 100644 --- a/contracts/svm/testing/src/express_relay/initialize.rs +++ b/contracts/svm/testing/src/express_relay/initialize.rs @@ -27,7 +27,6 @@ pub fn initialize_instruction( ) -> Instruction { let express_relay_metadata = get_express_relay_metadata_key(); - Instruction { program_id: express_relay::id(), data: express_relay::instruction::Initialize { diff --git a/contracts/svm/testing/src/express_relay/set_admin.rs b/contracts/svm/testing/src/express_relay/set_admin.rs index d093198e..e389879f 100644 --- a/contracts/svm/testing/src/express_relay/set_admin.rs +++ b/contracts/svm/testing/src/express_relay/set_admin.rs @@ -16,7 +16,6 @@ use { pub fn set_admin_instruction(admin: &Keypair, admin_new: Pubkey) -> Instruction { let express_relay_metadata = get_express_relay_metadata_key(); - Instruction { program_id: express_relay::id(), data: express_relay::instruction::SetAdmin {}.data(), diff --git a/contracts/svm/testing/src/express_relay/set_relayer.rs b/contracts/svm/testing/src/express_relay/set_relayer.rs index cd776c42..b4539602 100644 --- a/contracts/svm/testing/src/express_relay/set_relayer.rs +++ b/contracts/svm/testing/src/express_relay/set_relayer.rs @@ -20,7 +20,6 @@ pub fn set_relayer_instruction( ) -> Instruction { let express_relay_metadata = get_express_relay_metadata_key(); - Instruction { program_id: express_relay::id(), data: express_relay::instruction::SetRelayer {}.data(), diff --git a/contracts/svm/testing/src/express_relay/set_splits.rs b/contracts/svm/testing/src/express_relay/set_splits.rs index 1d318aee..a666aefe 100644 --- a/contracts/svm/testing/src/express_relay/set_splits.rs +++ b/contracts/svm/testing/src/express_relay/set_splits.rs @@ -22,7 +22,6 @@ pub fn set_splits_instruction( ) -> Instruction { let express_relay_metadata = get_express_relay_metadata_key(); - Instruction { program_id: express_relay::id(), data: express_relay::instruction::SetSplits { diff --git a/contracts/svm/testing/src/express_relay/withdraw_fees.rs b/contracts/svm/testing/src/express_relay/withdraw_fees.rs index f5db8f72..3de259dd 100644 --- a/contracts/svm/testing/src/express_relay/withdraw_fees.rs +++ b/contracts/svm/testing/src/express_relay/withdraw_fees.rs @@ -16,7 +16,6 @@ use { pub fn withdraw_fees_instruction(admin: &Keypair, fee_receiver_admin: Pubkey) -> Instruction { let express_relay_metadata = get_express_relay_metadata_key(); - Instruction { program_id: express_relay::id(), data: express_relay::instruction::WithdrawFees {}.data(), diff --git a/gas-oracle/Cargo.toml b/gas-oracle/Cargo.toml index 06082bdb..a28bc783 100644 --- a/gas-oracle/Cargo.toml +++ b/gas-oracle/Cargo.toml @@ -7,4 +7,4 @@ edition = "2021" [dependencies] async-trait = "0.1.80" -ethers = "2.0.10" +ethers = { workspace = true } diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 00000000..0193dee3 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "1.83.0" diff --git a/sdk/rust/Cargo.toml b/sdk/rust/Cargo.toml new file mode 100644 index 00000000..d6c67561 --- /dev/null +++ b/sdk/rust/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "express-relay-client" +version = "0.2.0" +edition = "2021" +description = "Pyth Express Relay client" +repository = "https://github.com/pyth-network/per" +license = "Apache-2.0" + +[dependencies] +express-relay-api-types = { version = "0.1.0", path = "../../auction-server/api-types" } +reqwest = { version = "0.12.9", features = ["json"] } +url = "2.5.4" +serde = { workspace = true } +serde_json = { workspace = true } +tokio-tungstenite = { version = "0.24.0", features = ["native-tls"] } +tokio-stream = { workspace = true, features = ["sync"] } +tokio = { workspace = true, features = ["macros"] } +futures-util = "0.3.31" +ethers = { workspace = true } +solana-sdk = { workspace = true } diff --git a/sdk/rust/abi/ERC20.sol/ERC20.json b/sdk/rust/abi/ERC20.sol/ERC20.json new file mode 100644 index 00000000..4895fab1 --- /dev/null +++ b/sdk/rust/abi/ERC20.sol/ERC20.json @@ -0,0 +1 @@ +{"abi":[{"type":"function","name":"allowance","inputs":[{"name":"owner","type":"address","internalType":"address"},{"name":"spender","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"approve","inputs":[{"name":"spender","type":"address","internalType":"address"},{"name":"value","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"},{"type":"function","name":"balanceOf","inputs":[{"name":"account","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"decimals","inputs":[],"outputs":[{"name":"","type":"uint8","internalType":"uint8"}],"stateMutability":"view"},{"type":"function","name":"name","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"type":"function","name":"symbol","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"type":"function","name":"totalSupply","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"transfer","inputs":[{"name":"to","type":"address","internalType":"address"},{"name":"value","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"},{"type":"function","name":"transferFrom","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"value","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"},{"type":"event","name":"Approval","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"spender","type":"address","indexed":true,"internalType":"address"},{"name":"value","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"name":"from","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"value","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"error","name":"ERC20InsufficientAllowance","inputs":[{"name":"spender","type":"address","internalType":"address"},{"name":"allowance","type":"uint256","internalType":"uint256"},{"name":"needed","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"ERC20InsufficientBalance","inputs":[{"name":"sender","type":"address","internalType":"address"},{"name":"balance","type":"uint256","internalType":"uint256"},{"name":"needed","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"ERC20InvalidApprover","inputs":[{"name":"approver","type":"address","internalType":"address"}]},{"type":"error","name":"ERC20InvalidReceiver","inputs":[{"name":"receiver","type":"address","internalType":"address"}]},{"type":"error","name":"ERC20InvalidSender","inputs":[{"name":"sender","type":"address","internalType":"address"}]},{"type":"error","name":"ERC20InvalidSpender","inputs":[{"name":"spender","type":"address","internalType":"address"}]}],"bytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"deployedBytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"methodIdentifiers":{"allowance(address,address)":"dd62ed3e","approve(address,uint256)":"095ea7b3","balanceOf(address)":"70a08231","decimals()":"313ce567","name()":"06fdde03","symbol()":"95d89b41","totalSupply()":"18160ddd","transfer(address,uint256)":"a9059cbb","transferFrom(address,address,uint256)":"23b872dd"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.20+commit.a1b79de6\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"allowance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientAllowance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"approver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidApprover\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidReceiver\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSpender\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Implementation of the {IERC20} interface. This implementation is agnostic to the way tokens are created. This means that a supply mechanism has to be added in a derived contract using {_mint}. TIP: For a detailed writeup see our guide https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How to implement supply mechanisms]. The default value of {decimals} is 18. To change this, you should override this function so it returns a different value. We have followed general OpenZeppelin Contracts guidelines: functions revert instead returning `false` on failure. This behavior is nonetheless conventional and does not conflict with the expectations of ERC20 applications. Additionally, an {Approval} event is emitted on calls to {transferFrom}. This allows applications to reconstruct the allowance for all accounts just by listening to said events. Other implementations of the EIP may not emit these events, as it isn't required by the specification.\",\"errors\":{\"ERC20InsufficientAllowance(address,uint256,uint256)\":[{\"details\":\"Indicates a failure with the `spender`\\u2019s `allowance`. Used in transfers.\",\"params\":{\"allowance\":\"Amount of tokens a `spender` is allowed to operate with.\",\"needed\":\"Minimum amount required to perform a transfer.\",\"spender\":\"Address that may be allowed to operate on tokens without being their owner.\"}}],\"ERC20InsufficientBalance(address,uint256,uint256)\":[{\"details\":\"Indicates an error related to the current `balance` of a `sender`. Used in transfers.\",\"params\":{\"balance\":\"Current balance for the interacting account.\",\"needed\":\"Minimum amount required to perform a transfer.\",\"sender\":\"Address whose tokens are being transferred.\"}}],\"ERC20InvalidApprover(address)\":[{\"details\":\"Indicates a failure with the `approver` of a token to be approved. Used in approvals.\",\"params\":{\"approver\":\"Address initiating an approval operation.\"}}],\"ERC20InvalidReceiver(address)\":[{\"details\":\"Indicates a failure with the token `receiver`. Used in transfers.\",\"params\":{\"receiver\":\"Address to which tokens are being transferred.\"}}],\"ERC20InvalidSender(address)\":[{\"details\":\"Indicates a failure with the token `sender`. Used in transfers.\",\"params\":{\"sender\":\"Address whose tokens are being transferred.\"}}],\"ERC20InvalidSpender(address)\":[{\"details\":\"Indicates a failure with the `spender` to be approved. Used in approvals.\",\"params\":{\"spender\":\"Address that may be allowed to operate on tokens without being their owner.\"}}]},\"events\":{\"Approval(address,address,uint256)\":{\"details\":\"Emitted when the allowance of a `spender` for an `owner` is set by a call to {approve}. `value` is the new allowance.\"},\"Transfer(address,address,uint256)\":{\"details\":\"Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero.\"}},\"kind\":\"dev\",\"methods\":{\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. NOTE: If `value` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"constructor\":{\"details\":\"Sets the values for {name} and {symbol}. All two of these values are immutable: they can only be set once during construction.\"},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the default value returned by this function, unless it's overridden. NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"name()\":{\"details\":\"Returns the name of the token.\"},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `value`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `value`. - the caller must have allowance for ``from``'s tokens of at least `value`.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol\":\"ERC20\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@pythnetwork/express-relay-sdk-solidity/=node_modules/@pythnetwork/express-relay-sdk-solidity/\",\":@pythnetwork/pyth-sdk-solidity/=node_modules/@pythnetwork/pyth-sdk-solidity/\",\":ExcessivelySafeCall/=lib/ExcessivelySafeCall/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/\",\":forge-gas-snapshot/=lib/permit2/lib/forge-gas-snapshot/src/\",\":forge-std/=lib/forge-std/src/\",\":halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":openzeppelin/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":permit2/=lib/permit2/src/\",\":solmate/=lib/permit2/lib/solmate/src/\"],\"viaIR\":true},\"sources\":{\"lib/openzeppelin-contracts/contracts/interfaces/draft-IERC6093.sol\":{\"keccak256\":\"0x60c65f701957fdd6faea1acb0bb45825791d473693ed9ecb34726fdfaa849dd7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://ea290300e0efc4d901244949dc4d877fd46e6c5e43dc2b26620e8efab3ab803f\",\"dweb:/ipfs/QmcLLJppxKeJWqHxE2CUkcfhuRTgHSn8J4kijcLa5MYhSt\"]},\"lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol\":{\"keccak256\":\"0xc3e1fa9d1987f8d349dfb4d6fe93bf2ca014b52ba335cfac30bfe71e357e6f80\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c5703ccdeb7b1d685e375ed719117e9edf2ab4bc544f24f23b0d50ec82257229\",\"dweb:/ipfs/QmTdwkbQq7owpCiyuzE7eh5LrD2ddrBCZ5WHVsWPi1RrTS\"]},\"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0xc6a8ff0ea489379b61faa647490411b80102578440ab9d84e9a957cc12164e70\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://0ea104e577e63faea3b69c415637e99e755dcbf64c5833d7140c35a714d6d90c\",\"dweb:/ipfs/Qmau6x4Ns9XdyynRCNNp3RhLqijJjFm7z5fyZazfYFGYdq\"]},\"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"keccak256\":\"0xaa761817f6cd7892fcf158b3c776b34551cde36f48ff9703d53898bc45a94ea2\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://0ad7c8d4d08938c8dfc43d75a148863fb324b80cf53e0a36f7e5a4ac29008850\",\"dweb:/ipfs/QmcrhfPgVNf5mkdhQvy1pMv51TFokD3Y4Wa5WZhFqVh8UV\"]},\"lib/openzeppelin-contracts/contracts/utils/Context.sol\":{\"keccak256\":\"0x493033a8d1b176a037b2cc6a04dad01a5c157722049bbecf632ca876224dd4b2\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6a708e8a5bdb1011c2c381c9a5cfd8a9a956d7d0a9dc1bd8bcdaf52f76ef2f12\",\"dweb:/ipfs/Qmax9WHBnVsZP46ZxEMNRQpLQnrdE4dK8LehML1Py8FowF\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.20+commit.a1b79de6"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"type":"error","name":"ERC20InsufficientAllowance"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"type":"error","name":"ERC20InsufficientBalance"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"type":"error","name":"ERC20InvalidApprover"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"type":"error","name":"ERC20InvalidReceiver"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"type":"error","name":"ERC20InvalidSender"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"type":"error","name":"ERC20InvalidSpender"},{"inputs":[{"internalType":"address","name":"owner","type":"address","indexed":true},{"internalType":"address","name":"spender","type":"address","indexed":true},{"internalType":"uint256","name":"value","type":"uint256","indexed":false}],"type":"event","name":"Approval","anonymous":false},{"inputs":[{"internalType":"address","name":"from","type":"address","indexed":true},{"internalType":"address","name":"to","type":"address","indexed":true},{"internalType":"uint256","name":"value","type":"uint256","indexed":false}],"type":"event","name":"Transfer","anonymous":false},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"stateMutability":"view","type":"function","name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}]},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"stateMutability":"view","type":"function","name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"name","outputs":[{"internalType":"string","name":"","type":"string"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}]},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}]}],"devdoc":{"kind":"dev","methods":{"allowance(address,address)":{"details":"See {IERC20-allowance}."},"approve(address,uint256)":{"details":"See {IERC20-approve}. NOTE: If `value` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address."},"balanceOf(address)":{"details":"See {IERC20-balanceOf}."},"constructor":{"details":"Sets the values for {name} and {symbol}. All two of these values are immutable: they can only be set once during construction."},"decimals()":{"details":"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the default value returned by this function, unless it's overridden. NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}."},"name()":{"details":"Returns the name of the token."},"symbol()":{"details":"Returns the symbol of the token, usually a shorter version of the name."},"totalSupply()":{"details":"See {IERC20-totalSupply}."},"transfer(address,uint256)":{"details":"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `value`."},"transferFrom(address,address,uint256)":{"details":"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `value`. - the caller must have allowance for ``from``'s tokens of at least `value`."}},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":["@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/","@pythnetwork/express-relay-sdk-solidity/=node_modules/@pythnetwork/express-relay-sdk-solidity/","@pythnetwork/pyth-sdk-solidity/=node_modules/@pythnetwork/pyth-sdk-solidity/","ExcessivelySafeCall/=lib/ExcessivelySafeCall/src/","ds-test/=lib/forge-std/lib/ds-test/src/","erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/","forge-gas-snapshot/=lib/permit2/lib/forge-gas-snapshot/src/","forge-std/=lib/forge-std/src/","halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/","openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/","openzeppelin-contracts/=lib/openzeppelin-contracts/","openzeppelin/=lib/openzeppelin-contracts-upgradeable/contracts/","permit2/=lib/permit2/src/","solmate/=lib/permit2/lib/solmate/src/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol":"ERC20"},"evmVersion":"shanghai","libraries":{},"viaIR":true},"sources":{"lib/openzeppelin-contracts/contracts/interfaces/draft-IERC6093.sol":{"keccak256":"0x60c65f701957fdd6faea1acb0bb45825791d473693ed9ecb34726fdfaa849dd7","urls":["bzz-raw://ea290300e0efc4d901244949dc4d877fd46e6c5e43dc2b26620e8efab3ab803f","dweb:/ipfs/QmcLLJppxKeJWqHxE2CUkcfhuRTgHSn8J4kijcLa5MYhSt"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol":{"keccak256":"0xc3e1fa9d1987f8d349dfb4d6fe93bf2ca014b52ba335cfac30bfe71e357e6f80","urls":["bzz-raw://c5703ccdeb7b1d685e375ed719117e9edf2ab4bc544f24f23b0d50ec82257229","dweb:/ipfs/QmTdwkbQq7owpCiyuzE7eh5LrD2ddrBCZ5WHVsWPi1RrTS"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol":{"keccak256":"0xc6a8ff0ea489379b61faa647490411b80102578440ab9d84e9a957cc12164e70","urls":["bzz-raw://0ea104e577e63faea3b69c415637e99e755dcbf64c5833d7140c35a714d6d90c","dweb:/ipfs/Qmau6x4Ns9XdyynRCNNp3RhLqijJjFm7z5fyZazfYFGYdq"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"keccak256":"0xaa761817f6cd7892fcf158b3c776b34551cde36f48ff9703d53898bc45a94ea2","urls":["bzz-raw://0ad7c8d4d08938c8dfc43d75a148863fb324b80cf53e0a36f7e5a4ac29008850","dweb:/ipfs/QmcrhfPgVNf5mkdhQvy1pMv51TFokD3Y4Wa5WZhFqVh8UV"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/Context.sol":{"keccak256":"0x493033a8d1b176a037b2cc6a04dad01a5c157722049bbecf632ca876224dd4b2","urls":["bzz-raw://6a708e8a5bdb1011c2c381c9a5cfd8a9a956d7d0a9dc1bd8bcdaf52f76ef2f12","dweb:/ipfs/Qmax9WHBnVsZP46ZxEMNRQpLQnrdE4dK8LehML1Py8FowF"],"license":"MIT"}},"version":1},"id":48} \ No newline at end of file diff --git a/sdk/rust/abi/ExpressRelay.sol/ExpressRelay.json b/sdk/rust/abi/ExpressRelay.sol/ExpressRelay.json new file mode 100644 index 00000000..55d999bd --- /dev/null +++ b/sdk/rust/abi/ExpressRelay.sol/ExpressRelay.json @@ -0,0 +1 @@ +{"abi":[{"type":"receive","stateMutability":"payable"},{"type":"function","name":"addRelayerSubwallet","inputs":[{"name":"subwallet","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"callWithBid","inputs":[{"name":"multicallData","type":"tuple","internalType":"struct MulticallData","components":[{"name":"bidId","type":"bytes16","internalType":"bytes16"},{"name":"targetContract","type":"address","internalType":"address"},{"name":"targetCalldata","type":"bytes","internalType":"bytes"},{"name":"bidAmount","type":"uint256","internalType":"uint256"},{"name":"gasLimit","type":"uint256","internalType":"uint256"},{"name":"revertOnFailure","type":"bool","internalType":"bool"}]}],"outputs":[{"name":"","type":"bool","internalType":"bool"},{"name":"","type":"bytes","internalType":"bytes"}],"stateMutability":"payable"},{"type":"function","name":"getAdmin","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"getFeeProtocol","inputs":[{"name":"feeRecipient","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getFeeProtocolDefault","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getFeeRelayer","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getFeeSplitPrecision","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getRelayer","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"getRelayerSubwallets","inputs":[],"outputs":[{"name":"","type":"address[]","internalType":"address[]"}],"stateMutability":"view"},{"type":"function","name":"isPermissioned","inputs":[{"name":"protocolFeeReceiver","type":"address","internalType":"address"},{"name":"permissionId","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"permissioned","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"multicall","inputs":[{"name":"permissionKey","type":"bytes","internalType":"bytes"},{"name":"multicallData","type":"tuple[]","internalType":"struct MulticallData[]","components":[{"name":"bidId","type":"bytes16","internalType":"bytes16"},{"name":"targetContract","type":"address","internalType":"address"},{"name":"targetCalldata","type":"bytes","internalType":"bytes"},{"name":"bidAmount","type":"uint256","internalType":"uint256"},{"name":"gasLimit","type":"uint256","internalType":"uint256"},{"name":"revertOnFailure","type":"bool","internalType":"bool"}]}],"outputs":[{"name":"multicallStatuses","type":"tuple[]","internalType":"struct MulticallStatus[]","components":[{"name":"externalSuccess","type":"bool","internalType":"bool"},{"name":"externalResult","type":"bytes","internalType":"bytes"},{"name":"multicallRevertReason","type":"string","internalType":"string"}]}],"stateMutability":"payable"},{"type":"function","name":"removeRelayerSubwallet","inputs":[{"name":"subwallet","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setFeeProtocol","inputs":[{"name":"feeRecipient","type":"address","internalType":"address"},{"name":"feeSplit","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setFeeProtocolDefault","inputs":[{"name":"feeSplit","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setFeeRelayer","inputs":[{"name":"feeSplit","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setRelayer","inputs":[{"name":"relayer","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"event","name":"FeeProtocolDefaultSet","inputs":[{"name":"feeSplit","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"FeeProtocolSet","inputs":[{"name":"feeRecipient","type":"address","indexed":true,"internalType":"address"},{"name":"feeSplit","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"FeeRelayerSet","inputs":[{"name":"feeSplit","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"MulticallIssued","inputs":[{"name":"permissionKey","type":"bytes","indexed":true,"internalType":"bytes"},{"name":"multicallIndex","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"bidId","type":"bytes16","indexed":true,"internalType":"bytes16"},{"name":"bidAmount","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"multicallStatus","type":"tuple","indexed":false,"internalType":"struct MulticallStatus","components":[{"name":"externalSuccess","type":"bool","internalType":"bool"},{"name":"externalResult","type":"bytes","internalType":"bytes"},{"name":"multicallRevertReason","type":"string","internalType":"string"}]}],"anonymous":false},{"type":"event","name":"ReceivedETH","inputs":[{"name":"sender","type":"address","indexed":true,"internalType":"address"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"RelayerSet","inputs":[{"name":"relayer","type":"address","indexed":false,"internalType":"address"}],"anonymous":false},{"type":"event","name":"RelayerSubwalletAdded","inputs":[{"name":"relayer","type":"address","indexed":true,"internalType":"address"},{"name":"subwallet","type":"address","indexed":false,"internalType":"address"}],"anonymous":false},{"type":"event","name":"RelayerSubwalletRemoved","inputs":[{"name":"relayer","type":"address","indexed":true,"internalType":"address"},{"name":"subwallet","type":"address","indexed":false,"internalType":"address"}],"anonymous":false},{"type":"error","name":"DuplicateRelayerSubwallet","inputs":[]},{"type":"error","name":"ExternalCallFailed","inputs":[{"name":"status","type":"tuple","internalType":"struct MulticallStatus","components":[{"name":"externalSuccess","type":"bool","internalType":"bool"},{"name":"externalResult","type":"bytes","internalType":"bytes"},{"name":"multicallRevertReason","type":"string","internalType":"string"}]}]},{"type":"error","name":"InvalidFeeSplit","inputs":[]},{"type":"error","name":"InvalidPermission","inputs":[]},{"type":"error","name":"InvalidTargetContract","inputs":[]},{"type":"error","name":"ReentrancyGuardReentrantCall","inputs":[]},{"type":"error","name":"RelayerSubwalletNotFound","inputs":[]},{"type":"error","name":"Unauthorized","inputs":[]}],"bytecode":{"object":"0x6080806040523461001b57600160085561173e90816100208239f35b5f80fdfe60806040526004361015610022575b3615610018575f80fd5b6100206115af565b005b5f3560e01c80631953ea7414610121578063403e96f61461011c5780634767ea4d1461011757806353383af1146101125780636548e9bc1461010d5780636caad4ec146101085780636e9960c314610103578063717a06f8146100fe5780638e7f00c8146100f9578063929628c2146100f45780639aacc67a146100ef578063b0e6fa47146100ea578063bdc50373146100e5578063be064301146100e0578063e6055ea6146100db5763fd6275bf0361000e576109e6565b6109b0565b610950565b610928565b61090b565b610890565b610736565b610680565b61059a565b610573565b6103ca565b6102f4565b6102d7565b61025c565b6101b7565b61013b565b6001600160a01b0381160361013757565b5f80fd5b346101375760203660031901126101375760043561015881610126565b6001600160a01b03165f908152600260205260409020548015610181575b602090604051908152f35b50600454610176565b9181601f84011215610137578235916001600160401b038311610137576020838186019501011161013757565b346101375760408060031936011261013757600435906101d682610126565b602435916001600160401b038311610137576102336101fc61025894369060040161018a565b6102258593929351938492602084019660018060a01b03168752878085015260608401916111db565b03601f198101835282611024565b5190205f52600360205260ff815f205416905191829182919091602081019215159052565b0390f35b34610137576020366003190112610137575f54600435906001600160a01b031633036102bc576020816102af7fb8a2163434e0d28db18a4672fd3c1c32af5fab38b11dc2354a3c5db51f83d925936116cc565b80600555604051908152a1005b6040516282b42960e81b8152600490fd5b5f91031261013757565b34610137575f366003190112610137576020600654604051908152f35b346101375760203660031901126101375760043561031181610126565b5f80549091906001600160a01b0390811633036102bc5760019082166bffffffffffffffffffffffff60a01b8254161781558260405161035081611009565b52600754836007558061039c575b60075f526040516001600160a01b038416815284907fb7041340e0c2a075059bf0488a71c767724be15dae8e737f8460007325e8d85790602090a180f35b600784525f805160206116e9833981519152908101905b8181106103c0575061035e565b84815582016103b3565b346101375760203660031901126101375760048035906103e982610126565b600180549091906001600160a01b03908116330361056457838116905f845b610471575b845486907f8e33eb399e9ba88b83b800f75bd766a52765bb94d513a72d77f33b7378a4dbde9061046c90610451906001600160a01b03165b6001600160a01b031690565b6040516001600160a01b039094168452929081906020820190565b0390a2005b600780548083101561055d5784846104a061048b86610ae8565b905460039190911b1c6001600160a01b031690565b16146104dc57506104b19054611479565b81146104cb57906104c3859392610ac1565b909192610408565b60405163ac4d92b360e01b81528490fd5b61046c95506104519450610445935061054f91509161053061052a61048b6105257f8e33eb399e9ba88b83b800f75bd766a52765bb94d513a72d77f33b7378a4dbde9a96611479565b610ae8565b91610ae8565b90919082549060031b9160018060a01b03809116831b921b1916179055565b610557611661565b9361040d565b505061040d565b506040516282b42960e81b8152fd5b34610137575f366003190112610137575f546040516001600160a01b039091168152602090f35b3461013757602036600319011261013757600480356105b881610126565b6001546001600160a01b03929083163303610672575f9283600791825492818616925b84811061062e5787876105ed8161160c565b6001547f8cc46934db1c70bf04828455a92a56b18a4b32e2c36b989d22842dee5a02ae889061062890610451906001600160a01b0316610445565b0390a280f35b8188525f805160206116e983398151915281015483166001600160a01b031684146106615761065c90610ac1565b6105db565b60405163b40d37c360e01b81528690fd5b6040516282b42960e81b8152fd5b34610137575f806003193601126107335760405180916007549081835260208093018092600783525f805160206116e983398151915290835b81811061071657505050846106cf910385611024565b60405193838594850191818652518092526040850193925b8281106106f657505050500390f35b83516001600160a01b0316855286955093810193928101926001016106e7565b82546001600160a01b0316845292860192600192830192016106b9565b80fd5b346101375760403660031901126101375760043561075381610126565b5f54602435916001600160a01b0391821633036102bc577f52ad746c8f4c13941233e6b7b2755019a39a992aa3dc7d2bb939c4020b1f573c91602091610798856116cc565b1692835f52600282528060405f2055604051908152a2005b5f5b8381106107c15750505f910152565b81810151838201526020016107b2565b906020916107ea815180928185528580860191016107b0565b601f01601f1916010190565b61082c91815115158152604061081b60208401516060602085015260608401906107d1565b9201519060408184039101526107d1565b90565b602080820190808352835180925260408301928160408460051b8301019501935f915b8483106108625750505050505090565b9091929394958480610880600193603f198682030187528a516107f6565b9801930193019194939290610852565b6040366003190112610137576001600160401b03600435818111610137576108bc90369060040161018a565b91602435918183116101375736602384011215610137578260040135918211610137573660248360051b85010111610137576102589360246108ff940191610b0f565b6040519182918261082f565b34610137575f366003190112610137576020600454604051908152f35b34610137575f366003190112610137576001546040516001600160a01b039091168152602090f35b34610137576020366003190112610137575f54600435906001600160a01b031633036102bc576020816109a37f0a3ed97e63337c869ee1c03d88650119096af2cbc89be5021154b622ed597670936116cc565b80600455604051908152a1005b34610137575f366003190112610137576020600554604051908152f35b60409061082c93921515815281602082015201906107d1565b60031960203682011261013757600435906001600160401b0382116101375760c0908236030112610137573033036102bc576024810130610a29610445836114e0565b14610a9b57610a61610a3b47926114e0565b610a55610a4e60448601866004016114ea565b3691611060565b90608485013590611556565b92819291610a7b575b5050610258604051928392836109cd565b6064610a8a610a949347611487565b910135111561151c565b5f80610a6a565b604051632ab4c28d60e11b8152600490fd5b634e487b7160e01b5f52601160045260245ffd5b5f198114610acf5760010190565b610aad565b634e487b7160e01b5f52603260045260245ffd5b600754811015610b0a5760075f525f805160206116e983398151915201905f90565b610ad4565b6001805490936001600160a01b0392909183163303610f85575b600260085414610f7357600260085560148410610f6157610b4b368583611060565b93610b75610b6886516020809801205f52600360205260405f2090565b805460ff19166001179055565b610b7e876110ad565b965f93845b828110610d3b57505050610ba0610b9b368385611060565b6115dd565b6001600160a01b0381165f908152600260205260409020909490548015610d32575b610bcf610bd891866113bc565b600654906113cf565b9485610c6c575b505091610c1d610c13610c2b96610bff610bcf9795610c22973691611060565b9081519101205f52600360205260405f2090565b805460ff19169055565b611487565b600554906113bc565b80610c3d575b505061082c6001600855565b5f80808093610c55610c65965460018060a01b031690565b5af1610c5f6113ed565b50611494565b5f80610c31565b9194929391803b63ffffffff1615610cfd571693843b15610137575f604051809663fced708160e01b8252818681610ca8878b60048401611468565b03925af1948515610cf857610c2b96610bff610c2296610c1d94610c1394610bcf9a610cdf575b505b959750959750509650610bdf565b80610cec610cf292610ff1565b806102cd565b5f610ccf565b6112b8565b610c1d9150610c2b96610bff610c2296610bcf98610d2d5f8080808c610c139a5af1610d276113ed565b5061141c565b610cd1565b50600454610bc2565b610d46818484611125565b6040908b8a835163fd6275bf60e01b8152855f8280610d69600498898301611208565b038183305af193845f938496610f38575b50610f055750505050508a610d8d6112d7565b6308c379a014610ed6575b610cf857610db7610db3610dac858f6112c3565b5151151590565b1590565b80610eba575b610e9257508a90610dd1610dac84846112c3565b610e5f575b908280927fd56fb0d5bb780b877d5c011d6bc88787167fd6429fc93e9acc40b20dd8e430368987610e52610e3c8c610e358860608f82610e5a9f91610e27610e22610e2d94838d611125565b611387565b99611125565b01359a6112c3565b5194611391565b94519283926001600160801b03191697836113a5565b0390a4610ac1565b610b83565b90828092818987828a9d610e758d9a8d85611125565b60600135610e829161137a565b9d50505050509192509250610dd6565b610eb6610e9f848e6112c3565b5192516372af8c3360e01b81529283928301611369565b0390fd5b50610ed160a0610ecb858888611125565b0161135f565b610dbd565b8c610edf6112f2565b80610eec575b5050610d98565b90915083610efb865f946112c3565b5101528c5f610ee5565b610db794610db394610f26610dac95610f1e86866112c3565b519015159052565b610f3084846112c3565b5101526112c3565b909550610f5791933d8091833e610f4f8183611024565b810190611151565b929092945f610d7a565b604051634345326f60e11b8152600490fd5b604051633ee5aeb560e01b8152600490fd5b5f80600754905b818110610fab575b5050610b29576040516282b42960e81b8152600490fd5b85610fb582610ae8565b919054339260031b1c1614610fd257610fcd90610ac1565b610f8c565b505050845f80610f94565b634e487b7160e01b5f52604160045260245ffd5b6001600160401b03811161100457604052565b610fdd565b602081019081106001600160401b0382111761100457604052565b90601f801991011681019081106001600160401b0382111761100457604052565b6001600160401b03811161100457601f01601f191660200190565b92919261106c82611045565b9161107a6040519384611024565b829481845281830111610137578281602093845f960137010152565b6001600160401b0381116110045760051b60200190565b906110b782611096565b6040906110c682519182611024565b83815280936110d7601f1991611096565b01905f92835b8381106110eb575050505050565b815190606091828101928184106001600160401b0385111761100457602093855287825283908082840152858301528286010152016110dd565b9190811015610b0a5760051b8101359060be1981360301821215610137570190565b8015150361013757565b919060408382031261013757825161116881611147565b926020810151906001600160401b038211610137570181601f8201121561013757805161119481611045565b926111a26040519485611024565b818452602082840101116101375761082c91602080850191016107b0565b6fffffffffffffffffffffffffffffffff1981160361013757565b908060209392818452848401375f828201840152601f01601f1916010190565b359061120682611147565b565b602081528135611217816111c0565b6001600160801b0319166020820152602082013561123481610126565b6001600160a01b031660408281019190915282013536839003601e1901811215610137578201906020823592016001600160401b038311610137578236038113610137576112b160a061129760c09361082c9685606088015260e08701916111db565b9560608101356080860152608081013582860152016111fb565b1515910152565b6040513d5f823e3d90fd5b8051821015610b0a5760209160051b010190565b5f9060033d116112e357565b905060045f803e5f5160e01c90565b5f60443d1061082c57604051600319913d83016004833e81516001600160401b03918282113d60248401111761134e57818401948551938411611356573d8501016020848701011161134e575061082c92910160200190611024565b949350505050565b50949350505050565b3561082c81611147565b90602061082c9281815201906107f6565b91908201809211610acf57565b3561082c816111c0565b81604051928392833781015f815203902090565b60409061082c9392815281602082015201906107f6565b81810292918115918404141715610acf57565b81156113d9570490565b634e487b7160e01b5f52601260045260245ffd5b3d15611417573d906113fe82611045565b9161140c6040519384611024565b82523d5f602084013e565b606090565b1561142357565b60405162461bcd60e51b815260206004820152601f60248201527f466565207472616e7366657220746f2070726f746f636f6c206661696c6564006044820152606490fd5b91602061082c9381815201916111db565b5f19810191908211610acf57565b91908203918211610acf57565b1561149b57565b60405162461bcd60e51b815260206004820152601e60248201527f466565207472616e7366657220746f2072656c61796572206661696c656400006044820152606490fd5b3561082c81610126565b903590601e198136030182121561013757018035906001600160401b0382116101375760200191813603831361013757565b1561152357565b60405162461bcd60e51b815260206004820152600b60248201526a1a5b9d985b1a5908189a5960aa1b6044820152606490fd5b909291925f6040519460408601908682106001600160401b03831117611004578291604052602093848852828589019686368937868451940192f1913d918083116115a7575b505f908286523e9190565b91505f61159c565b6040513481527f4103257eaac983ca79a70d28f90dfc4fa16b619bb0c17ee7cab0d4034c27962460203392a2565b6020815191015190602081106115fb575b506001600160a01b031690565b5f199060200360031b1b165f6115ee565b60075468010000000000000000811015611004576001810180600755811015610b0a5760075f525f805160206116e98339815191520180546001600160a01b0319166001600160a01b03909216919091179055565b60075480156116b8575f1981019080821015610b0a577fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6879060075f52016bffffffffffffffffffffffff60a01b8154169055600755565b634e487b7160e01b5f52603160045260245ffd5b600654106116d657565b604051630601f69760e01b8152600490fdfea66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688a2646970667358221220bb69fd194b3c6e8f231165252ba1d4d347f7401303e88ea2f7b1d256248d015c64736f6c63430008140033","sourceMap":"463:5731:78:-:0;;;;;;;1713:1:56;1917:21;1713:1;463:5731:78;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x60806040526004361015610022575b3615610018575f80fd5b6100206115af565b005b5f3560e01c80631953ea7414610121578063403e96f61461011c5780634767ea4d1461011757806353383af1146101125780636548e9bc1461010d5780636caad4ec146101085780636e9960c314610103578063717a06f8146100fe5780638e7f00c8146100f9578063929628c2146100f45780639aacc67a146100ef578063b0e6fa47146100ea578063bdc50373146100e5578063be064301146100e0578063e6055ea6146100db5763fd6275bf0361000e576109e6565b6109b0565b610950565b610928565b61090b565b610890565b610736565b610680565b61059a565b610573565b6103ca565b6102f4565b6102d7565b61025c565b6101b7565b61013b565b6001600160a01b0381160361013757565b5f80fd5b346101375760203660031901126101375760043561015881610126565b6001600160a01b03165f908152600260205260409020548015610181575b602090604051908152f35b50600454610176565b9181601f84011215610137578235916001600160401b038311610137576020838186019501011161013757565b346101375760408060031936011261013757600435906101d682610126565b602435916001600160401b038311610137576102336101fc61025894369060040161018a565b6102258593929351938492602084019660018060a01b03168752878085015260608401916111db565b03601f198101835282611024565b5190205f52600360205260ff815f205416905191829182919091602081019215159052565b0390f35b34610137576020366003190112610137575f54600435906001600160a01b031633036102bc576020816102af7fb8a2163434e0d28db18a4672fd3c1c32af5fab38b11dc2354a3c5db51f83d925936116cc565b80600555604051908152a1005b6040516282b42960e81b8152600490fd5b5f91031261013757565b34610137575f366003190112610137576020600654604051908152f35b346101375760203660031901126101375760043561031181610126565b5f80549091906001600160a01b0390811633036102bc5760019082166bffffffffffffffffffffffff60a01b8254161781558260405161035081611009565b52600754836007558061039c575b60075f526040516001600160a01b038416815284907fb7041340e0c2a075059bf0488a71c767724be15dae8e737f8460007325e8d85790602090a180f35b600784525f805160206116e9833981519152908101905b8181106103c0575061035e565b84815582016103b3565b346101375760203660031901126101375760048035906103e982610126565b600180549091906001600160a01b03908116330361056457838116905f845b610471575b845486907f8e33eb399e9ba88b83b800f75bd766a52765bb94d513a72d77f33b7378a4dbde9061046c90610451906001600160a01b03165b6001600160a01b031690565b6040516001600160a01b039094168452929081906020820190565b0390a2005b600780548083101561055d5784846104a061048b86610ae8565b905460039190911b1c6001600160a01b031690565b16146104dc57506104b19054611479565b81146104cb57906104c3859392610ac1565b909192610408565b60405163ac4d92b360e01b81528490fd5b61046c95506104519450610445935061054f91509161053061052a61048b6105257f8e33eb399e9ba88b83b800f75bd766a52765bb94d513a72d77f33b7378a4dbde9a96611479565b610ae8565b91610ae8565b90919082549060031b9160018060a01b03809116831b921b1916179055565b610557611661565b9361040d565b505061040d565b506040516282b42960e81b8152fd5b34610137575f366003190112610137575f546040516001600160a01b039091168152602090f35b3461013757602036600319011261013757600480356105b881610126565b6001546001600160a01b03929083163303610672575f9283600791825492818616925b84811061062e5787876105ed8161160c565b6001547f8cc46934db1c70bf04828455a92a56b18a4b32e2c36b989d22842dee5a02ae889061062890610451906001600160a01b0316610445565b0390a280f35b8188525f805160206116e983398151915281015483166001600160a01b031684146106615761065c90610ac1565b6105db565b60405163b40d37c360e01b81528690fd5b6040516282b42960e81b8152fd5b34610137575f806003193601126107335760405180916007549081835260208093018092600783525f805160206116e983398151915290835b81811061071657505050846106cf910385611024565b60405193838594850191818652518092526040850193925b8281106106f657505050500390f35b83516001600160a01b0316855286955093810193928101926001016106e7565b82546001600160a01b0316845292860192600192830192016106b9565b80fd5b346101375760403660031901126101375760043561075381610126565b5f54602435916001600160a01b0391821633036102bc577f52ad746c8f4c13941233e6b7b2755019a39a992aa3dc7d2bb939c4020b1f573c91602091610798856116cc565b1692835f52600282528060405f2055604051908152a2005b5f5b8381106107c15750505f910152565b81810151838201526020016107b2565b906020916107ea815180928185528580860191016107b0565b601f01601f1916010190565b61082c91815115158152604061081b60208401516060602085015260608401906107d1565b9201519060408184039101526107d1565b90565b602080820190808352835180925260408301928160408460051b8301019501935f915b8483106108625750505050505090565b9091929394958480610880600193603f198682030187528a516107f6565b9801930193019194939290610852565b6040366003190112610137576001600160401b03600435818111610137576108bc90369060040161018a565b91602435918183116101375736602384011215610137578260040135918211610137573660248360051b85010111610137576102589360246108ff940191610b0f565b6040519182918261082f565b34610137575f366003190112610137576020600454604051908152f35b34610137575f366003190112610137576001546040516001600160a01b039091168152602090f35b34610137576020366003190112610137575f54600435906001600160a01b031633036102bc576020816109a37f0a3ed97e63337c869ee1c03d88650119096af2cbc89be5021154b622ed597670936116cc565b80600455604051908152a1005b34610137575f366003190112610137576020600554604051908152f35b60409061082c93921515815281602082015201906107d1565b60031960203682011261013757600435906001600160401b0382116101375760c0908236030112610137573033036102bc576024810130610a29610445836114e0565b14610a9b57610a61610a3b47926114e0565b610a55610a4e60448601866004016114ea565b3691611060565b90608485013590611556565b92819291610a7b575b5050610258604051928392836109cd565b6064610a8a610a949347611487565b910135111561151c565b5f80610a6a565b604051632ab4c28d60e11b8152600490fd5b634e487b7160e01b5f52601160045260245ffd5b5f198114610acf5760010190565b610aad565b634e487b7160e01b5f52603260045260245ffd5b600754811015610b0a5760075f525f805160206116e983398151915201905f90565b610ad4565b6001805490936001600160a01b0392909183163303610f85575b600260085414610f7357600260085560148410610f6157610b4b368583611060565b93610b75610b6886516020809801205f52600360205260405f2090565b805460ff19166001179055565b610b7e876110ad565b965f93845b828110610d3b57505050610ba0610b9b368385611060565b6115dd565b6001600160a01b0381165f908152600260205260409020909490548015610d32575b610bcf610bd891866113bc565b600654906113cf565b9485610c6c575b505091610c1d610c13610c2b96610bff610bcf9795610c22973691611060565b9081519101205f52600360205260405f2090565b805460ff19169055565b611487565b600554906113bc565b80610c3d575b505061082c6001600855565b5f80808093610c55610c65965460018060a01b031690565b5af1610c5f6113ed565b50611494565b5f80610c31565b9194929391803b63ffffffff1615610cfd571693843b15610137575f604051809663fced708160e01b8252818681610ca8878b60048401611468565b03925af1948515610cf857610c2b96610bff610c2296610c1d94610c1394610bcf9a610cdf575b505b959750959750509650610bdf565b80610cec610cf292610ff1565b806102cd565b5f610ccf565b6112b8565b610c1d9150610c2b96610bff610c2296610bcf98610d2d5f8080808c610c139a5af1610d276113ed565b5061141c565b610cd1565b50600454610bc2565b610d46818484611125565b6040908b8a835163fd6275bf60e01b8152855f8280610d69600498898301611208565b038183305af193845f938496610f38575b50610f055750505050508a610d8d6112d7565b6308c379a014610ed6575b610cf857610db7610db3610dac858f6112c3565b5151151590565b1590565b80610eba575b610e9257508a90610dd1610dac84846112c3565b610e5f575b908280927fd56fb0d5bb780b877d5c011d6bc88787167fd6429fc93e9acc40b20dd8e430368987610e52610e3c8c610e358860608f82610e5a9f91610e27610e22610e2d94838d611125565b611387565b99611125565b01359a6112c3565b5194611391565b94519283926001600160801b03191697836113a5565b0390a4610ac1565b610b83565b90828092818987828a9d610e758d9a8d85611125565b60600135610e829161137a565b9d50505050509192509250610dd6565b610eb6610e9f848e6112c3565b5192516372af8c3360e01b81529283928301611369565b0390fd5b50610ed160a0610ecb858888611125565b0161135f565b610dbd565b8c610edf6112f2565b80610eec575b5050610d98565b90915083610efb865f946112c3565b5101528c5f610ee5565b610db794610db394610f26610dac95610f1e86866112c3565b519015159052565b610f3084846112c3565b5101526112c3565b909550610f5791933d8091833e610f4f8183611024565b810190611151565b929092945f610d7a565b604051634345326f60e11b8152600490fd5b604051633ee5aeb560e01b8152600490fd5b5f80600754905b818110610fab575b5050610b29576040516282b42960e81b8152600490fd5b85610fb582610ae8565b919054339260031b1c1614610fd257610fcd90610ac1565b610f8c565b505050845f80610f94565b634e487b7160e01b5f52604160045260245ffd5b6001600160401b03811161100457604052565b610fdd565b602081019081106001600160401b0382111761100457604052565b90601f801991011681019081106001600160401b0382111761100457604052565b6001600160401b03811161100457601f01601f191660200190565b92919261106c82611045565b9161107a6040519384611024565b829481845281830111610137578281602093845f960137010152565b6001600160401b0381116110045760051b60200190565b906110b782611096565b6040906110c682519182611024565b83815280936110d7601f1991611096565b01905f92835b8381106110eb575050505050565b815190606091828101928184106001600160401b0385111761100457602093855287825283908082840152858301528286010152016110dd565b9190811015610b0a5760051b8101359060be1981360301821215610137570190565b8015150361013757565b919060408382031261013757825161116881611147565b926020810151906001600160401b038211610137570181601f8201121561013757805161119481611045565b926111a26040519485611024565b818452602082840101116101375761082c91602080850191016107b0565b6fffffffffffffffffffffffffffffffff1981160361013757565b908060209392818452848401375f828201840152601f01601f1916010190565b359061120682611147565b565b602081528135611217816111c0565b6001600160801b0319166020820152602082013561123481610126565b6001600160a01b031660408281019190915282013536839003601e1901811215610137578201906020823592016001600160401b038311610137578236038113610137576112b160a061129760c09361082c9685606088015260e08701916111db565b9560608101356080860152608081013582860152016111fb565b1515910152565b6040513d5f823e3d90fd5b8051821015610b0a5760209160051b010190565b5f9060033d116112e357565b905060045f803e5f5160e01c90565b5f60443d1061082c57604051600319913d83016004833e81516001600160401b03918282113d60248401111761134e57818401948551938411611356573d8501016020848701011161134e575061082c92910160200190611024565b949350505050565b50949350505050565b3561082c81611147565b90602061082c9281815201906107f6565b91908201809211610acf57565b3561082c816111c0565b81604051928392833781015f815203902090565b60409061082c9392815281602082015201906107f6565b81810292918115918404141715610acf57565b81156113d9570490565b634e487b7160e01b5f52601260045260245ffd5b3d15611417573d906113fe82611045565b9161140c6040519384611024565b82523d5f602084013e565b606090565b1561142357565b60405162461bcd60e51b815260206004820152601f60248201527f466565207472616e7366657220746f2070726f746f636f6c206661696c6564006044820152606490fd5b91602061082c9381815201916111db565b5f19810191908211610acf57565b91908203918211610acf57565b1561149b57565b60405162461bcd60e51b815260206004820152601e60248201527f466565207472616e7366657220746f2072656c61796572206661696c656400006044820152606490fd5b3561082c81610126565b903590601e198136030182121561013757018035906001600160401b0382116101375760200191813603831361013757565b1561152357565b60405162461bcd60e51b815260206004820152600b60248201526a1a5b9d985b1a5908189a5960aa1b6044820152606490fd5b909291925f6040519460408601908682106001600160401b03831117611004578291604052602093848852828589019686368937868451940192f1913d918083116115a7575b505f908286523e9190565b91505f61159c565b6040513481527f4103257eaac983ca79a70d28f90dfc4fa16b619bb0c17ee7cab0d4034c27962460203392a2565b6020815191015190602081106115fb575b506001600160a01b031690565b5f199060200360031b1b165f6115ee565b60075468010000000000000000811015611004576001810180600755811015610b0a5760075f525f805160206116e98339815191520180546001600160a01b0319166001600160a01b03909216919091179055565b60075480156116b8575f1981019080821015610b0a577fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6879060075f52016bffffffffffffffffffffffff60a01b8154169055600755565b634e487b7160e01b5f52603160045260245ffd5b600654106116d657565b604051630601f69760e01b8152600490fdfea66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688a2646970667358221220bb69fd194b3c6e8f231165252ba1d4d347f7401303e88ea2f7b1d256248d015c64736f6c63430008140033","sourceMap":"463:5731:78:-:0;;;;;;;;;-1:-1:-1;463:5731:78;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;-1:-1:-1;;;;;463:5731:78;;;;;:::o;:::-;;;;;;;;;;-1:-1:-1;;463:5731:78;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;463:5731:78;-1:-1:-1;463:5731:78;;;6002:15:82;463:5731:78;;;;;;6045:16:82;;6041:90;;463:5731:78;;;;;;;;;6041:90:82;-1:-1:-1;463:5731:78;;6041:90:82;;463:5731:78;;;;;;;;;;;;;-1:-1:-1;;;;;463:5731:78;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;463:5731:78;;;;7546:45:82;463:5731:78;;;;;;;;:::i;:::-;;;;;;;7546:45:82;;;463:5731:78;7546:45:82;;463:5731:78;;;;;;;;;;;;;;;;;;;:::i;:::-;7546:45:82;;;;;;;;;:::i;:::-;463:5731:78;7536:56:82;;-1:-1:-1;463:5731:78;;;;;;-1:-1:-1;463:5731:78;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;463:5731:78;;;;-1:-1:-1;463:5731:78;;;;-1:-1:-1;;;;;463:5731:78;1363:10:82;:25;1359:77;;463:5731:78;6476:8:82;;6542:23;6476:8;;:::i;:::-;1755:1:56;6495:21:82;1755:1:56;463:5731:78;;;;;6542:23:82;463:5731:78;1359:77:82;463:5731:78;;-1:-1:-1;;;1411:14:82;;463:5731:78;;1411:14:82;463:5731:78;;;;;;;:::o;:::-;;;;;;-1:-1:-1;;463:5731:78;;;;;6957:23:82;463:5731:78;;;;;;;;;;;;;-1:-1:-1;;463:5731:78;;;;;;;;;:::i;:::-;-1:-1:-1;463:5731:78;;-1:-1:-1;;;;;;;;463:5731:78;;;1363:10:82;:25;1359:77;;463:5731:78;;;;;;;;;;;;;;;;;;;:::i;:::-;;2634:23:82;463:5731:78;;2634:23:82;463:5731:78;;;;;2634:23:82;463:5731:78;;;;-1:-1:-1;;;;;463:5731:78;;;;;;2691:19:82;;463:5731:78;;2691:19:82;463:5731:78;;;2634:23:82;463:5731:78;;-1:-1:-1;;;;;;;;;;;463:5731:78;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;463:5731:78;;;;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;;;;463:5731:78;;;1962:10:82;:27;1958:79;;463:5731:78;;;;-1:-1:-1;3749:10:82;463:5731:78;;;3744:481:82;463:5731:78;;;;4239:49:82;;;;;;-1:-1:-1;;;;;463:5731:78;;-1:-1:-1;;;;;463:5731:78;;;4239:49:82;463:5731:78;;-1:-1:-1;;;;;463:5731:78;;;;;;;;;;;;;;4239:49:82;;;;463:5731:78;3797:3:82;3765:23;463:5731:78;;3761:34:82;;;;;;3820:26;;463:5731:78;3820:26:82;;;:::i;:::-;463:5731:78;;;;;;;;-1:-1:-1;;;;;463:5731:78;;;;;3820:39:82;3816:274;;463:5731:78;4113:34:82;463:5731:78;;4113:34:82;:::i;:::-;4108:39;;4104:111;;3797:3;;;;;;:::i;:::-;3749:10;;;;;4104:111;463:5731:78;;-1:-1:-1;;;4174:26:82;;463:5731:78;;4174:26:82;3816:274;4239:49;3953:34;;4239:49;3953:34;;463:5731:78;3953:34:82;;3879:126;3953:34;;;3879:26;463:5731:78;3908:97:82;3953:34;4239:49;3953:34;;;:::i;:::-;3908:97;:::i;463:5731:78:-;3879:26:82;;:::i;:::-;:126;463:5731:78;;;;;;;;;;;;;;;;;;;;;;;;;;3879:126:82;4023:27;;:::i;:::-;4070:5;;;3761:34;;;;;1958:79;-1:-1:-1;463:5731:78;;-1:-1:-1;;;2012:14:82;;;463:5731:78;;;;;;-1:-1:-1;;463:5731:78;;;;;;;;-1:-1:-1;;;;;463:5731:78;;;;;;;;;;;;;;-1:-1:-1;;463:5731:78;;;;;;;;;;:::i;:::-;;;-1:-1:-1;;;;;463:5731:78;;;;1962:10:82;:27;1958:79;;-1:-1:-1;3159:10:82;;3175:23;463:5731:78;;;;;;;3154:194:82;3171:34;;;;;;3357:39;;;;;:::i;:::-;463:5731:78;;3411:47:82;;;;;;-1:-1:-1;;;;;463:5731:78;;;3411:47:82;;;;463:5731:78;;3207:3:82;463:5731:78;;;-1:-1:-1;;;;;;;;;;;463:5731:78;;;;;-1:-1:-1;;;;;463:5731:78;3230:39:82;;3226:112;;3207:3;;;:::i;:::-;3159:10;;3226:112;463:5731:78;;-1:-1:-1;;;3296:27:82;;463:5731:78;;3296:27:82;1958:79;463:5731:78;;-1:-1:-1;;;2012:14:82;;;463:5731:78;;;;;;;;;;;;;;;;;4483:23:82;463:5731:78;;;;;;;;;;;4483:23:82;463:5731:78;;-1:-1:-1;;;;;;;;;;;463:5731:78;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;463:5731:78;;;;;-1:-1:-1;463:5731:78;;;;;;;;;;;;;;;-1:-1:-1;;;;;463:5731:78;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;463:5731:78;;;;;;;;;:::i;:::-;-1:-1:-1;463:5731:78;;;;-1:-1:-1;;;;;463:5731:78;;;1363:10:82;:25;1359:77;;5634:38;5560:8;463:5731:78;5560:8:82;;;;:::i;:::-;463:5731:78;;;-1:-1:-1;463:5731:78;5579:15:82;463:5731:78;;;;-1:-1:-1;463:5731:78;1755:1:56;463:5731:78;;;;;5634:38:82;463:5731:78;;;;;;;;;-1:-1:-1;;463:5731:78;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7546:45:82;463:5731:78;-1:-1:-1;;463:5731:78;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:::i;:::-;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;-1:-1:-1;;463:5731:78;;;;-1:-1:-1;;;;;463:5731:78;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2057:42;463:5731;;2057:42;;:::i;:::-;463:5731;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;463:5731:78;;;;;;;;;;;;;;;;;;;-1:-1:-1;;463:5731:78;;;;;;;;-1:-1:-1;;;;;463:5731:78;;;;;;;;;;;;;;-1:-1:-1;;463:5731:78;;;;-1:-1:-1;463:5731:78;;;;-1:-1:-1;;;;;463:5731:78;1363:10:82;:25;1359:77;;463:5731:78;4807:8:82;;4881:31;4807:8;;:::i;:::-;1755:1:56;463:5731:78;1755:1:56;463:5731:78;;;;;4881:31:82;463:5731:78;;;;;;;-1:-1:-1;;463:5731:78;;;;;6744:21:82;463:5731:78;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;463:5731:78;;;;;;;;;;-1:-1:-1;;;;;463:5731:78;;;;;;;;;;;;;5267:4;5245:10;:27;5241:79;;5333:28;;;5267:4;5333:45;:28;;;:::i;:45::-;;5329:106;;5540:213;:41;5470:21;5540:41;;:::i;:::-;463:5731;5711:28;;;;463:5731;;;5711:28;:::i;:::-;463:5731;;;:::i;:::-;5632:22;;;;463:5731;5540:213;;:::i;:::-;5764:298;;;;;;463:5731;;;;5711:28;463:5731;;;;;;:::i;5764:298::-;5982:23;5946:32;5920:131;5817:21;;5946:32;:::i;:::-;5982:23;;463:5731;-1:-1:-1;5946:59:78;5920:131;:::i;:::-;5764:298;;;;5329:106;463:5731;;-1:-1:-1;;;5401:23:78;;463:5731;;5401:23;463:5731;;;;;;;;;;;;;-1:-1:-1;;463:5731:78;;;;;;;:::o;:::-;;:::i;:::-;;;;;;;;;;;;;3765:23:82;463:5731:78;;;;;;3765:23:82;-1:-1:-1;463:5731:78;-1:-1:-1;;;;;;;;;;;463:5731:78;;-1:-1:-1;463:5731:78;:::o;:::-;;:::i;1459:453:82:-;463:5731:78;;;;;-1:-1:-1;;;;;463:5731:78;1459:453:82;;463:5731:78;;1496:10:82;:27;1492:403;;1459:453;1755:1:56;2558:7;463:5731:78;2558:18:56;2554:86;;1755:1;2558:7;1755:1;2142:2:78;2119:25;;2115:82;;463:5731;;;;;:::i;:::-;;2207:50;:43;463:5731;;;;;;2225:24;463:5731;;2207:17;463:5731;;;;;;;2207:43;463:5731;;-1:-1:-1;;463:5731:78;2253:4;463:5731;;;;2207:50;2287:43;;;:::i;:::-;2341:20;-1:-1:-1;2376:13:78;;2391:24;;;;;;463:5731;;;3663:29;463:5731;;;;;:::i;:::-;3663:29;:::i;:::-;-1:-1:-1;;;;;463:5731:78;;;;;;1755:1:56;463:5731:78;;;;;3769:28;;;463:5731;3811:21;;3807:100;;2371:1196;3939:27;3938:67;3939:27;;;:::i;:::-;3982:23;463:5731;3938:67;;:::i;:::-;4019:15;;4015:404;;2371:1196;463:5731;;;4428:51;:43;4538:88;463:5731;;4539:60;463:5731;;4540:22;463:5731;;;;:::i;:::-;;;;;;4446:24;463:5731;;2207:17;463:5731;;;;;;;4428:43;463:5731;;-1:-1:-1;;463:5731:78;;;;4428:51;4540:22;:::i;:::-;4578:21;463:5731;4539:60;;:::i;4538:88::-;4640:14;4636:163;;2371:1196;2387:1:56;;;1713;2924:21;1755:1;2744:208;4636:163:78;-1:-1:-1;463:5731:78;;;;;4741:47;463:5731;;;;;;;;;;;4686:41;;;;:::i;:::-;;4741:47;:::i;:::-;4636:163;;;;4015:404;180:58:81;;;;;;;463:5731:78;;255:8:81;463:5731:78;;;4097:136;;;;;;-1:-1:-1;463:5731:78;;;;;;;4097:136;;;;;;;;2563:34;4097:136;;;:::i;:::-;;;;;;;;;;4538:88;4097:136;463:5731;4540:22;4097:136;4428:51;4097:136;4428:43;4097:136;4539:60;4097:136;;;4050:359;;;4015:404;;;;;;;;;;;4097:136;;;;;;:::i;:::-;;;:::i;:::-;;;;;;:::i;4050:359::-;4428:51;4288:40;;4538:88;4288:40;463:5731;4540:22;4288:40;4539:60;4288:40;4346:48;-1:-1:-1;4288:40:78;;;;4428:43;4288:40;;;;;:::i;:::-;;4346:48;:::i;:::-;4050:359;;3807:100;-1:-1:-1;2563:34:78;463:5731;3807:100;;2417:3;2580:16;;;;;:::i;:::-;463:5731;;;;;;;;;2563:34;;;-1:-1:-1;2563:34:78;;;;;;;;;:::i;:::-;;:4;;;:34;;;;-1:-1:-1;;;2563:34:78;;;2417:3;-1:-1:-1;2436:478:78;;;;;;;;;;:::i;:::-;;;;;;;;2949:37;2950:36;:20;2436:478;;2950:20;:::i;:::-;;463:5731;;;;;2950:36;2949:37;;463:5731;2949:37;:89;;;2436:478;2928:205;;3227:20;;;:36;:20;;;;:::i;:36::-;3223:113;;2436:478;3438:16;;;;3355:201;3438:16;;3355:201;;3438:16;3522:20;3438:16;3478:26;3438:16;;2417:3;3438:16;;:22;:16;3478;3438;;;;:::i;:::-;:22;:::i;:::-;3478:16;;:::i;:::-;:26;463:5731;3522:20;;:::i;:::-;;3355:201;;:::i;:::-;463:5731;;;;;-1:-1:-1;;;;;463:5731:78;;3355:201;;;:::i;:::-;;;;2417:3;:::i;:::-;2376:13;;3223:113;3295:16;;;;;;;;;;;;;;;;:::i;:::-;3478:26;3295;463:5731;3283:38;;;:::i;:::-;3223:113;;;;;;;;;;;;;2928:205;3078:40;3097:20;;;;:::i;:::-;;463:5731;;-1:-1:-1;;;3078:40:78;;463:5731;;;3078:40;;;:::i;:::-;;;;2949:89;3006:16;:32;463:5731;3006:16;;;;;:::i;:::-;:32;;:::i;:::-;2949:89;;2436:478;2796:118;;;:::i;:::-;;;;2436:478;;;;;2796:118;;;;;2848:20;2796:118;-1:-1:-1;2848:20:78;;:::i;:::-;;:42;:51;2796:118;;;;2436:478;2949:37;2672:20;2950:36;2672:20;:46;2950:20;2672;;;;;:::i;:::-;;463:5731;;;;;;2672:46;2736:20;;;;:::i;:::-;;:35;:44;2950:20;:::i;2563:34::-;;;;;;;;;;;;;;;;:::i;:::-;;;;;:::i;:::-;;;;;;;;2115:82;463:5731;;-1:-1:-1;;;2167:19:78;;;;;2554:86:56;463:5731:78;;-1:-1:-1;;;2599:30:56;;;;;1492:403:82;-1:-1:-1;1582:10:82;1598:23;463:5731:78;1577:222:82;1594:34;;;;;;1577:222;1817:12;;1492:403;1813:72;463:5731:78;;-1:-1:-1;;;1856:14:82;;;;;1630:3;1657:26;;;;:::i;:::-;463:5731:78;;;1496:10:82;463:5731:78;;;;;1657:40:82;1653:132;;1630:3;;;:::i;:::-;1582:10;;1653:132;1721:18;;;;1761:5;;;;463:5731:78;;;;;;;;;;;;;-1:-1:-1;;;;;463:5731:78;;;;;;:::o;:::-;;:::i;:::-;;;;;;;-1:-1:-1;;;;;463:5731:78;;;;;;;:::o;:::-;;7546:45:82;;;463:5731:78;;;;;;;;-1:-1:-1;;;;;463:5731:78;;;;;;;:::o;:::-;-1:-1:-1;;;;;463:5731:78;;;;7546:45:82;463:5731:78;-1:-1:-1;;463:5731:78;;;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;-1:-1:-1;463:5731:78;;;;;;:::o;:::-;-1:-1:-1;;;;;463:5731:78;;;;;;;;;:::o;:::-;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;7546:45:82;463:5731:78;7546:45:82;;463:5731:78;;:::i;:::-;;;-1:-1:-1;463:5731:78;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;-1:-1:-1;;;;;463:5731:78;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;:::o;:::-;;;;;;;;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;;;;463:5731:78;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;463:5731:78;;;;;:::o;:::-;;;;;;;;;;;;;-1:-1:-1;463:5731:78;;;;;;7546:45:82;463:5731:78;-1:-1:-1;;463:5731:78;;;;:::o;:::-;;;;;;:::i;:::-;:::o;:::-;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;463:5731:78;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;463:5731:78;;;;;;;;;;;;;;;;-1:-1:-1;;463:5731:78;;;;;;;;;;;;;;-1:-1:-1;;;;;463:5731:78;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;:::o;:::-;;;;;;;;;;;;:::o;:::-;;;;;;;;;-1:-1:-1;;463:5731:78;;;;;;;;;-1:-1:-1;;;;;463:5731:78;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;463:5731:78;;;;;;;;:::i;:::-;;;;;;;:::o;:::-;;;;;;;;:::o;:::-;;;;;:::i;:::-;;;;;;;;;;;:::i;:::-;;;;;;;;;;:::o;:::-;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;463:5731:78;;;;;;:::o;:::-;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;-1:-1:-1;463:5731:78;;;;:::o;:::-;;;:::o;:::-;;;;:::o;:::-;;;-1:-1:-1;;;463:5731:78;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;463:5731:78;;;;;;;;:::o;:::-;;;;;;;;;;:::o;:::-;;;;:::o;:::-;;;-1:-1:-1;;;463:5731:78;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;463:5731:78;;;;;;;;;;;;;;:::o;:::-;;;;:::o;:::-;;;-1:-1:-1;;;463:5731:78;;;;;;;;;;;;-1:-1:-1;;;463:5731:78;;;;;;;1192:1309:0;;;;;-1:-1:-1;463:5731:78;;;;;;;;;;-1:-1:-1;;;;;463:5731:78;;;;;;;;;;;;;;;;;;;;;;;1753:702:0;;;;;;;;;;;;;;;1192:1309;1753:702;-1:-1:-1;1753:702:0;;;;;2464:30;1192:1309;:::o;1753:702::-;;-1:-1:-1;;1753:702:0;;6109:83:78;463:5731;;6175:9;463:5731;;6151:34;463:5731;6163:10;6151:34;;6109:83::o;277:220:81:-;463:5731:78;;;;;;;;;;;;277:220:81;-1:-1:-1;;;;;;463:5731:78;;277:220:81:o;463:5731:78:-;;;;;;;;;;;;;;3175:23:82;463:5731:78;;;;;;;;;;;3175:23:82;463:5731:78;;;;;;3175:23:82;-1:-1:-1;463:5731:78;-1:-1:-1;;;;;;;;;;;463:5731:78;;;-1:-1:-1;;;;;;463:5731:78;-1:-1:-1;;;;;463:5731:78;;;;;;;;;:::o;:::-;3765:23:82;463:5731:78;;;;;-1:-1:-1;;463:5731:78;;;;;;;;;;;3765:23:82;463:5731:78;;;;;;;;;;;3765:23:82;463:5731:78;:::o;:::-;;;;;;;;;;;;2060:163:82;2143:23;463:5731:78;-1:-1:-1;2128:89:82;;2060:163::o;2128:89::-;463:5731:78;;-1:-1:-1;;;2189:17:82;;;;","linkReferences":{}},"methodIdentifiers":{"addRelayerSubwallet(address)":"717a06f8","callWithBid((bytes16,address,bytes,uint256,uint256,bool))":"fd6275bf","getAdmin()":"6e9960c3","getFeeProtocol(address)":"1953ea74","getFeeProtocolDefault()":"b0e6fa47","getFeeRelayer()":"e6055ea6","getFeeSplitPrecision()":"53383af1","getRelayer()":"bdc50373","getRelayerSubwallets()":"8e7f00c8","isPermissioned(address,bytes)":"403e96f6","multicall(bytes,(bytes16,address,bytes,uint256,uint256,bool)[])":"9aacc67a","removeRelayerSubwallet(address)":"6caad4ec","setFeeProtocol(address,uint256)":"929628c2","setFeeProtocolDefault(uint256)":"be064301","setFeeRelayer(uint256)":"4767ea4d","setRelayer(address)":"6548e9bc"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.20+commit.a1b79de6\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DuplicateRelayerSubwallet\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"externalSuccess\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"externalResult\",\"type\":\"bytes\"},{\"internalType\":\"string\",\"name\":\"multicallRevertReason\",\"type\":\"string\"}],\"internalType\":\"struct MulticallStatus\",\"name\":\"status\",\"type\":\"tuple\"}],\"name\":\"ExternalCallFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidFeeSplit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPermission\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTargetContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrancyGuardReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RelayerSubwalletNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeSplit\",\"type\":\"uint256\"}],\"name\":\"FeeProtocolDefaultSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeRecipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeSplit\",\"type\":\"uint256\"}],\"name\":\"FeeProtocolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeSplit\",\"type\":\"uint256\"}],\"name\":\"FeeRelayerSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes\",\"name\":\"permissionKey\",\"type\":\"bytes\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"multicallIndex\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bytes16\",\"name\":\"bidId\",\"type\":\"bytes16\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"bidAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"externalSuccess\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"externalResult\",\"type\":\"bytes\"},{\"internalType\":\"string\",\"name\":\"multicallRevertReason\",\"type\":\"string\"}],\"indexed\":false,\"internalType\":\"struct MulticallStatus\",\"name\":\"multicallStatus\",\"type\":\"tuple\"}],\"name\":\"MulticallIssued\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"ReceivedETH\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"relayer\",\"type\":\"address\"}],\"name\":\"RelayerSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"relayer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"subwallet\",\"type\":\"address\"}],\"name\":\"RelayerSubwalletAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"relayer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"subwallet\",\"type\":\"address\"}],\"name\":\"RelayerSubwalletRemoved\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"subwallet\",\"type\":\"address\"}],\"name\":\"addRelayerSubwallet\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes16\",\"name\":\"bidId\",\"type\":\"bytes16\"},{\"internalType\":\"address\",\"name\":\"targetContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"targetCalldata\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"bidAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"revertOnFailure\",\"type\":\"bool\"}],\"internalType\":\"struct MulticallData\",\"name\":\"multicallData\",\"type\":\"tuple\"}],\"name\":\"callWithBid\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"feeRecipient\",\"type\":\"address\"}],\"name\":\"getFeeProtocol\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeeProtocolDefault\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeeRelayer\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeeSplitPrecision\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRelayer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRelayerSubwallets\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"protocolFeeReceiver\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"permissionId\",\"type\":\"bytes\"}],\"name\":\"isPermissioned\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"permissioned\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"permissionKey\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bytes16\",\"name\":\"bidId\",\"type\":\"bytes16\"},{\"internalType\":\"address\",\"name\":\"targetContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"targetCalldata\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"bidAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"revertOnFailure\",\"type\":\"bool\"}],\"internalType\":\"struct MulticallData[]\",\"name\":\"multicallData\",\"type\":\"tuple[]\"}],\"name\":\"multicall\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"externalSuccess\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"externalResult\",\"type\":\"bytes\"},{\"internalType\":\"string\",\"name\":\"multicallRevertReason\",\"type\":\"string\"}],\"internalType\":\"struct MulticallStatus[]\",\"name\":\"multicallStatuses\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"subwallet\",\"type\":\"address\"}],\"name\":\"removeRelayerSubwallet\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"feeRecipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeSplit\",\"type\":\"uint256\"}],\"name\":\"setFeeProtocol\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"feeSplit\",\"type\":\"uint256\"}],\"name\":\"setFeeProtocolDefault\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"feeSplit\",\"type\":\"uint256\"}],\"name\":\"setFeeRelayer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"relayer\",\"type\":\"address\"}],\"name\":\"setRelayer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"errors\":{\"ReentrancyGuardReentrantCall()\":[{\"details\":\"Unauthorized reentrant call.\"}]},\"kind\":\"dev\",\"methods\":{\"addRelayerSubwallet(address)\":{\"params\":{\"subwallet\":\": address of the relayer subwallet to be added\"}},\"callWithBid((bytes16,address,bytes,uint256,uint256,bool))\":{\"params\":{\"multicallData\":\": data for multicall, consisting of targetContract, targetCalldata, and bidAmount\"}},\"getFeeProtocol(address)\":{\"params\":{\"feeRecipient\":\": address of the fee recipient for the protocol\"}},\"isPermissioned(address,bytes)\":{\"params\":{\"permissionId\":\": arbitrary bytes representing the action being gated, second part of the permission key\",\"protocolFeeReceiver\":\": address of the protocol fee receiver, first part of permission key\"}},\"multicall(bytes,(bytes16,address,bytes,uint256,uint256,bool)[])\":{\"params\":{\"multicallData\":\": ordered list of data for multicall, consisting of targetContract, targetCalldata, and bidAmount\",\"permissionKey\":\": permission to allow for this call\"}},\"removeRelayerSubwallet(address)\":{\"params\":{\"subwallet\":\": address of the relayer subwallet to be removed\"}},\"setFeeProtocol(address,uint256)\":{\"params\":{\"feeRecipient\":\": address of the fee recipient for the protocol\",\"feeSplit\":\": split of fee to be sent to the protocol. 10**18 is 100%\"}},\"setFeeProtocolDefault(uint256)\":{\"params\":{\"feeSplit\":\": split of fee to be sent to the protocol. 10**18 is 100%\"}},\"setFeeRelayer(uint256)\":{\"params\":{\"feeSplit\":\": split of remaining fee (after subtracting protocol fee) to be sent to the relayer. 10**18 is 100%\"}},\"setRelayer(address)\":{\"params\":{\"relayer\":\": address of the relayer to be set\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"addRelayerSubwallet(address)\":{\"notice\":\"addRelayerSubwallet function - adds a relayer subwallet\"},\"callWithBid((bytes16,address,bytes,uint256,uint256,bool))\":{\"notice\":\"callWithBid function - contained call to function with check for bid invariant\"},\"getAdmin()\":{\"notice\":\"getAdmin function - returns the address of the admin\"},\"getFeeProtocol(address)\":{\"notice\":\"getFeeProtocol function - returns the fee split for a given protocol fee recipient\"},\"getFeeProtocolDefault()\":{\"notice\":\"getFeeProtocolDefault function - returns the default fee split for the protocol\"},\"getFeeRelayer()\":{\"notice\":\"getFeeRelayer function - returns the fee split for the relayer\"},\"getFeeSplitPrecision()\":{\"notice\":\"getFeeSplitPrecision function - returns the precision for fee splits\"},\"getRelayer()\":{\"notice\":\"getRelayer function - returns the address of the relayer\"},\"getRelayerSubwallets()\":{\"notice\":\"getRelayerSubwallets function - returns the relayer subwallets\"},\"isPermissioned(address,bytes)\":{\"notice\":\"isPermissioned function - checks if a given permission key is currently allowed\"},\"multicall(bytes,(bytes16,address,bytes,uint256,uint256,bool)[])\":{\"notice\":\"multicall function - performs a number of calls to external contracts in order\"},\"removeRelayerSubwallet(address)\":{\"notice\":\"removeRelayerSubwallet function - removes a relayer subwallet\"},\"setFeeProtocol(address,uint256)\":{\"notice\":\"setFeeProtocol function - sets the fee split for a given protocol fee recipient\"},\"setFeeProtocolDefault(uint256)\":{\"notice\":\"setFeeProtocolDefault function - sets the default fee split for the protocol\"},\"setFeeRelayer(uint256)\":{\"notice\":\"setFeeRelayer function - sets the fee split for the relayer\"},\"setRelayer(address)\":{\"notice\":\"setRelayer function - sets the relayer\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/express-relay/ExpressRelay.sol\":\"ExpressRelay\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@pythnetwork/express-relay-sdk-solidity/=node_modules/@pythnetwork/express-relay-sdk-solidity/\",\":@pythnetwork/pyth-sdk-solidity/=node_modules/@pythnetwork/pyth-sdk-solidity/\",\":ExcessivelySafeCall/=lib/ExcessivelySafeCall/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/\",\":forge-gas-snapshot/=lib/permit2/lib/forge-gas-snapshot/src/\",\":forge-std/=lib/forge-std/src/\",\":halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":openzeppelin/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":permit2/=lib/permit2/src/\",\":solmate/=lib/permit2/lib/solmate/src/\"],\"viaIR\":true},\"sources\":{\"lib/ExcessivelySafeCall/src/ExcessivelySafeCall.sol\":{\"keccak256\":\"0x7d9d432e8f02168bf3f790e3dabcf36402782acf7ffa476cabe86fc4d8962eb2\",\"license\":\"MIT OR Apache-2.0\",\"urls\":[\"bzz-raw://1adc13e7f399f500ea5f81480ad149a50408fde7990a2c6347e6377486f389dc\",\"dweb:/ipfs/QmSvm5TUBJqknsqNJLLHqNS4MLSH5k3vNrbquVg6ZKSfx9\"]},\"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0xc6a8ff0ea489379b61faa647490411b80102578440ab9d84e9a957cc12164e70\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://0ea104e577e63faea3b69c415637e99e755dcbf64c5833d7140c35a714d6d90c\",\"dweb:/ipfs/Qmau6x4Ns9XdyynRCNNp3RhLqijJjFm7z5fyZazfYFGYdq\"]},\"lib/openzeppelin-contracts/contracts/utils/ReentrancyGuard.sol\":{\"keccak256\":\"0xf980daa263b661ab8ddee7d4fd833c7da7e7995e2c359ff1f17e67e4112f2236\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://7448ab095d6940130bcf76ba47a2eab14148c83119523b93dd89f6d84edd6c02\",\"dweb:/ipfs/QmawrZ4voKQjH3oomXT3Kuheb3Mnmo2VvVpxg8Ne5UJUrd\"]},\"node_modules/@pythnetwork/express-relay-sdk-solidity/IExpressRelay.sol\":{\"keccak256\":\"0xde2d530bc6bc0d4f417a14ab80bcd9867f464b777e64e6d968b1a1c2d96ec538\",\"license\":\"UNLICENSED\",\"urls\":[\"bzz-raw://1fcca54f3191f9d31405539b055b124aa88db37dcc3964062d1f230a982089c8\",\"dweb:/ipfs/QmZ2VxrzDjUHTQwso3o8xSi7FkjihRmEq87PfnizAkj6K7\"]},\"node_modules/@pythnetwork/express-relay-sdk-solidity/IExpressRelayFeeReceiver.sol\":{\"keccak256\":\"0xa2644c4da62bd9da8f8f0904030f3537361ec3e74550202bedfac2a2f98a3088\",\"license\":\"UNLICENSED\",\"urls\":[\"bzz-raw://f2769866f51e447027c327bd9f0e6a0f143d86a11ae12fb30a3597a4debd1bc2\",\"dweb:/ipfs/QmdNUGZDCxFJ6kz7Y8AJJcRMG6U7jA5AhjKD5QatFEmo5D\"]},\"src/express-relay/Errors.sol\":{\"keccak256\":\"0x7be7230c606a597906c09fad167f3a0e9d9ebec98f982c1189e9f7658d38067e\",\"license\":\"Apache 2\",\"urls\":[\"bzz-raw://871a795cd080c805c8423d373a03c47df69e3c10f9161b6cacdec5b12e56d47d\",\"dweb:/ipfs/QmVnmNNMFowbVtZBtq6F51qBSR994pxfPQZtKAApxgnbUC\"]},\"src/express-relay/Events.sol\":{\"keccak256\":\"0x9eb1038eb92d37a304fda2e32abccf3f1e2a1b614af8683d87bfd0b3ee35006c\",\"license\":\"Apache 2\",\"urls\":[\"bzz-raw://a7d069436fcddcca85b5e13c7577446fb73180c201d00057f71814a0a4624986\",\"dweb:/ipfs/QmXHtiq5eMa4BwnsiZnwVkp9tXeNSoRfZTvqq5Uo4EfQJP\"]},\"src/express-relay/ExpressRelay.sol\":{\"keccak256\":\"0x3eb7b0972ba15b97b67397ae428e1ac93d79d19a1761c6d83aa0214602e8b05d\",\"license\":\"Apache 2\",\"urls\":[\"bzz-raw://356938ef39f3922da64c6606cfe1e2775eca69fa8b1eae61a653c1a9f768b71a\",\"dweb:/ipfs/QmSnhuaiMMTfyf3eni7ApaDJgDfcEzsSESZhYvx6YHywTg\"]},\"src/express-relay/GovernanceEvents.sol\":{\"keccak256\":\"0x4af670ad938b44bb2836b6212a6eff63ba59e59f35d115ed6d444698f8aead6a\",\"license\":\"Apache 2\",\"urls\":[\"bzz-raw://c41c45c0e3a7cf4e90572b8fe1e4cfda5ef1d8eb6fd784ac6785cfd118dc76e0\",\"dweb:/ipfs/Qma2w5HheMQhKVPXPj9qSyNkjXvYVSBhcBVR3P5EZaMr2b\"]},\"src/express-relay/Helpers.sol\":{\"keccak256\":\"0xf2a2893c2d46e816e033bfaa6a933027ba0648b654e4c03372a714e830b760e0\",\"license\":\"Apache 2\",\"urls\":[\"bzz-raw://3c8e0be649b61bc8e27a818c4bff9288981d29c602ed506193d7b5a2baf3faaa\",\"dweb:/ipfs/QmP3xVcC1SQKxtjgc3LVjHjZKTzEqax3NZfgdeNFhVSkUL\"]},\"src/express-relay/State.sol\":{\"keccak256\":\"0xbd12dc956ed2d96cf964a510fa59a6eacb381d77e5fbc2e65c68c99a22692390\",\"license\":\"Apache 2\",\"urls\":[\"bzz-raw://f14f09cf1c5c3760d520f33ba493de93e59afc9395e6d455211672350a158145\",\"dweb:/ipfs/QmXWT3Ks6GBPAyEzy1ErXnbHkKsB5yqNdTtcYhyoDReQdn\"]},\"src/express-relay/Structs.sol\":{\"keccak256\":\"0x17d0b684650532efe556ac33cc74b9fe6befba7abbcd29f4af1415058b736453\",\"license\":\"Apache 2\",\"urls\":[\"bzz-raw://ee60a5e5e3ee4955b7fb4b0f90fdf438955988bb58659f25c3ed08bff23bbdb4\",\"dweb:/ipfs/Qmbj5QxUX2spunScm7Meov8WbbEjz2nwWALFGKJCJr2RK6\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.20+commit.a1b79de6"},"language":"Solidity","output":{"abi":[{"inputs":[],"type":"error","name":"DuplicateRelayerSubwallet"},{"inputs":[{"internalType":"struct MulticallStatus","name":"status","type":"tuple","components":[{"internalType":"bool","name":"externalSuccess","type":"bool"},{"internalType":"bytes","name":"externalResult","type":"bytes"},{"internalType":"string","name":"multicallRevertReason","type":"string"}]}],"type":"error","name":"ExternalCallFailed"},{"inputs":[],"type":"error","name":"InvalidFeeSplit"},{"inputs":[],"type":"error","name":"InvalidPermission"},{"inputs":[],"type":"error","name":"InvalidTargetContract"},{"inputs":[],"type":"error","name":"ReentrancyGuardReentrantCall"},{"inputs":[],"type":"error","name":"RelayerSubwalletNotFound"},{"inputs":[],"type":"error","name":"Unauthorized"},{"inputs":[{"internalType":"uint256","name":"feeSplit","type":"uint256","indexed":false}],"type":"event","name":"FeeProtocolDefaultSet","anonymous":false},{"inputs":[{"internalType":"address","name":"feeRecipient","type":"address","indexed":true},{"internalType":"uint256","name":"feeSplit","type":"uint256","indexed":false}],"type":"event","name":"FeeProtocolSet","anonymous":false},{"inputs":[{"internalType":"uint256","name":"feeSplit","type":"uint256","indexed":false}],"type":"event","name":"FeeRelayerSet","anonymous":false},{"inputs":[{"internalType":"bytes","name":"permissionKey","type":"bytes","indexed":true},{"internalType":"uint256","name":"multicallIndex","type":"uint256","indexed":true},{"internalType":"bytes16","name":"bidId","type":"bytes16","indexed":true},{"internalType":"uint256","name":"bidAmount","type":"uint256","indexed":false},{"internalType":"struct MulticallStatus","name":"multicallStatus","type":"tuple","components":[{"internalType":"bool","name":"externalSuccess","type":"bool"},{"internalType":"bytes","name":"externalResult","type":"bytes"},{"internalType":"string","name":"multicallRevertReason","type":"string"}],"indexed":false}],"type":"event","name":"MulticallIssued","anonymous":false},{"inputs":[{"internalType":"address","name":"sender","type":"address","indexed":true},{"internalType":"uint256","name":"amount","type":"uint256","indexed":false}],"type":"event","name":"ReceivedETH","anonymous":false},{"inputs":[{"internalType":"address","name":"relayer","type":"address","indexed":false}],"type":"event","name":"RelayerSet","anonymous":false},{"inputs":[{"internalType":"address","name":"relayer","type":"address","indexed":true},{"internalType":"address","name":"subwallet","type":"address","indexed":false}],"type":"event","name":"RelayerSubwalletAdded","anonymous":false},{"inputs":[{"internalType":"address","name":"relayer","type":"address","indexed":true},{"internalType":"address","name":"subwallet","type":"address","indexed":false}],"type":"event","name":"RelayerSubwalletRemoved","anonymous":false},{"inputs":[{"internalType":"address","name":"subwallet","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"addRelayerSubwallet"},{"inputs":[{"internalType":"struct MulticallData","name":"multicallData","type":"tuple","components":[{"internalType":"bytes16","name":"bidId","type":"bytes16"},{"internalType":"address","name":"targetContract","type":"address"},{"internalType":"bytes","name":"targetCalldata","type":"bytes"},{"internalType":"uint256","name":"bidAmount","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"bool","name":"revertOnFailure","type":"bool"}]}],"stateMutability":"payable","type":"function","name":"callWithBid","outputs":[{"internalType":"bool","name":"","type":"bool"},{"internalType":"bytes","name":"","type":"bytes"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"getAdmin","outputs":[{"internalType":"address","name":"","type":"address"}]},{"inputs":[{"internalType":"address","name":"feeRecipient","type":"address"}],"stateMutability":"view","type":"function","name":"getFeeProtocol","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"getFeeProtocolDefault","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"getFeeRelayer","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"getFeeSplitPrecision","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"getRelayer","outputs":[{"internalType":"address","name":"","type":"address"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"getRelayerSubwallets","outputs":[{"internalType":"address[]","name":"","type":"address[]"}]},{"inputs":[{"internalType":"address","name":"protocolFeeReceiver","type":"address"},{"internalType":"bytes","name":"permissionId","type":"bytes"}],"stateMutability":"view","type":"function","name":"isPermissioned","outputs":[{"internalType":"bool","name":"permissioned","type":"bool"}]},{"inputs":[{"internalType":"bytes","name":"permissionKey","type":"bytes"},{"internalType":"struct MulticallData[]","name":"multicallData","type":"tuple[]","components":[{"internalType":"bytes16","name":"bidId","type":"bytes16"},{"internalType":"address","name":"targetContract","type":"address"},{"internalType":"bytes","name":"targetCalldata","type":"bytes"},{"internalType":"uint256","name":"bidAmount","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"bool","name":"revertOnFailure","type":"bool"}]}],"stateMutability":"payable","type":"function","name":"multicall","outputs":[{"internalType":"struct MulticallStatus[]","name":"multicallStatuses","type":"tuple[]","components":[{"internalType":"bool","name":"externalSuccess","type":"bool"},{"internalType":"bytes","name":"externalResult","type":"bytes"},{"internalType":"string","name":"multicallRevertReason","type":"string"}]}]},{"inputs":[{"internalType":"address","name":"subwallet","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"removeRelayerSubwallet"},{"inputs":[{"internalType":"address","name":"feeRecipient","type":"address"},{"internalType":"uint256","name":"feeSplit","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"setFeeProtocol"},{"inputs":[{"internalType":"uint256","name":"feeSplit","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"setFeeProtocolDefault"},{"inputs":[{"internalType":"uint256","name":"feeSplit","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"setFeeRelayer"},{"inputs":[{"internalType":"address","name":"relayer","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"setRelayer"},{"inputs":[],"stateMutability":"payable","type":"receive"}],"devdoc":{"kind":"dev","methods":{"addRelayerSubwallet(address)":{"params":{"subwallet":": address of the relayer subwallet to be added"}},"callWithBid((bytes16,address,bytes,uint256,uint256,bool))":{"params":{"multicallData":": data for multicall, consisting of targetContract, targetCalldata, and bidAmount"}},"getFeeProtocol(address)":{"params":{"feeRecipient":": address of the fee recipient for the protocol"}},"isPermissioned(address,bytes)":{"params":{"permissionId":": arbitrary bytes representing the action being gated, second part of the permission key","protocolFeeReceiver":": address of the protocol fee receiver, first part of permission key"}},"multicall(bytes,(bytes16,address,bytes,uint256,uint256,bool)[])":{"params":{"multicallData":": ordered list of data for multicall, consisting of targetContract, targetCalldata, and bidAmount","permissionKey":": permission to allow for this call"}},"removeRelayerSubwallet(address)":{"params":{"subwallet":": address of the relayer subwallet to be removed"}},"setFeeProtocol(address,uint256)":{"params":{"feeRecipient":": address of the fee recipient for the protocol","feeSplit":": split of fee to be sent to the protocol. 10**18 is 100%"}},"setFeeProtocolDefault(uint256)":{"params":{"feeSplit":": split of fee to be sent to the protocol. 10**18 is 100%"}},"setFeeRelayer(uint256)":{"params":{"feeSplit":": split of remaining fee (after subtracting protocol fee) to be sent to the relayer. 10**18 is 100%"}},"setRelayer(address)":{"params":{"relayer":": address of the relayer to be set"}}},"version":1},"userdoc":{"kind":"user","methods":{"addRelayerSubwallet(address)":{"notice":"addRelayerSubwallet function - adds a relayer subwallet"},"callWithBid((bytes16,address,bytes,uint256,uint256,bool))":{"notice":"callWithBid function - contained call to function with check for bid invariant"},"getAdmin()":{"notice":"getAdmin function - returns the address of the admin"},"getFeeProtocol(address)":{"notice":"getFeeProtocol function - returns the fee split for a given protocol fee recipient"},"getFeeProtocolDefault()":{"notice":"getFeeProtocolDefault function - returns the default fee split for the protocol"},"getFeeRelayer()":{"notice":"getFeeRelayer function - returns the fee split for the relayer"},"getFeeSplitPrecision()":{"notice":"getFeeSplitPrecision function - returns the precision for fee splits"},"getRelayer()":{"notice":"getRelayer function - returns the address of the relayer"},"getRelayerSubwallets()":{"notice":"getRelayerSubwallets function - returns the relayer subwallets"},"isPermissioned(address,bytes)":{"notice":"isPermissioned function - checks if a given permission key is currently allowed"},"multicall(bytes,(bytes16,address,bytes,uint256,uint256,bool)[])":{"notice":"multicall function - performs a number of calls to external contracts in order"},"removeRelayerSubwallet(address)":{"notice":"removeRelayerSubwallet function - removes a relayer subwallet"},"setFeeProtocol(address,uint256)":{"notice":"setFeeProtocol function - sets the fee split for a given protocol fee recipient"},"setFeeProtocolDefault(uint256)":{"notice":"setFeeProtocolDefault function - sets the default fee split for the protocol"},"setFeeRelayer(uint256)":{"notice":"setFeeRelayer function - sets the fee split for the relayer"},"setRelayer(address)":{"notice":"setRelayer function - sets the relayer"}},"version":1}},"settings":{"remappings":["@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/","@pythnetwork/express-relay-sdk-solidity/=node_modules/@pythnetwork/express-relay-sdk-solidity/","@pythnetwork/pyth-sdk-solidity/=node_modules/@pythnetwork/pyth-sdk-solidity/","ExcessivelySafeCall/=lib/ExcessivelySafeCall/src/","ds-test/=lib/forge-std/lib/ds-test/src/","erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/","forge-gas-snapshot/=lib/permit2/lib/forge-gas-snapshot/src/","forge-std/=lib/forge-std/src/","halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/","openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/","openzeppelin-contracts/=lib/openzeppelin-contracts/","openzeppelin/=lib/openzeppelin-contracts-upgradeable/contracts/","permit2/=lib/permit2/src/","solmate/=lib/permit2/lib/solmate/src/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"src/express-relay/ExpressRelay.sol":"ExpressRelay"},"evmVersion":"shanghai","libraries":{},"viaIR":true},"sources":{"lib/ExcessivelySafeCall/src/ExcessivelySafeCall.sol":{"keccak256":"0x7d9d432e8f02168bf3f790e3dabcf36402782acf7ffa476cabe86fc4d8962eb2","urls":["bzz-raw://1adc13e7f399f500ea5f81480ad149a50408fde7990a2c6347e6377486f389dc","dweb:/ipfs/QmSvm5TUBJqknsqNJLLHqNS4MLSH5k3vNrbquVg6ZKSfx9"],"license":"MIT OR Apache-2.0"},"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol":{"keccak256":"0xc6a8ff0ea489379b61faa647490411b80102578440ab9d84e9a957cc12164e70","urls":["bzz-raw://0ea104e577e63faea3b69c415637e99e755dcbf64c5833d7140c35a714d6d90c","dweb:/ipfs/Qmau6x4Ns9XdyynRCNNp3RhLqijJjFm7z5fyZazfYFGYdq"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/ReentrancyGuard.sol":{"keccak256":"0xf980daa263b661ab8ddee7d4fd833c7da7e7995e2c359ff1f17e67e4112f2236","urls":["bzz-raw://7448ab095d6940130bcf76ba47a2eab14148c83119523b93dd89f6d84edd6c02","dweb:/ipfs/QmawrZ4voKQjH3oomXT3Kuheb3Mnmo2VvVpxg8Ne5UJUrd"],"license":"MIT"},"node_modules/@pythnetwork/express-relay-sdk-solidity/IExpressRelay.sol":{"keccak256":"0xde2d530bc6bc0d4f417a14ab80bcd9867f464b777e64e6d968b1a1c2d96ec538","urls":["bzz-raw://1fcca54f3191f9d31405539b055b124aa88db37dcc3964062d1f230a982089c8","dweb:/ipfs/QmZ2VxrzDjUHTQwso3o8xSi7FkjihRmEq87PfnizAkj6K7"],"license":"UNLICENSED"},"node_modules/@pythnetwork/express-relay-sdk-solidity/IExpressRelayFeeReceiver.sol":{"keccak256":"0xa2644c4da62bd9da8f8f0904030f3537361ec3e74550202bedfac2a2f98a3088","urls":["bzz-raw://f2769866f51e447027c327bd9f0e6a0f143d86a11ae12fb30a3597a4debd1bc2","dweb:/ipfs/QmdNUGZDCxFJ6kz7Y8AJJcRMG6U7jA5AhjKD5QatFEmo5D"],"license":"UNLICENSED"},"src/express-relay/Errors.sol":{"keccak256":"0x7be7230c606a597906c09fad167f3a0e9d9ebec98f982c1189e9f7658d38067e","urls":["bzz-raw://871a795cd080c805c8423d373a03c47df69e3c10f9161b6cacdec5b12e56d47d","dweb:/ipfs/QmVnmNNMFowbVtZBtq6F51qBSR994pxfPQZtKAApxgnbUC"],"license":"Apache 2"},"src/express-relay/Events.sol":{"keccak256":"0x9eb1038eb92d37a304fda2e32abccf3f1e2a1b614af8683d87bfd0b3ee35006c","urls":["bzz-raw://a7d069436fcddcca85b5e13c7577446fb73180c201d00057f71814a0a4624986","dweb:/ipfs/QmXHtiq5eMa4BwnsiZnwVkp9tXeNSoRfZTvqq5Uo4EfQJP"],"license":"Apache 2"},"src/express-relay/ExpressRelay.sol":{"keccak256":"0x3eb7b0972ba15b97b67397ae428e1ac93d79d19a1761c6d83aa0214602e8b05d","urls":["bzz-raw://356938ef39f3922da64c6606cfe1e2775eca69fa8b1eae61a653c1a9f768b71a","dweb:/ipfs/QmSnhuaiMMTfyf3eni7ApaDJgDfcEzsSESZhYvx6YHywTg"],"license":"Apache 2"},"src/express-relay/GovernanceEvents.sol":{"keccak256":"0x4af670ad938b44bb2836b6212a6eff63ba59e59f35d115ed6d444698f8aead6a","urls":["bzz-raw://c41c45c0e3a7cf4e90572b8fe1e4cfda5ef1d8eb6fd784ac6785cfd118dc76e0","dweb:/ipfs/Qma2w5HheMQhKVPXPj9qSyNkjXvYVSBhcBVR3P5EZaMr2b"],"license":"Apache 2"},"src/express-relay/Helpers.sol":{"keccak256":"0xf2a2893c2d46e816e033bfaa6a933027ba0648b654e4c03372a714e830b760e0","urls":["bzz-raw://3c8e0be649b61bc8e27a818c4bff9288981d29c602ed506193d7b5a2baf3faaa","dweb:/ipfs/QmP3xVcC1SQKxtjgc3LVjHjZKTzEqax3NZfgdeNFhVSkUL"],"license":"Apache 2"},"src/express-relay/State.sol":{"keccak256":"0xbd12dc956ed2d96cf964a510fa59a6eacb381d77e5fbc2e65c68c99a22692390","urls":["bzz-raw://f14f09cf1c5c3760d520f33ba493de93e59afc9395e6d455211672350a158145","dweb:/ipfs/QmXWT3Ks6GBPAyEzy1ErXnbHkKsB5yqNdTtcYhyoDReQdn"],"license":"Apache 2"},"src/express-relay/Structs.sol":{"keccak256":"0x17d0b684650532efe556ac33cc74b9fe6befba7abbcd29f4af1415058b736453","urls":["bzz-raw://ee60a5e5e3ee4955b7fb4b0f90fdf438955988bb58659f25c3ed08bff23bbdb4","dweb:/ipfs/Qmbj5QxUX2spunScm7Meov8WbbEjz2nwWALFGKJCJr2RK6"],"license":"Apache 2"}},"version":1},"id":78} \ No newline at end of file diff --git a/sdk/rust/abi/OpportunityAdapter.sol/OpportunityAdapter.json b/sdk/rust/abi/OpportunityAdapter.sol/OpportunityAdapter.json new file mode 100644 index 00000000..5b9726a3 --- /dev/null +++ b/sdk/rust/abi/OpportunityAdapter.sol/OpportunityAdapter.json @@ -0,0 +1 @@ +{"abi":[{"type":"constructor","inputs":[],"stateMutability":"nonpayable"},{"type":"receive","stateMutability":"payable"},{"type":"function","name":"WITNESS_TYPE_STRING","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"type":"function","name":"executeOpportunity","inputs":[{"name":"params","type":"tuple","internalType":"struct ExecutionParams","components":[{"name":"permit","type":"tuple","internalType":"struct ISignatureTransfer.PermitBatchTransferFrom","components":[{"name":"permitted","type":"tuple[]","internalType":"struct ISignatureTransfer.TokenPermissions[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"}]},{"name":"nonce","type":"uint256","internalType":"uint256"},{"name":"deadline","type":"uint256","internalType":"uint256"}]},{"name":"witness","type":"tuple","internalType":"struct ExecutionWitness","components":[{"name":"buyTokens","type":"tuple[]","internalType":"struct TokenAmount[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"}]},{"name":"executor","type":"address","internalType":"address"},{"name":"targetContract","type":"address","internalType":"address"},{"name":"targetCalldata","type":"bytes","internalType":"bytes"},{"name":"targetCallValue","type":"uint256","internalType":"uint256"},{"name":"bidAmount","type":"uint256","internalType":"uint256"}]}]},{"name":"signature","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"getExpressRelay","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"getOwner","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"getWeth","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"hash","inputs":[{"name":"params","type":"tuple","internalType":"struct ExecutionWitness","components":[{"name":"buyTokens","type":"tuple[]","internalType":"struct TokenAmount[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"}]},{"name":"executor","type":"address","internalType":"address"},{"name":"targetContract","type":"address","internalType":"address"},{"name":"targetCalldata","type":"bytes","internalType":"bytes"},{"name":"targetCallValue","type":"uint256","internalType":"uint256"},{"name":"bidAmount","type":"uint256","internalType":"uint256"}]}],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"pure"},{"type":"function","name":"version","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"pure"},{"type":"function","name":"withdrawEth","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"withdrawToken","inputs":[{"name":"token","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"error","name":"AdapterOwnerMismatch","inputs":[]},{"type":"error","name":"AddressEmptyCode","inputs":[{"name":"target","type":"address","internalType":"address"}]},{"type":"error","name":"AddressInsufficientBalance","inputs":[{"name":"account","type":"address","internalType":"address"}]},{"type":"error","name":"DuplicateToken","inputs":[]},{"type":"error","name":"EthOrWethBalanceDecreased","inputs":[]},{"type":"error","name":"FailedInnerCall","inputs":[]},{"type":"error","name":"InsufficientEthToSettleBid","inputs":[]},{"type":"error","name":"InsufficientTokenReceived","inputs":[]},{"type":"error","name":"InsufficientWethForTargetCallValue","inputs":[]},{"type":"error","name":"NotCalledByFactory","inputs":[]},{"type":"error","name":"OnlyOwnerCanCall","inputs":[]},{"type":"error","name":"ReentrancyGuardReentrantCall","inputs":[]},{"type":"error","name":"SafeERC20FailedOperation","inputs":[{"name":"token","type":"address","internalType":"address"}]},{"type":"error","name":"TargetCallFailed","inputs":[{"name":"returnData","type":"bytes","internalType":"bytes"}]},{"type":"error","name":"TargetContractNotAllowed","inputs":[]}],"bytecode":{"object":"0x610120806040523462000171575f60018155608091338352630890357360e41b81528281600481335afa908115620001665782918391848092620000c6575b505060a05261010092835260e05260c052604051906119e292836200018b843951826103a1015260a05182818160e1015281816101ac0152818161026601526103f4015260c051828181609c015261157e015260e051828181610c0801528181610eba01528181611546015261168c0152518181816104330152818161070101526108540152f35b935093505050823d84116200015e575b601f8101601f191683016001600160401b038111848210176200014a5784918491604052810103126200014757506200010f8162000175565b906200011e6020820162000175565b906200013b6060620001336040840162000175565b920162000175565b929190925f806200003e565b80fd5b634e487b7160e01b83526041600452602483fd5b503d620000d6565b6040513d84823e3d90fd5b5f80fd5b51906001600160a01b0382168203620001715756fe608080604052600436101561001c575b50361561001a575f80fd5b005b5f90813560e01c908163107c279f14610ea657508063156e215214610e765780632608ba811461032257806354fd4d50146102d85780636184196a14610295578063893d20e8146102505780638947606914610182578063a0ef91df146100ce5763c9b4518a0361000f57346100cb57806003193601126100cb576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b80fd5b50346100cb57806003193601126100cb577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163381900361017057818080809347905af1610122611295565b501561012b5780f35b60405162461bcd60e51b815260206004820152601860248201527f5769746864726177616c206f6620455448206661696c656400000000000000006044820152606490fd5b6040516308f51d4b60e31b8152600490fd5b50346100cb5760203660031901126100cb576001600160a01b0360043581811690819003610239577f00000000000000000000000000000000000000000000000000000000000000009182163303610170576040516370a0823160e01b815230600482015291602083602481855afa91821561024557849261020c575b61020993506112c4565b80f35b91506020833d821161023d575b8161022660209383610f4a565b81010312610239576102099251916101ff565b5f80fd5b3d9150610219565b6040513d86823e3d90fd5b50346100cb57806003193601126100cb576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b50346100cb5760203660031901126100cb57600435906001600160401b0382116100cb5760206102d06102cb3660048601611153565b611702565b604051908152f35b50346100cb57806003193601126100cb5761031e6040516102f881610eed565b60058152640302e322e360dc1b60208201526040519182916020835260208301906110ea565b0390f35b5060403660031901126100cb57600435906001600160401b0382116100cb57604060031983360301126100cb576001600160401b03602435116100cb573660236024350112156100cb576001600160401b0360243560040135116100cb5736602480356004013581350101116100cb576002815414610e6457600281557f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163303610e52576103ea60206103e460248501856004016113ee565b0161144d565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116911603610e405761043160406103e460248501856004016113ee565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b039081169116148015610e1a575b610e085761048a61048461047e6004850180611438565b80611403565b90611493565b6104a061048461047e60248501856004016113ee565b6104a861166f565b6104be61047e60248695949501866004016113ee565b6104c781611128565b916104d56040519384610f4a565b818352601f196104e483611128565b01366020850137845b828110610d6757506105059150506004860180611438565b9161051660248701876004016113ee565b916105218480611403565b97905061054661053089611128565b9861053e6040519a8b610f4a565b808a52611128565b865b601f1982018110610d44575050855b6105618680611403565b90508110156106d6578060206105846106509361057e8a80611403565b9061146f565b0135816105ab6105a66105978b80611403565b6001600160a01b03949161146f565b61144d565b168b6105cc84604051926105be84610eed565b308452856020850152611527565b526105d7838d611527565b506105e46040890161144d565b60405163095ea7b360e01b602082018181526001600160a01b038416602484015260448084019690965294825293909291908c908190610625606487610f4a565b85519082865af1610634611295565b816106a7575b508061069d575b15610655575b50505050611461565b610557565b60405160208101949094526001600160a01b0316602484015260448084018c905283526106949261068f9061068981610f2f565b8261131a565b61131a565b5f808080610647565b50813b1515610641565b80518015925082156106bc575b50505f61063a565b6106cf9250602080918301019101611302565b5f806106b4565b508686868a876106f66102cb6106ee6020840161144d565b923690611153565b6106fe610f86565b917f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163b15610d405760405163fe8ec1a760e01b815260c060048201529480359036819003601e1901821215610d3c576001600160401b038183013511610d3c578082013560061b360360208284010113610d3c579187959391879593606060c4880152610124870181830135905261014487019160208282010190895b838201358110610cf657505050806020604092013560e4890152013561010487015260031986820301602487015260208086519283815201950190875b818110610cc5575050506001600160a01b031660448501526064840152828203600319016084840152602091839161081991906110ea565b6003198282030160a4830152602480356004810135808452910184830137600460243501358181018401869052601f01601f191601030181837f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af18015610cba57610cab575b5090608061089d60248501856004016113ee565b0135610c06575b6108b960406103e460248601866004016113ee565b6108c960248501856004016113ee565b606081013590601e1981360301821215610c0257018035906001600160401b038211610c02576020018136038113610c0257918492918392608061091360248a018a6004016113ee565b013590826040519384928337810185815203925af1610930611295565b9015610bd957506109446004840180611438565b9461095a60406103e460248701876004016113ee565b93835b6109678880611403565b9050811015610a5e57806109e7916109856105a66105978c80611403565b1660405160208101915f8063095ea7b360e01b9485815260018060a01b038d166024860152816044860152604485526109bd85610f2f565b84519082855af16109cc611295565b81610a2f575b5080610a25575b156109ec575b505050611461565b61095d565b61068f610a1d9360405190602082015260018060a01b038c1660248201525f60448201526044815261068981610f2f565b8980806109df565b50803b15156109d9565b8051801592508215610a44575b50508d6109d2565b610a579250602080918301019101611302565b8d80610a3c565b506103e486610a7f60a0610a7860248601866004016113ee565b013561153b565b610aa76020610a9761047e60248701876004016113ee565b94909560248101906004016113ee565b92865b838110610aef57878787610abc61166f565b9211918215610ae5575b5050610ad3576001815580f35b604051631979776d60e01b8152600490fd5b1090508280610ac6565b6001600160a01b03610b056105a683878661146f565b6040516370a0823160e01b8152306004820152929116602083602481845afa928315610bce578a93610b9a575b50610b3d8286611527565b516020610b4b84898861146f565b01358101809111610b86578310610b7457610b6f9287610b6a926112c4565b611461565b610aaa565b604051632578a3d560e11b8152600490fd5b634e487b7160e01b5f52601160045260245ffd5b9092506020813d602011610bc6575b81610bb660209383610f4a565b810103126102395751918a610b32565b3d9150610ba9565b6040513d8c823e3d90fd5b60405163549964bd60e11b815260206004820152908190610bfe9060248301906110ea565b0390fd5b8480fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166080610c4260248601600487016113ee565b0135813b15610ca757838092602482936040519586938492632e1a7d4d60e01b845260048401525af19182610c8f575b5050610c8a57604051631794833560e21b8152600490fd5b6108a4565b610c9890610f1c565b610ca3578287610c72565b8280fd5b8380fd5b610cb490610f1c565b85610889565b6040513d84823e3d90fd5b825180516001600160a01b03168852602090810151818901528b99508a9850604090970196909201916001016107e1565b929496985092849195979950604080600192838060a01b03610d178a61113f565b1681526020890135602082015201960192018a98969450928b999795939291926107a4565b8780fd5b8580fd5b602090604051610d5381610eed565b898152898382015282828d01015201610548565b60249060206001600160a01b03610d826105a684888861146f565b16604051938480926370a0823160e01b82523060048301525afa8015610dfd578790610dc3575b610dbe9250610db88287611527565b52611461565b6104ed565b50906020813d602011610df5575b81610dde60209383610f4a565b81010312610df15790610dbe9151610da9565b8680fd5b3d9150610dd1565b6040513d89823e3d90fd5b604051634e4372cf60e11b8152600490fd5b50610e3060406103e460248501856004016113ee565b6001600160a01b03163014610467565b60405163446f3eeb60e01b8152600490fd5b604051632c090db360e21b8152600490fd5b604051633ee5aeb560e01b8152600490fd5b50346100cb57806003193601126100cb5761031e610e92610f86565b6040519182916020835260208301906110ea565b905034610ee95781600319360112610ee9577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5080fd5b604081019081106001600160401b03821117610f0857604052565b634e487b7160e01b5f52604160045260245ffd5b6001600160401b038111610f0857604052565b608081019081106001600160401b03821117610f0857604052565b90601f801991011681019081106001600160401b03821117610f0857604052565b6001600160401b038111610f0857601f01601f191660200190565b6040519061014082018281106001600160401b03821117610f0857604052610104825263756e742960e01b610120837f4f70706f7274756e6974795769746e657373207769746e657373294f70706f7260208201527f74756e6974795769746e65737328546f6b656e416d6f756e745b5d206275795460408201527f6f6b656e732c61646472657373206578656375746f722c61646472657373207460608201527f6172676574436f6e74726163742c62797465732074617267657443616c6c646160808201527f74612c75696e743235362074617267657443616c6c56616c75652c75696e743260a08201527f353620626964416d6f756e7429546f6b656e416d6f756e74286164647265737360c08201527f20746f6b656e2c75696e7432353620616d6f756e7429546f6b656e5065726d6960e08201527f7373696f6e73286164647265737320746f6b656e2c75696e7432353620616d6f6101008201520152565b91908251928382525f5b848110611114575050825f602080949584010152601f8019910116010190565b6020818301810151848301820152016110f4565b6001600160401b038111610f085760051b60200190565b35906001600160a01b038216820361023957565b919060c0838203126102395760409283519160c08301916001600160401b039284811084821117610f08578652839581358481116102395782019383601f86011215610239578435946111a586611128565b906111b284519283610f4a565b868252602096878084019160061b83010191878311610239578801905b8282106112605750505086526111e685840161113f565b858701526111f582840161113f565b82870152606083013590811161023957820183601f820112156102395780359361122a61122186610f6b565b93519384610f4a565b84835285858301011161023957848460a0969587965f940183860137830101526060850152608081013560808501520135910152565b858289031261023957888691825161127781610eed565b6112808561113f565b815282850135838201528152019101906111cf565b3d156112bf573d906112a682610f6b565b916112b46040519384610f4a565b82523d5f602084013e565b606090565b60405163a9059cbb60e01b60208201526001600160a01b039290921660248301526044808301939093529181526113009161068f606483610f4a565b565b90816020910312610239575180151581036102395790565b5f806113429260018060a01b03169360208151910182865af161133b611295565b908361138b565b8051908115159182611370575b50506113585750565b60249060405190635274afe760e01b82526004820152fd5b6113839250602080918301019101611302565b155f8061134f565b906113b257508051156113a057805190602001fd5b604051630a12f52160e11b8152600490fd5b815115806113e5575b6113c3575090565b604051639996b31560e01b81526001600160a01b039091166004820152602490fd5b50803b156113bb565b90359060be1981360301821215610239570190565b903590601e198136030182121561023957018035906001600160401b03821161023957602001918160061b3603831361023957565b903590605e1981360301821215610239570190565b356001600160a01b03811681036102395790565b5f198114610b865760010190565b919081101561147f5760061b0190565b634e487b7160e01b5f52603260045260245ffd5b5f90815b8381106114a45750505050565b60018101808211611513575b8481106114c657506114c190611461565b611497565b6114d46105a683878661146f565b6001600160a01b03806114eb6105a6858a8961146f565b16911614611501576114fc90611461565b6114b0565b6040516323271fb560e11b8152600490fd5b634e487b7160e01b84526011600452602484fd5b805182101561147f5760209160051b010190565b5f90801561166b57817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031647838110611600575b50508080927f00000000000000000000000000000000000000000000000000000000000000005af16115a7611295565b50156115af57565b60405162461bcd60e51b8152602060048201526024808201527f426964207472616e7366657220746f20657870726573732072656c61792066616044820152631a5b195960e21b6064820152608490fd5b909150820382811161151357813b15610ca7578391602483926040519485938492632e1a7d4d60e01b845260048401525af19081611658575b5061165057604051632031c40f60e11b8152600490fd5b818080611577565b61166490939193610f1c565b915f611639565b5050565b6040516370a0823160e01b815230600482015290476020836024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa9283156116f7575f936116c857509190565b90926020823d82116116ef575b816116e260209383610f4a565b810103126100cb57505190565b3d91506116d5565b6040513d5f823e3d90fd5b604091825160e081016001600160401b039082811082821117610f0857855260bb8252602060bb8184017f4f70706f7274756e6974795769746e65737328546f6b656e416d6f756e745b5d81527f20627579546f6b656e732c61646472657373206578656375746f722c61646472888601527f647265737320746f6b656e2c75696e7432353620616d6f756e7429000000000060c06060967f65737320746172676574436f6e74726163742c62797465732074617267657443888201527f616c6c646174612c75696e743235362074617267657443616c6c56616c75652c60808201527f75696e7432353620626964416d6f756e7429546f6b656e416d6f756e7428616460a08201520152209385519081519561183661182188611128565b9761182e8b51998a610f4a565b808952611128565b97848801601f19809a013682375f5b85518110156118ef576118588187611527565b51908c51918a83018381108b821117610f08576118ea938f918252602990818152683620616d6f756e742960b81b838d8301927f546f6b656e416d6f756e74286164647265737320746f6b656e2c75696e7432358452015220918a60018060a01b03825116910151908251928c84019485528301528c8201528b81526118dd81610f2f565b519020610db8828d611527565b611845565b5090935098949593969198979097855191828981018095519093905f5b8c82821061199557505050506119289203908101835282610f4a565b5190209160018060a01b0380878401511690858401511690828401518881519101209260a06080860151950151958751998a019a8b52878a0152880152608087015260a086015260c085015260e084015260e0835261010083019183831090831117610f08575251902090565b83518752958601958794509092019160010161190c56fea2646970667358221220797322f89790945f9447121f12f2c5f8b9fb27cdcaa77d6df10908917f7348ed64736f6c63430008140033","sourceMap":"605:9234:87:-:0;;;;;;;1917:21:56;1713:1;;;1360:39:87;1389:10;;1360:39;;605:9234;;;1452:73;;1389:10;;1452:73;1389:10;;1452:73;;;;;;;;1917:21:56;;;;;1452:73:87;;;-1:-1:-1;1409:116:87;;;;;;;;605:9234;1409:116;;;605:9234;;;;;;;;;;;;;;1409:116;605:9234;;;;;;;;;;;;;;;;;;;;1409:116;605:9234;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1452:73;;;;;;;;;;;;;;605:9234;;;-1:-1:-1;;605:9234:87;;;-1:-1:-1;;;;;605:9234:87;;;;;;;;;;;;;;1452:73;;605:9234;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;:::i;:::-;1452:73;;;;;;;;605:9234;;;;-1:-1:-1;;;605:9234:87;;;1452:73;605:9234;;;;1452:73;;;;;;605:9234;;;;;;;;;;;;;;;;-1:-1:-1;;;;;605:9234:87;;;;;;:::o","linkReferences":{}},"deployedBytecode":{"object":"0x608080604052600436101561001c575b50361561001a575f80fd5b005b5f90813560e01c908163107c279f14610ea657508063156e215214610e765780632608ba811461032257806354fd4d50146102d85780636184196a14610295578063893d20e8146102505780638947606914610182578063a0ef91df146100ce5763c9b4518a0361000f57346100cb57806003193601126100cb576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b80fd5b50346100cb57806003193601126100cb577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163381900361017057818080809347905af1610122611295565b501561012b5780f35b60405162461bcd60e51b815260206004820152601860248201527f5769746864726177616c206f6620455448206661696c656400000000000000006044820152606490fd5b6040516308f51d4b60e31b8152600490fd5b50346100cb5760203660031901126100cb576001600160a01b0360043581811690819003610239577f00000000000000000000000000000000000000000000000000000000000000009182163303610170576040516370a0823160e01b815230600482015291602083602481855afa91821561024557849261020c575b61020993506112c4565b80f35b91506020833d821161023d575b8161022660209383610f4a565b81010312610239576102099251916101ff565b5f80fd5b3d9150610219565b6040513d86823e3d90fd5b50346100cb57806003193601126100cb576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b50346100cb5760203660031901126100cb57600435906001600160401b0382116100cb5760206102d06102cb3660048601611153565b611702565b604051908152f35b50346100cb57806003193601126100cb5761031e6040516102f881610eed565b60058152640302e322e360dc1b60208201526040519182916020835260208301906110ea565b0390f35b5060403660031901126100cb57600435906001600160401b0382116100cb57604060031983360301126100cb576001600160401b03602435116100cb573660236024350112156100cb576001600160401b0360243560040135116100cb5736602480356004013581350101116100cb576002815414610e6457600281557f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163303610e52576103ea60206103e460248501856004016113ee565b0161144d565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116911603610e405761043160406103e460248501856004016113ee565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b039081169116148015610e1a575b610e085761048a61048461047e6004850180611438565b80611403565b90611493565b6104a061048461047e60248501856004016113ee565b6104a861166f565b6104be61047e60248695949501866004016113ee565b6104c781611128565b916104d56040519384610f4a565b818352601f196104e483611128565b01366020850137845b828110610d6757506105059150506004860180611438565b9161051660248701876004016113ee565b916105218480611403565b97905061054661053089611128565b9861053e6040519a8b610f4a565b808a52611128565b865b601f1982018110610d44575050855b6105618680611403565b90508110156106d6578060206105846106509361057e8a80611403565b9061146f565b0135816105ab6105a66105978b80611403565b6001600160a01b03949161146f565b61144d565b168b6105cc84604051926105be84610eed565b308452856020850152611527565b526105d7838d611527565b506105e46040890161144d565b60405163095ea7b360e01b602082018181526001600160a01b038416602484015260448084019690965294825293909291908c908190610625606487610f4a565b85519082865af1610634611295565b816106a7575b508061069d575b15610655575b50505050611461565b610557565b60405160208101949094526001600160a01b0316602484015260448084018c905283526106949261068f9061068981610f2f565b8261131a565b61131a565b5f808080610647565b50813b1515610641565b80518015925082156106bc575b50505f61063a565b6106cf9250602080918301019101611302565b5f806106b4565b508686868a876106f66102cb6106ee6020840161144d565b923690611153565b6106fe610f86565b917f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163b15610d405760405163fe8ec1a760e01b815260c060048201529480359036819003601e1901821215610d3c576001600160401b038183013511610d3c578082013560061b360360208284010113610d3c579187959391879593606060c4880152610124870181830135905261014487019160208282010190895b838201358110610cf657505050806020604092013560e4890152013561010487015260031986820301602487015260208086519283815201950190875b818110610cc5575050506001600160a01b031660448501526064840152828203600319016084840152602091839161081991906110ea565b6003198282030160a4830152602480356004810135808452910184830137600460243501358181018401869052601f01601f191601030181837f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af18015610cba57610cab575b5090608061089d60248501856004016113ee565b0135610c06575b6108b960406103e460248601866004016113ee565b6108c960248501856004016113ee565b606081013590601e1981360301821215610c0257018035906001600160401b038211610c02576020018136038113610c0257918492918392608061091360248a018a6004016113ee565b013590826040519384928337810185815203925af1610930611295565b9015610bd957506109446004840180611438565b9461095a60406103e460248701876004016113ee565b93835b6109678880611403565b9050811015610a5e57806109e7916109856105a66105978c80611403565b1660405160208101915f8063095ea7b360e01b9485815260018060a01b038d166024860152816044860152604485526109bd85610f2f565b84519082855af16109cc611295565b81610a2f575b5080610a25575b156109ec575b505050611461565b61095d565b61068f610a1d9360405190602082015260018060a01b038c1660248201525f60448201526044815261068981610f2f565b8980806109df565b50803b15156109d9565b8051801592508215610a44575b50508d6109d2565b610a579250602080918301019101611302565b8d80610a3c565b506103e486610a7f60a0610a7860248601866004016113ee565b013561153b565b610aa76020610a9761047e60248701876004016113ee565b94909560248101906004016113ee565b92865b838110610aef57878787610abc61166f565b9211918215610ae5575b5050610ad3576001815580f35b604051631979776d60e01b8152600490fd5b1090508280610ac6565b6001600160a01b03610b056105a683878661146f565b6040516370a0823160e01b8152306004820152929116602083602481845afa928315610bce578a93610b9a575b50610b3d8286611527565b516020610b4b84898861146f565b01358101809111610b86578310610b7457610b6f9287610b6a926112c4565b611461565b610aaa565b604051632578a3d560e11b8152600490fd5b634e487b7160e01b5f52601160045260245ffd5b9092506020813d602011610bc6575b81610bb660209383610f4a565b810103126102395751918a610b32565b3d9150610ba9565b6040513d8c823e3d90fd5b60405163549964bd60e11b815260206004820152908190610bfe9060248301906110ea565b0390fd5b8480fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166080610c4260248601600487016113ee565b0135813b15610ca757838092602482936040519586938492632e1a7d4d60e01b845260048401525af19182610c8f575b5050610c8a57604051631794833560e21b8152600490fd5b6108a4565b610c9890610f1c565b610ca3578287610c72565b8280fd5b8380fd5b610cb490610f1c565b85610889565b6040513d84823e3d90fd5b825180516001600160a01b03168852602090810151818901528b99508a9850604090970196909201916001016107e1565b929496985092849195979950604080600192838060a01b03610d178a61113f565b1681526020890135602082015201960192018a98969450928b999795939291926107a4565b8780fd5b8580fd5b602090604051610d5381610eed565b898152898382015282828d01015201610548565b60249060206001600160a01b03610d826105a684888861146f565b16604051938480926370a0823160e01b82523060048301525afa8015610dfd578790610dc3575b610dbe9250610db88287611527565b52611461565b6104ed565b50906020813d602011610df5575b81610dde60209383610f4a565b81010312610df15790610dbe9151610da9565b8680fd5b3d9150610dd1565b6040513d89823e3d90fd5b604051634e4372cf60e11b8152600490fd5b50610e3060406103e460248501856004016113ee565b6001600160a01b03163014610467565b60405163446f3eeb60e01b8152600490fd5b604051632c090db360e21b8152600490fd5b604051633ee5aeb560e01b8152600490fd5b50346100cb57806003193601126100cb5761031e610e92610f86565b6040519182916020835260208301906110ea565b905034610ee95781600319360112610ee9577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5080fd5b604081019081106001600160401b03821117610f0857604052565b634e487b7160e01b5f52604160045260245ffd5b6001600160401b038111610f0857604052565b608081019081106001600160401b03821117610f0857604052565b90601f801991011681019081106001600160401b03821117610f0857604052565b6001600160401b038111610f0857601f01601f191660200190565b6040519061014082018281106001600160401b03821117610f0857604052610104825263756e742960e01b610120837f4f70706f7274756e6974795769746e657373207769746e657373294f70706f7260208201527f74756e6974795769746e65737328546f6b656e416d6f756e745b5d206275795460408201527f6f6b656e732c61646472657373206578656375746f722c61646472657373207460608201527f6172676574436f6e74726163742c62797465732074617267657443616c6c646160808201527f74612c75696e743235362074617267657443616c6c56616c75652c75696e743260a08201527f353620626964416d6f756e7429546f6b656e416d6f756e74286164647265737360c08201527f20746f6b656e2c75696e7432353620616d6f756e7429546f6b656e5065726d6960e08201527f7373696f6e73286164647265737320746f6b656e2c75696e7432353620616d6f6101008201520152565b91908251928382525f5b848110611114575050825f602080949584010152601f8019910116010190565b6020818301810151848301820152016110f4565b6001600160401b038111610f085760051b60200190565b35906001600160a01b038216820361023957565b919060c0838203126102395760409283519160c08301916001600160401b039284811084821117610f08578652839581358481116102395782019383601f86011215610239578435946111a586611128565b906111b284519283610f4a565b868252602096878084019160061b83010191878311610239578801905b8282106112605750505086526111e685840161113f565b858701526111f582840161113f565b82870152606083013590811161023957820183601f820112156102395780359361122a61122186610f6b565b93519384610f4a565b84835285858301011161023957848460a0969587965f940183860137830101526060850152608081013560808501520135910152565b858289031261023957888691825161127781610eed565b6112808561113f565b815282850135838201528152019101906111cf565b3d156112bf573d906112a682610f6b565b916112b46040519384610f4a565b82523d5f602084013e565b606090565b60405163a9059cbb60e01b60208201526001600160a01b039290921660248301526044808301939093529181526113009161068f606483610f4a565b565b90816020910312610239575180151581036102395790565b5f806113429260018060a01b03169360208151910182865af161133b611295565b908361138b565b8051908115159182611370575b50506113585750565b60249060405190635274afe760e01b82526004820152fd5b6113839250602080918301019101611302565b155f8061134f565b906113b257508051156113a057805190602001fd5b604051630a12f52160e11b8152600490fd5b815115806113e5575b6113c3575090565b604051639996b31560e01b81526001600160a01b039091166004820152602490fd5b50803b156113bb565b90359060be1981360301821215610239570190565b903590601e198136030182121561023957018035906001600160401b03821161023957602001918160061b3603831361023957565b903590605e1981360301821215610239570190565b356001600160a01b03811681036102395790565b5f198114610b865760010190565b919081101561147f5760061b0190565b634e487b7160e01b5f52603260045260245ffd5b5f90815b8381106114a45750505050565b60018101808211611513575b8481106114c657506114c190611461565b611497565b6114d46105a683878661146f565b6001600160a01b03806114eb6105a6858a8961146f565b16911614611501576114fc90611461565b6114b0565b6040516323271fb560e11b8152600490fd5b634e487b7160e01b84526011600452602484fd5b805182101561147f5760209160051b010190565b5f90801561166b57817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031647838110611600575b50508080927f00000000000000000000000000000000000000000000000000000000000000005af16115a7611295565b50156115af57565b60405162461bcd60e51b8152602060048201526024808201527f426964207472616e7366657220746f20657870726573732072656c61792066616044820152631a5b195960e21b6064820152608490fd5b909150820382811161151357813b15610ca7578391602483926040519485938492632e1a7d4d60e01b845260048401525af19081611658575b5061165057604051632031c40f60e11b8152600490fd5b818080611577565b61166490939193610f1c565b915f611639565b5050565b6040516370a0823160e01b815230600482015290476020836024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa9283156116f7575f936116c857509190565b90926020823d82116116ef575b816116e260209383610f4a565b810103126100cb57505190565b3d91506116d5565b6040513d5f823e3d90fd5b604091825160e081016001600160401b039082811082821117610f0857855260bb8252602060bb8184017f4f70706f7274756e6974795769746e65737328546f6b656e416d6f756e745b5d81527f20627579546f6b656e732c61646472657373206578656375746f722c61646472888601527f647265737320746f6b656e2c75696e7432353620616d6f756e7429000000000060c06060967f65737320746172676574436f6e74726163742c62797465732074617267657443888201527f616c6c646174612c75696e743235362074617267657443616c6c56616c75652c60808201527f75696e7432353620626964416d6f756e7429546f6b656e416d6f756e7428616460a08201520152209385519081519561183661182188611128565b9761182e8b51998a610f4a565b808952611128565b97848801601f19809a013682375f5b85518110156118ef576118588187611527565b51908c51918a83018381108b821117610f08576118ea938f918252602990818152683620616d6f756e742960b81b838d8301927f546f6b656e416d6f756e74286164647265737320746f6b656e2c75696e7432358452015220918a60018060a01b03825116910151908251928c84019485528301528c8201528b81526118dd81610f2f565b519020610db8828d611527565b611845565b5090935098949593969198979097855191828981018095519093905f5b8c82821061199557505050506119289203908101835282610f4a565b5190209160018060a01b0380878401511690858401511690828401518881519101209260a06080860151950151958751998a019a8b52878a0152880152608087015260a086015260c085015260e084015260e0835261010083019183831090831117610f08575251902090565b83518752958601958794509092019160010161190c56fea2646970667358221220797322f89790945f9447121f12f2c5f8b9fb27cdcaa77d6df10908917f7348ed64736f6c63430008140033","sourceMap":"605:9234:87:-:0;;;;;;;;;;-1:-1:-1;605:9234:87;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2067:13;-1:-1:-1;;;;;605:9234:87;;;;;;;;;;;;;;;;;;;;;;1587:6;-1:-1:-1;;;;;605:9234:87;1573:10;:20;;;1569:76;;2498:21;;;;;;2470:54;;;;;:::i;:::-;;605:9234;;;;;;;;-1:-1:-1;;;605:9234:87;;;;;;;;;;;;;;;;;;;;1569:76;605:9234;;-1:-1:-1;;;1616:18:87;;605:9234;;1616:18;605:9234;;;;;;;-1:-1:-1;;605:9234:87;;;;-1:-1:-1;;;;;605:9234:87;;;;;;;;;;;1587:6;605:9234;;;1573:10;:20;1569:76;;605:9234;;-1:-1:-1;;;2888:38:87;;2920:4;605:9234;2888:38;;605:9234;;;;;;2888:38;;;;;;;;;;;;605:9234;2888:38;;;;:::i;:::-;605:9234;;2888:38;;;605:9234;2888:38;;;;;;;;;605:9234;2888:38;;;:::i;:::-;;;605:9234;;;;2888:38;605:9234;;2888:38;;;605:9234;;;;2888:38;;;-1:-1:-1;2888:38:87;;;605:9234;;;;;;;;;;;;;;;;;;;;;;;;1835:6;-1:-1:-1;;;;;605:9234:87;;;;;;;;;;;;;-1:-1:-1;;605:9234:87;;;;;;;-1:-1:-1;;;;;605:9234:87;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;;605:9234:87;;;;;;;;;;;;;;;;;:::i;:::-;;;;;-1:-1:-1;605:9234:87;;-1:-1:-1;;605:9234:87;;;;;;;-1:-1:-1;;;;;605:9234:87;;;;;;;;;;;;;;-1:-1:-1;;;;;605:9234:87;;;;;;;;;;;;;;-1:-1:-1;;;;;605:9234:87;;;;;;;;;;;;;;;;;;;;;;1755:1:56;605:9234:87;;2558:18:56;2554:86;;1755:1;;;8040:26:87;-1:-1:-1;;;;;605:9234:87;8026:10;:40;8022:98;;3144:23;605:9234;3144:14;605:9234;3144:14;;605:9234;;;3144:14;:::i;:::-;:23;;:::i;:::-;-1:-1:-1;;;;;3171:6:87;605:9234;;;;3144:33;3140:93;;3259:29;605:9234;3259:14;605:9234;3144:14;;605:9234;;;3259:14;:::i;:29::-;3292:8;-1:-1:-1;;;;;605:9234:87;;;;;3259:41;:103;;;;605:9234;3242:189;;3462:23;;:13;605:9234;;;;3462:13;:::i;:::-;:23;;:::i;:::-;;;:::i;:::-;3518:24;;:14;605:9234;3144:14;;605:9234;;;3518:14;:::i;:24::-;8258;;:::i;:::-;8494;:14;605:9234;3144:14;;;;;605:9234;;;8494:14;:::i;:24::-;605:9234;;;:::i;:::-;;;;;;;;:::i;:::-;;;;-1:-1:-1;;605:9234:87;;;:::i;:::-;;;;;;;6834:10;6846:17;;;;;;-1:-1:-1;8561:13:87;;-1:-1:-1;;605:9234:87;;;;8561:13;:::i;:::-;3144:14;8576;605:9234;3144:14;;605:9234;;;8576:14;:::i;:::-;4644:16;;;;;:::i;:::-;605:9234;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;:::i;:::-;;;-1:-1:-1;;605:9234:87;;;;;;4696:10;;;4737:3;4712:16;;;;:::i;:::-;4708:27;;;;;;;4773:16;605:9234;4773:19;4737:3;4773:16;;;;;:::i;:::-;:19;;:::i;:::-;:26;605:9234;4835:16;:25;:19;:16;;;;:::i;:::-;-1:-1:-1;;;;;605:9234:87;;4835:19;:::i;:::-;:25;:::i;:::-;605:9234;;4875:156;605:9234;;;;;;;:::i;:::-;6979:4;605:9234;;4896:135;605:9234;4896:135;;605:9234;4875:156;:::i;:::-;;;;;;:::i;:::-;;5064:22;605:9234;5064:22;;;:::i;:::-;605:9234;;-1:-1:-1;;;605:9234:87;3411:47:52;;;;;-1:-1:-1;;;;;605:9234:87;;;3411:47:52;;605:9234:87;;;;;;;;;3411:47:52;;;605:9234:87;;;;;3411:47:52;;;;;605:9234:87;;3411:47:52;:::i;:::-;5615:25;;;;;;;;;:::i;:::-;5657:69;;;4737:3:87;5657:103:52;;;;4737:3:87;3473:45:52;3469:201;;4737:3:87;;;;;;:::i;:::-;4696:10;;3469:201:52;605:9234:87;;;3561:43:52;;;;;;-1:-1:-1;;;;;605:9234:87;;3561:43:52;;605:9234:87;;;;;;;;3561:43:52;;3646:12;;3561:43;;;605:9234:87;3561:43:52;:::i;:::-;;;:::i;:::-;3646:12;:::i;:::-;3469:201;;;;;;5657:103;5730:26;;;:30;;5657:103;;:69;605:9234:87;;5669:22:52;;;-1:-1:-1;5669:56:52;;;;5657:69;;;;;;5669:56;5695:30;;;605:9234:87;5695:30:52;;;;;;;;:::i;:::-;5669:56;;;;4708:27:87;;;;;;;5262:13;605:9234;5232:16;605:9234;5232:16;;;:::i;:::-;605:9234;;;;:::i;5262:13::-;605:9234;;:::i;:::-;;3292:8;-1:-1:-1;;;;;605:9234:87;5115:226;;;;605:9234;;-1:-1:-1;;;5115:226:87;;605:9234;;5115:226;;605:9234;;;;;;;;;-1:-1:-1;;605:9234:87;;;;;;-1:-1:-1;;;;;605:9234:87;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;605:9234:87;;;;;;;;;;;;-1:-1:-1;;605:9234:87;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;605:9234:87;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;605:9234:87;;5115:226;;605:9234;;3292:8;-1:-1:-1;;;;;605:9234:87;5115:226;;;;;;;;605:9234;3144:14;;605:9234;8616:14;605:9234;3144:14;;605:9234;;;8616:14;:::i;:::-;:30;605:9234;8612:245;;605:9234;8899:29;605:9234;8899:14;605:9234;3144:14;;605:9234;;;8899:14;:::i;:29::-;8942:14;605:9234;3144:14;;605:9234;;;8942:14;:::i;:::-;605:9234;8942:29;;605:9234;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;605:9234:87;;;;;;;;;;;;;3144:14;;;;;;605:9234;8985:14;605:9234;3144:14;;605:9234;;;8985:14;:::i;:::-;:30;605:9234;;;;;;;;;;;;;;;6450:81;;;;;;:::i;:::-;6545:8;;6541:74;;-1:-1:-1;9053:13:87;605:9234;;;;9053:13;:::i;:::-;3144:14;9068:29;605:9234;9068:14;605:9234;3144:14;;605:9234;;;9068:14;:::i;:29::-;5511:10;;5552:3;5527:16;;;;:::i;:::-;5523:27;;;;;;;5593:16;5552:3;5593:16;:25;:19;:16;;;;:::i;:25::-;605:9234;;;;3411:47:52;;605:9234:87;;;;;;3411:47:52;;;;605:9234:87;;;;;;;;3411:47:52;;605:9234:87;;;;;;;3411:47:52;;;;;:::i;:::-;5615:25;;;;;;;;;:::i;:::-;5657:69;;;5552:3:87;5657:103:52;;;;5552:3:87;3473:45:52;3469:201;;5552:3:87;;;;;:::i;:::-;5511:10;;3469:201:52;3561:43;3646:12;605:9234:87;;;3561:43:52;605:9234:87;3561:43:52;;;605:9234:87;;;;;;;;3561:43:52;;605:9234:87;;;;;;;3561:43:52;;;;;:::i;3646:12::-;3469:201;;;;;5657:103;5730:26;;;:30;;5657:103;;:69;605:9234:87;;5669:22:52;;;-1:-1:-1;5669:56:52;;;;5657:69;;;;;;5669:56;5695:30;;;605:9234:87;5695:30:52;;;;;;;;:::i;:::-;5669:56;;;;5523:27:87;;9235:14;5523:27;9119:24;605:9234;9119:14;605:9234;3144:14;;605:9234;;;9119:14;:::i;:::-;:24;605:9234;9119:24;:::i;:::-;9235:23;605:9234;9197:24;:14;605:9234;3144:14;;605:9234;;;9197:14;:::i;:24::-;3144:14;;;605:9234;3144:14;;605:9234;;;9235:14;:::i;:23::-;7229:10;;7241:20;;;;;;9415:24;;;;;:::i;:::-;9466:42;-1:-1:-1;9466:102:87;;;;;7224:432;9449:189;;;;605:9234;1755:1:56;;605:9234:87;;9449:189;605:9234;;-1:-1:-1;;;9600:27:87;;605:9234;;9600:27;9466:102;9524:44;;-1:-1:-1;9466:102:87;;;;7263:3;-1:-1:-1;;;;;7304:18:87;:12;;;;;:::i;:18::-;605:9234;;-1:-1:-1;;;7360:30:87;;6979:4;605:9234;7360:30;;605:9234;;;;;;;;;7360:30;;;;;;;;;;;7263:3;7456:30;;;;;:::i;:::-;605:9234;;7489:12;;;;;:::i;:::-;:19;605:9234;;;;;;;;7425:83;;7404:186;;7263:3;7632:12;;;;;:::i;:::-;7263:3;:::i;:::-;7229:10;;7404:186;605:9234;;-1:-1:-1;;;7548:27:87;;605:9234;;7548:27;605:9234;;;;;;;;;;;;7360:30;;;;605:9234;7360:30;;605:9234;7360:30;;;;;;605:9234;7360:30;;;:::i;:::-;;;605:9234;;;;;7360:30;;;;;;;-1:-1:-1;7360:30:87;;;605:9234;;;;;;;;;6541:74;605:9234;;-1:-1:-1;;;6576:28:87;;605:9234;;6576:28;;605:9234;;;;;;;;;;;:::i;:::-;6576:28;;;605:9234;;;;8612:245;3040:5;-1:-1:-1;;;;;605:9234:87;;8730:14;605:9234;3144:14;;605:9234;;;8730:14;:::i;:::-;:30;605:9234;8716:45;;;;;605:9234;;;;;;;;;;;;;;;;8716:45;;605:9234;8716:45;;605:9234;8716:45;;;;;;8612:245;-1:-1:-1;;8712:135:87;;605:9234;;-1:-1:-1;;;8796:36:87;;605:9234;;8796:36;8712:135;8612:245;;8716:45;;;;:::i;:::-;605:9234;;8716:45;;;;605:9234;;;;8716:45;605:9234;;;5115:226;;;;:::i;:::-;;;;;605:9234;;;;;;;;;;;;;;-1:-1:-1;;;;;605:9234:87;;;;;;;;;;;;;;-1:-1:-1;605:9234:87;;-1:-1:-1;605:9234:87;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5115:226;605:9234;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;6865:3;605:9234;;;-1:-1:-1;;;;;6906:15:87;:9;605:9234;6906:9;;;:::i;:15::-;605:9234;;;;;;;;;;6955:30;;6979:4;605:9234;6955:30;;605:9234;6955:30;;;;;;;;;;6865:3;;6936:49;;;;;;:::i;:::-;605:9234;6865:3;:::i;:::-;6834:10;;6955:30;;;605:9234;6955:30;;605:9234;6955:30;;;;;;605:9234;6955:30;;;:::i;:::-;;;605:9234;;;;;6865:3;605:9234;;6955:30;;605:9234;;;;6955:30;;;-1:-1:-1;6955:30:87;;;605:9234;;;;;;;;;3242:189;605:9234;;-1:-1:-1;;;3394:26:87;;605:9234;;3394:26;3259:103;3144:14;3316:29;605:9234;3316:14;605:9234;3144:14;;605:9234;;;3316:14;:::i;:29::-;-1:-1:-1;;;;;605:9234:87;3357:4;3316:46;3259:103;;3140:93;605:9234;;-1:-1:-1;;;3200:22:87;;605:9234;;3200:22;8022:98;605:9234;;-1:-1:-1;;;8089:20:87;;605:9234;;8089:20;2554:86:56;605:9234:87;;-1:-1:-1;;;2599:30:56;;605:9234:87;;2599:30:56;605:9234:87;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;2287:5;-1:-1:-1;;;;;605:9234:87;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;605:9234:87;;;;;;;:::o;:::-;;;;;;;;;;;;;-1:-1:-1;;;;;605:9234:87;;;;;;:::o;:::-;;;;;;;-1:-1:-1;;;;;605:9234:87;;;;;;;:::o;:::-;;;;;;;;;;;;;-1:-1:-1;;;;;605:9234:87;;;;;;;:::o;:::-;-1:-1:-1;;;;;605:9234:87;;;;;;-1:-1:-1;;605:9234:87;;;;:::o;:::-;;;;;;;;;;-1:-1:-1;;;;;605:9234:87;;;;;;;;;;-1:-1:-1;;;605:9234:87;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;605:9234:87;;;;;;;;;:::o;:::-;;;-1:-1:-1;;;;;605:9234:87;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;605:9234:87;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;-1:-1:-1;605:9234:87;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;:::i;:::-;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;-1:-1:-1;605:9234:87;;;;:::o;:::-;;;:::o;1303:160:52:-;605:9234:87;;-1:-1:-1;;;1412:43:52;;;;-1:-1:-1;;;;;605:9234:87;;;;1412:43:52;;;605:9234:87;;;;;;;;;1412:43:52;;;;;;605:9234:87;;1412:43:52;:::i;:::-;1303:160::o;605:9234:87:-;;;;;;;;;;;;;;;;;;:::o;4059:629:52:-;2847:1:53;4059:629:52;3510:55:53;4059:629:52;605:9234:87;;;;;;3462:31:53;;;;;;;;;;;;:::i;:::-;3510:55;;;:::i;:::-;605:9234:87;;4551:22:52;;;;:57;;;;4059:629;4547:135;;;;4059:629;:::o;4547:135::-;605:9234:87;;;;4631:40:52;;;;;;;;;605:9234:87;4631:40:52;4551:57;4578:30;;;3462:31:53;4578:30:52;;;;;;;;:::i;:::-;4577:31;4551:57;;;;4625:582:53;;4797:8;;-1:-1:-1;605:9234:87;;5874:21:53;:17;;6046:142;;;;;;5870:383;605:9234:87;;-1:-1:-1;;;6225:17:53;;;;;4793:408;605:9234:87;;5045:22:53;:49;;;4793:408;5041:119;;5173:17;;:::o;5041:119::-;605:9234:87;;-1:-1:-1;;;5121:24:53;;-1:-1:-1;;;;;605:9234:87;;;5121:24:53;;;605:9234:87;;;5121:24:53;5045:49;5071:18;;;:23;5045:49;;605:9234:87;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;605:9234:87;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;:::o;:::-;;-1:-1:-1;;;;;605:9234:87;;;;;;;:::o;:::-;-1:-1:-1;;605:9234:87;;;;;;;:::o;:::-;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;3556:352;3670:1;3661:10;;3673:17;;;;;;3556:352;;;;:::o;3692:3::-;3729:1;605:9234;;;;;;;3732:17;;;;;;3692:3;;;;:::i;:::-;3661:10;;3751:3;3778:15;:9;;;;;:::i;:15::-;-1:-1:-1;;;;;605:9234:87;3797:15;:9;;;;;:::i;:15::-;605:9234;;;3778:34;3774:104;;3751:3;;;:::i;:::-;3716:14;;3774:104;605:9234;;-1:-1:-1;;;3843:16:87;;;;;605:9234;-1:-1:-1;;;605:9234:87;;;;;;;;;;;;;;;;;;;;;;;:::o;5693:551::-;5768:1;5755:14;;;5751:27;;605:9234;3040:5;-1:-1:-1;;;;;605:9234:87;5847:21;5882:19;;;5878:227;;5693:551;2067:13;;;;;;6130:44;;;;:::i;:::-;;605:9234;;;5693:551::o;605:9234::-;;;-1:-1:-1;;;605:9234:87;;;;;;;;;;;;;;;;;-1:-1:-1;;;605:9234:87;;;;;;;5878:227;605:9234;;;;;;;;;;5983:34;;;;;605:9234;;;;;;;;;;;;;;;5983:34;;;;;605:9234;5983:34;;;;;;5878:227;-1:-1:-1;5979:116:87;;605:9234;;-1:-1:-1;;;6052:28:87;;5983:34;;6052:28;5979:116;;;;5878:227;;5983:34;;;;;;;:::i;:::-;;;;;5751:27;5771:7;;:::o;7668:201::-;605:9234;;-1:-1:-1;;;7809:43:87;;7782:4;7809:43;;;605:9234;;7774:21;7809:43;605:9234;;;3040:5;-1:-1:-1;;;;;605:9234:87;7809:43;;;;;;;-1:-1:-1;7809:43:87;;;7753:109;;7668:201;:::o;7809:43::-;;;;;;;;;;;;;;;;;:::i;:::-;;;605:9234;;;;;;7668:201;:::o;7809:43::-;;;-1:-1:-1;7809:43:87;;;605:9234;;;-1:-1:-1;605:9234:87;;;;;1190:520:89;605:9234:87;;;;;;;-1:-1:-1;;;;;605:9234:87;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1368:43:89;1438:16;;;605:9234:87;;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;:::i;:::-;;;;;;;;;;;;;-1:-1:-1;1051:3:89;605:9234:87;;1026:23:89;;;;;1093:15;;;;:::i;:::-;;605:9234:87;;;;;;;;;;;;;;;;1051:3:89;605:9234:87;;;;;;;;;;-1:-1:-1;;;605:9234:87;;;;;;;;;;668:36:89;605:9234:87;;;;;;;189:189:89;;605:9234:87;765:18:89;;605:9234:87;;;;636:165:89;;;;605:9234:87;;;438:43:89;;605:9234:87;438:43:89;;;605:9234:87;636:165:89;;;;;;:::i;:::-;605:9234:87;609:206:89;;1070:39;;;;:::i;1051:3::-;1014:10;;1026:23;;;;;;;;;;;;;;;605:9234:87;;1146:30:89;;;;;605:9234:87;;;;;;-1:-1:-1;605:9234:87;;;;;;;1146:30:89;;;;;;;;;;;;;;:::i;:::-;605:9234:87;1136:41:89;;605:9234:87;;;;;;1477:15:89;;;;189:189;605:9234:87;1514:21:89;;;;189:189;605:9234:87;1567:21:89;;;;;605:9234:87;;;;;1557:32:89;1611:22;605:9234:87;;1611:22:89;;605:9234:87;1655:16:89;;605:9234:87;;;;1336:353:89;;;605:9234:87;;;189:189:89;;;605:9234:87;189:189:89;;605:9234:87;;189:189:89;;605:9234:87;;189:189:89;;605:9234:87;;189:189:89;;605:9234:87;;189:189:89;;605:9234:87;;1336:353:89;;189:189;605:9234:87;;;;;;;;;;;;;;1309:394:89;;1190:520;:::o;605:9234:87:-;;;;;;;;;;;-1:-1:-1;605:9234:87;;;;;;;","linkReferences":{},"immutableReferences":{"59785":[{"start":929,"length":32}],"59787":[{"start":225,"length":32},{"start":428,"length":32},{"start":614,"length":32},{"start":1012,"length":32}],"59789":[{"start":156,"length":32},{"start":5502,"length":32}],"59791":[{"start":3080,"length":32},{"start":3770,"length":32},{"start":5446,"length":32},{"start":5772,"length":32}],"59793":[{"start":1075,"length":32},{"start":1793,"length":32},{"start":2132,"length":32}]}},"methodIdentifiers":{"WITNESS_TYPE_STRING()":"156e2152","executeOpportunity((((address,uint256)[],uint256,uint256),((address,uint256)[],address,address,bytes,uint256,uint256)),bytes)":"2608ba81","getExpressRelay()":"c9b4518a","getOwner()":"893d20e8","getWeth()":"107c279f","hash(((address,uint256)[],address,address,bytes,uint256,uint256))":"6184196a","version()":"54fd4d50","withdrawEth()":"a0ef91df","withdrawToken(address)":"89476069"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.20+commit.a1b79de6\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AdapterOwnerMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"AddressEmptyCode\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"AddressInsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthOrWethBalanceDecreased\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedInnerCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientEthToSettleBid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientTokenReceived\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientWethForTargetCallValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotCalledByFactory\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyOwnerCanCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrancyGuardReentrantCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SafeERC20FailedOperation\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"TargetCallFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TargetContractNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WITNESS_TYPE_STRING\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct ISignatureTransfer.TokenPermissions[]\",\"name\":\"permitted\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"}],\"internalType\":\"struct ISignatureTransfer.PermitBatchTransferFrom\",\"name\":\"permit\",\"type\":\"tuple\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct TokenAmount[]\",\"name\":\"buyTokens\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"executor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"targetContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"targetCalldata\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"targetCallValue\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"bidAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct ExecutionWitness\",\"name\":\"witness\",\"type\":\"tuple\"}],\"internalType\":\"struct ExecutionParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"executeOpportunity\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpressRelay\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getWeth\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct TokenAmount[]\",\"name\":\"buyTokens\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"executor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"targetContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"targetCalldata\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"targetCallValue\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"bidAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct ExecutionWitness\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"hash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawEth\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"withdrawToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"errors\":{\"AddressEmptyCode(address)\":[{\"details\":\"There's no code at `target` (it is not a contract).\"}],\"AddressInsufficientBalance(address)\":[{\"details\":\"The ETH balance of the account is not enough to perform the operation.\"}],\"FailedInnerCall()\":[{\"details\":\"A call to an address target failed. The target may have reverted.\"}],\"ReentrancyGuardReentrantCall()\":[{\"details\":\"Unauthorized reentrant call.\"}],\"SafeERC20FailedOperation(address)\":[{\"details\":\"An operation with an ERC20 token failed.\"}]},\"kind\":\"dev\",\"methods\":{\"withdrawToken(address)\":{\"params\":{\"token\":\": address of the token to withdraw\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"OpportunityAdapter initializer - Initializes a new opportunity adapter contract\"},\"getExpressRelay()\":{\"notice\":\"getExpressRelay function - returns the address of the express relay authenticated for calling this contract\"},\"getOwner()\":{\"notice\":\"getOwner function - returns the address of the owner of the contract\"},\"getWeth()\":{\"notice\":\"getWeth function - returns the address of the WETH contract used for wrapping and unwrapping ETH\"},\"withdrawEth()\":{\"notice\":\"withdrawEth function - withdraws ETH from the contract to the owner\"},\"withdrawToken(address)\":{\"notice\":\"withdrawToken function - withdraws specified tokens from the contract to the owner\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/opportunity-adapter/OpportunityAdapter.sol\":\"OpportunityAdapter\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@pythnetwork/express-relay-sdk-solidity/=node_modules/@pythnetwork/express-relay-sdk-solidity/\",\":@pythnetwork/pyth-sdk-solidity/=node_modules/@pythnetwork/pyth-sdk-solidity/\",\":ExcessivelySafeCall/=lib/ExcessivelySafeCall/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/\",\":forge-gas-snapshot/=lib/permit2/lib/forge-gas-snapshot/src/\",\":forge-std/=lib/forge-std/src/\",\":halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":openzeppelin/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":permit2/=lib/permit2/src/\",\":solmate/=lib/permit2/lib/solmate/src/\"],\"viaIR\":true},\"sources\":{\"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0xc6a8ff0ea489379b61faa647490411b80102578440ab9d84e9a957cc12164e70\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://0ea104e577e63faea3b69c415637e99e755dcbf64c5833d7140c35a714d6d90c\",\"dweb:/ipfs/Qmau6x4Ns9XdyynRCNNp3RhLqijJjFm7z5fyZazfYFGYdq\"]},\"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"keccak256\":\"0x6008dabfe393240d73d7dd7688033f72740d570aa422254d29a7dce8568f3aff\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f5196ec75139918c6c7bb4251b36395e668f1fa6d206beba7e7520e74913940d\",\"dweb:/ipfs/QmSyqjksXxmm2mCG6qRd1yuwLykypkSVBbnBnGqJRcuJMi\"]},\"lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol\":{\"keccak256\":\"0x37bb49513c49c87c4642a891b13b63571bc87013dde806617aa1efb54605f386\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b3036b3a83b7c48f96641f2a9002b9f2dcb6a5958dd670894ada21ae8229b3d0\",\"dweb:/ipfs/QmUNfSBdoVtjhETaUJCYcaC7pTMgbhht926tJ2uXJbiVd3\"]},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xaf28a975a78550e45f65e559a3ad6a5ad43b9b8a37366999abd1b7084eb70721\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b7bd24e224f67f65bfadf85dc2929fa965456bb2415478bd0125471b5ce35245\",\"dweb:/ipfs/QmRaydGr8BTHs1kvaZfsNU69pKzUAGFrvABn1KiRSbE51y\"]},\"lib/openzeppelin-contracts/contracts/utils/ReentrancyGuard.sol\":{\"keccak256\":\"0xf980daa263b661ab8ddee7d4fd833c7da7e7995e2c359ff1f17e67e4112f2236\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://7448ab095d6940130bcf76ba47a2eab14148c83119523b93dd89f6d84edd6c02\",\"dweb:/ipfs/QmawrZ4voKQjH3oomXT3Kuheb3Mnmo2VvVpxg8Ne5UJUrd\"]},\"lib/openzeppelin-contracts/contracts/utils/Strings.sol\":{\"keccak256\":\"0x55f102ea785d8399c0e58d1108e2d289506dde18abc6db1b7f68c1f9f9bc5792\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6e52e0a7765c943ef14e5bcf11e46e6139fa044be564881378349236bf2e3453\",\"dweb:/ipfs/QmZEeeXoFPW47amyP35gfzomF9DixqqTEPwzBakv6cZw6i\"]},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0x005ec64c6313f0555d59e278f9a7a5ab2db5bdc72a027f255a37c327af1ec02d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4ece9f0b9c8daca08c76b6b5405a6446b6f73b3a15fab7ff56e296cbd4a2c875\",\"dweb:/ipfs/QmQyRpyPRL5SQuAgj6SHmbir3foX65FJjbVTTQrA2EFg6L\"]},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0x5f7e4076e175393767754387c962926577f1660dd9b810187b9002407656be72\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://7d533a1c97cd43a57cd9c465f7ee8dd0e39ae93a8fb8ff8e5303a356b081cdcc\",\"dweb:/ipfs/QmVBEei6aTnvYNZp2CHYVNKyZS4q1KkjANfY39WVXZXVoT\"]},\"lib/permit2/src/interfaces/ISignatureTransfer.sol\":{\"keccak256\":\"0xbab1c35f0a63761be6b50a9a2ce2459b63f09587dd9c6ac46955252a1a04f43c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://225dca1a3d91c0737fe75c72bfecae391fc2e7b2eb2ebe1a154bfb16a7527972\",\"dweb:/ipfs/QmdGQdUCANKZ6S23TyHDtBnGvr6CtyyqNNcziVTjEHJ5rk\"]},\"src/opportunity-adapter/Errors.sol\":{\"keccak256\":\"0x52dbef88d515328490963ea923d04841d2e80d68c879342c8c05c9a59652f570\",\"license\":\"Apache 2\",\"urls\":[\"bzz-raw://5f825b83839dcc779db5e3735f2ca4854c0f2c0f4f382edb2e7380508cd8d570\",\"dweb:/ipfs/QmSowVpNasgthmBys8g49pDmbLDifLzE22hRejTXHve7sF\"]},\"src/opportunity-adapter/IOpportunityAdapterFactory.sol\":{\"keccak256\":\"0xaa1972242ea4d9c8c55256775945c3db850c7563e4a3ea1e7bf483aa43193fb0\",\"license\":\"Apache 2\",\"urls\":[\"bzz-raw://3ddd9fe69de5917e95218603b68957f1186636149f9c9636054651165de047e5\",\"dweb:/ipfs/QmW8n4vuWCtwAYcU3M5QDSwL4Wvu8Zmq5SCDxHECLfKWzc\"]},\"src/opportunity-adapter/IWETH9.sol\":{\"keccak256\":\"0x06e8fe3818fdbf58152dfd115015cea455cce5e25739d2efd5e0fe4a47fa914e\",\"license\":\"Apache 2\",\"urls\":[\"bzz-raw://2f30048c1be6a967720b48b6d9758c1066df174a1bac8fbf5c46be2119c3e0ba\",\"dweb:/ipfs/QmaxEJZWM5StRWMJQzT6NuqhrQXFi9cNASijjYBKxGdgB1\"]},\"src/opportunity-adapter/OpportunityAdapter.sol\":{\"keccak256\":\"0xb740bc27178fd4764511fb2ce422ad3ec806d5fcf0a5e5b8516c2595bf8189bd\",\"license\":\"Apache 2\",\"urls\":[\"bzz-raw://6693e0a6e5487c10e952a1a7b8e792909272fc0e5a0f24d3f40b3b25b9a978e2\",\"dweb:/ipfs/QmXoELHWPRCZ4M7S6n9MHFCbzrVKTx9HXUw41vnLVKhXKQ\"]},\"src/opportunity-adapter/OpportunityAdapterHasher.sol\":{\"keccak256\":\"0x3522d08da173a34e19e00680d28896c5baa0a80e1b712fbec385e0a571685196\",\"license\":\"Apache 2\",\"urls\":[\"bzz-raw://d6452f694f3508a3d5e1926c320d55ecb0c129120da3046c61102942eb7c5d8f\",\"dweb:/ipfs/QmS2zLzFmpgqWEYDe4p71ZZJJJuSPwn5uWjYz9XmYjjMXb\"]},\"src/opportunity-adapter/Structs.sol\":{\"keccak256\":\"0xdb445d4e01f554cc6ac18578329fb763487c84e5158f98cf9c34844b8f470f47\",\"license\":\"Apache 2\",\"urls\":[\"bzz-raw://7da599018a0baa466b1f48f14ef4a5741a72678d45079cae4ab4447825b16774\",\"dweb:/ipfs/QmTqe7Y6KMAVisDUm7kcWEHXMvtCKAKuveCWBre3NdiinX\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.20+commit.a1b79de6"},"language":"Solidity","output":{"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"type":"error","name":"AdapterOwnerMismatch"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"type":"error","name":"AddressEmptyCode"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"type":"error","name":"AddressInsufficientBalance"},{"inputs":[],"type":"error","name":"DuplicateToken"},{"inputs":[],"type":"error","name":"EthOrWethBalanceDecreased"},{"inputs":[],"type":"error","name":"FailedInnerCall"},{"inputs":[],"type":"error","name":"InsufficientEthToSettleBid"},{"inputs":[],"type":"error","name":"InsufficientTokenReceived"},{"inputs":[],"type":"error","name":"InsufficientWethForTargetCallValue"},{"inputs":[],"type":"error","name":"NotCalledByFactory"},{"inputs":[],"type":"error","name":"OnlyOwnerCanCall"},{"inputs":[],"type":"error","name":"ReentrancyGuardReentrantCall"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"type":"error","name":"SafeERC20FailedOperation"},{"inputs":[{"internalType":"bytes","name":"returnData","type":"bytes"}],"type":"error","name":"TargetCallFailed"},{"inputs":[],"type":"error","name":"TargetContractNotAllowed"},{"inputs":[],"stateMutability":"view","type":"function","name":"WITNESS_TYPE_STRING","outputs":[{"internalType":"string","name":"","type":"string"}]},{"inputs":[{"internalType":"struct ExecutionParams","name":"params","type":"tuple","components":[{"internalType":"struct ISignatureTransfer.PermitBatchTransferFrom","name":"permit","type":"tuple","components":[{"internalType":"struct ISignatureTransfer.TokenPermissions[]","name":"permitted","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}]},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}]},{"internalType":"struct ExecutionWitness","name":"witness","type":"tuple","components":[{"internalType":"struct TokenAmount[]","name":"buyTokens","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}]},{"internalType":"address","name":"executor","type":"address"},{"internalType":"address","name":"targetContract","type":"address"},{"internalType":"bytes","name":"targetCalldata","type":"bytes"},{"internalType":"uint256","name":"targetCallValue","type":"uint256"},{"internalType":"uint256","name":"bidAmount","type":"uint256"}]}]},{"internalType":"bytes","name":"signature","type":"bytes"}],"stateMutability":"payable","type":"function","name":"executeOpportunity"},{"inputs":[],"stateMutability":"view","type":"function","name":"getExpressRelay","outputs":[{"internalType":"address","name":"","type":"address"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"getOwner","outputs":[{"internalType":"address","name":"","type":"address"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"getWeth","outputs":[{"internalType":"address","name":"","type":"address"}]},{"inputs":[{"internalType":"struct ExecutionWitness","name":"params","type":"tuple","components":[{"internalType":"struct TokenAmount[]","name":"buyTokens","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}]},{"internalType":"address","name":"executor","type":"address"},{"internalType":"address","name":"targetContract","type":"address"},{"internalType":"bytes","name":"targetCalldata","type":"bytes"},{"internalType":"uint256","name":"targetCallValue","type":"uint256"},{"internalType":"uint256","name":"bidAmount","type":"uint256"}]}],"stateMutability":"pure","type":"function","name":"hash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}]},{"inputs":[],"stateMutability":"pure","type":"function","name":"version","outputs":[{"internalType":"string","name":"","type":"string"}]},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"withdrawEth"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"withdrawToken"},{"inputs":[],"stateMutability":"payable","type":"receive"}],"devdoc":{"kind":"dev","methods":{"withdrawToken(address)":{"params":{"token":": address of the token to withdraw"}}},"version":1},"userdoc":{"kind":"user","methods":{"constructor":{"notice":"OpportunityAdapter initializer - Initializes a new opportunity adapter contract"},"getExpressRelay()":{"notice":"getExpressRelay function - returns the address of the express relay authenticated for calling this contract"},"getOwner()":{"notice":"getOwner function - returns the address of the owner of the contract"},"getWeth()":{"notice":"getWeth function - returns the address of the WETH contract used for wrapping and unwrapping ETH"},"withdrawEth()":{"notice":"withdrawEth function - withdraws ETH from the contract to the owner"},"withdrawToken(address)":{"notice":"withdrawToken function - withdraws specified tokens from the contract to the owner"}},"version":1}},"settings":{"remappings":["@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/","@pythnetwork/express-relay-sdk-solidity/=node_modules/@pythnetwork/express-relay-sdk-solidity/","@pythnetwork/pyth-sdk-solidity/=node_modules/@pythnetwork/pyth-sdk-solidity/","ExcessivelySafeCall/=lib/ExcessivelySafeCall/src/","ds-test/=lib/forge-std/lib/ds-test/src/","erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/","forge-gas-snapshot/=lib/permit2/lib/forge-gas-snapshot/src/","forge-std/=lib/forge-std/src/","halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/","openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/","openzeppelin-contracts/=lib/openzeppelin-contracts/","openzeppelin/=lib/openzeppelin-contracts-upgradeable/contracts/","permit2/=lib/permit2/src/","solmate/=lib/permit2/lib/solmate/src/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"src/opportunity-adapter/OpportunityAdapter.sol":"OpportunityAdapter"},"evmVersion":"shanghai","libraries":{},"viaIR":true},"sources":{"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol":{"keccak256":"0xc6a8ff0ea489379b61faa647490411b80102578440ab9d84e9a957cc12164e70","urls":["bzz-raw://0ea104e577e63faea3b69c415637e99e755dcbf64c5833d7140c35a714d6d90c","dweb:/ipfs/Qmau6x4Ns9XdyynRCNNp3RhLqijJjFm7z5fyZazfYFGYdq"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol":{"keccak256":"0x6008dabfe393240d73d7dd7688033f72740d570aa422254d29a7dce8568f3aff","urls":["bzz-raw://f5196ec75139918c6c7bb4251b36395e668f1fa6d206beba7e7520e74913940d","dweb:/ipfs/QmSyqjksXxmm2mCG6qRd1yuwLykypkSVBbnBnGqJRcuJMi"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol":{"keccak256":"0x37bb49513c49c87c4642a891b13b63571bc87013dde806617aa1efb54605f386","urls":["bzz-raw://b3036b3a83b7c48f96641f2a9002b9f2dcb6a5958dd670894ada21ae8229b3d0","dweb:/ipfs/QmUNfSBdoVtjhETaUJCYcaC7pTMgbhht926tJ2uXJbiVd3"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/Address.sol":{"keccak256":"0xaf28a975a78550e45f65e559a3ad6a5ad43b9b8a37366999abd1b7084eb70721","urls":["bzz-raw://b7bd24e224f67f65bfadf85dc2929fa965456bb2415478bd0125471b5ce35245","dweb:/ipfs/QmRaydGr8BTHs1kvaZfsNU69pKzUAGFrvABn1KiRSbE51y"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/ReentrancyGuard.sol":{"keccak256":"0xf980daa263b661ab8ddee7d4fd833c7da7e7995e2c359ff1f17e67e4112f2236","urls":["bzz-raw://7448ab095d6940130bcf76ba47a2eab14148c83119523b93dd89f6d84edd6c02","dweb:/ipfs/QmawrZ4voKQjH3oomXT3Kuheb3Mnmo2VvVpxg8Ne5UJUrd"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/Strings.sol":{"keccak256":"0x55f102ea785d8399c0e58d1108e2d289506dde18abc6db1b7f68c1f9f9bc5792","urls":["bzz-raw://6e52e0a7765c943ef14e5bcf11e46e6139fa044be564881378349236bf2e3453","dweb:/ipfs/QmZEeeXoFPW47amyP35gfzomF9DixqqTEPwzBakv6cZw6i"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/math/Math.sol":{"keccak256":"0x005ec64c6313f0555d59e278f9a7a5ab2db5bdc72a027f255a37c327af1ec02d","urls":["bzz-raw://4ece9f0b9c8daca08c76b6b5405a6446b6f73b3a15fab7ff56e296cbd4a2c875","dweb:/ipfs/QmQyRpyPRL5SQuAgj6SHmbir3foX65FJjbVTTQrA2EFg6L"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol":{"keccak256":"0x5f7e4076e175393767754387c962926577f1660dd9b810187b9002407656be72","urls":["bzz-raw://7d533a1c97cd43a57cd9c465f7ee8dd0e39ae93a8fb8ff8e5303a356b081cdcc","dweb:/ipfs/QmVBEei6aTnvYNZp2CHYVNKyZS4q1KkjANfY39WVXZXVoT"],"license":"MIT"},"lib/permit2/src/interfaces/ISignatureTransfer.sol":{"keccak256":"0xbab1c35f0a63761be6b50a9a2ce2459b63f09587dd9c6ac46955252a1a04f43c","urls":["bzz-raw://225dca1a3d91c0737fe75c72bfecae391fc2e7b2eb2ebe1a154bfb16a7527972","dweb:/ipfs/QmdGQdUCANKZ6S23TyHDtBnGvr6CtyyqNNcziVTjEHJ5rk"],"license":"MIT"},"src/opportunity-adapter/Errors.sol":{"keccak256":"0x52dbef88d515328490963ea923d04841d2e80d68c879342c8c05c9a59652f570","urls":["bzz-raw://5f825b83839dcc779db5e3735f2ca4854c0f2c0f4f382edb2e7380508cd8d570","dweb:/ipfs/QmSowVpNasgthmBys8g49pDmbLDifLzE22hRejTXHve7sF"],"license":"Apache 2"},"src/opportunity-adapter/IOpportunityAdapterFactory.sol":{"keccak256":"0xaa1972242ea4d9c8c55256775945c3db850c7563e4a3ea1e7bf483aa43193fb0","urls":["bzz-raw://3ddd9fe69de5917e95218603b68957f1186636149f9c9636054651165de047e5","dweb:/ipfs/QmW8n4vuWCtwAYcU3M5QDSwL4Wvu8Zmq5SCDxHECLfKWzc"],"license":"Apache 2"},"src/opportunity-adapter/IWETH9.sol":{"keccak256":"0x06e8fe3818fdbf58152dfd115015cea455cce5e25739d2efd5e0fe4a47fa914e","urls":["bzz-raw://2f30048c1be6a967720b48b6d9758c1066df174a1bac8fbf5c46be2119c3e0ba","dweb:/ipfs/QmaxEJZWM5StRWMJQzT6NuqhrQXFi9cNASijjYBKxGdgB1"],"license":"Apache 2"},"src/opportunity-adapter/OpportunityAdapter.sol":{"keccak256":"0xb740bc27178fd4764511fb2ce422ad3ec806d5fcf0a5e5b8516c2595bf8189bd","urls":["bzz-raw://6693e0a6e5487c10e952a1a7b8e792909272fc0e5a0f24d3f40b3b25b9a978e2","dweb:/ipfs/QmXoELHWPRCZ4M7S6n9MHFCbzrVKTx9HXUw41vnLVKhXKQ"],"license":"Apache 2"},"src/opportunity-adapter/OpportunityAdapterHasher.sol":{"keccak256":"0x3522d08da173a34e19e00680d28896c5baa0a80e1b712fbec385e0a571685196","urls":["bzz-raw://d6452f694f3508a3d5e1926c320d55ecb0c129120da3046c61102942eb7c5d8f","dweb:/ipfs/QmS2zLzFmpgqWEYDe4p71ZZJJJuSPwn5uWjYz9XmYjjMXb"],"license":"Apache 2"},"src/opportunity-adapter/Structs.sol":{"keccak256":"0xdb445d4e01f554cc6ac18578329fb763487c84e5158f98cf9c34844b8f470f47","urls":["bzz-raw://7da599018a0baa466b1f48f14ef4a5741a72678d45079cae4ab4447825b16774","dweb:/ipfs/QmTqe7Y6KMAVisDUm7kcWEHXMvtCKAKuveCWBre3NdiinX"],"license":"Apache 2"}},"version":1},"id":87} \ No newline at end of file diff --git a/sdk/rust/abi/OpportunityAdapterFactory.sol/OpportunityAdapterFactory.json b/sdk/rust/abi/OpportunityAdapterFactory.sol/OpportunityAdapterFactory.json new file mode 100644 index 00000000..f3061ab7 --- /dev/null +++ b/sdk/rust/abi/OpportunityAdapterFactory.sol/OpportunityAdapterFactory.json @@ -0,0 +1 @@ +{"abi":[{"type":"constructor","inputs":[{"name":"expressRelay","type":"address","internalType":"address"},{"name":"weth","type":"address","internalType":"address"},{"name":"permit2","type":"address","internalType":"address"}],"stateMutability":"nonpayable"},{"type":"function","name":"computeAddress","inputs":[{"name":"owner","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"createAdapter","inputs":[{"name":"owner","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"nonpayable"},{"type":"function","name":"executeOpportunity","inputs":[{"name":"params","type":"tuple","internalType":"struct ExecutionParams","components":[{"name":"permit","type":"tuple","internalType":"struct ISignatureTransfer.PermitBatchTransferFrom","components":[{"name":"permitted","type":"tuple[]","internalType":"struct ISignatureTransfer.TokenPermissions[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"}]},{"name":"nonce","type":"uint256","internalType":"uint256"},{"name":"deadline","type":"uint256","internalType":"uint256"}]},{"name":"witness","type":"tuple","internalType":"struct ExecutionWitness","components":[{"name":"buyTokens","type":"tuple[]","internalType":"struct TokenAmount[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"}]},{"name":"executor","type":"address","internalType":"address"},{"name":"targetContract","type":"address","internalType":"address"},{"name":"targetCalldata","type":"bytes","internalType":"bytes"},{"name":"targetCallValue","type":"uint256","internalType":"uint256"},{"name":"bidAmount","type":"uint256","internalType":"uint256"}]}]},{"name":"signature","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"getExpressRelay","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"getOpportunityAdapterCreationCodeHash","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"getPermit2","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"getWeth","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"parameters","inputs":[],"outputs":[{"name":"expressRelay","type":"address","internalType":"address"},{"name":"weth","type":"address","internalType":"address"},{"name":"permit2","type":"address","internalType":"address"},{"name":"owner","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"error","name":"Create2EmptyBytecode","inputs":[]},{"type":"error","name":"Create2FailedDeployment","inputs":[]},{"type":"error","name":"Create2InsufficientBalance","inputs":[{"name":"balance","type":"uint256","internalType":"uint256"},{"name":"needed","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"NotCalledByExpressRelay","inputs":[]},{"type":"error","name":"ReentrancyGuardReentrantCall","inputs":[]}],"bytecode":{"object":"0x6080604052346100b157613f346060813803918261001c816100b5565b9384928339810103126100b157610032816100ee565b9061004b6040610044602084016100ee565b92016100ee565b60015f5560018060a01b0380928160018060a01b031995168560015416176001551683600254161760025516906003541617600355611b6d61008f602082016100b5565b81815260208101916123c783395190206004556040516122c490816101038239f35b5f80fd5b6040519190601f01601f191682016001600160401b038111838210176100da57604052565b634e487b7160e01b5f52604160045260245ffd5b51906001600160a01b03821682036100b15756fe6080806040526004361015610012575f80fd5b5f90813560e01c908163107c279f146104f5575080631bbf2e23146104cc5780632608ba81146101615780633e239349146101435780634e1d91d81461011f57806389035730146100d7578063acf461f9146100a15763c9b4518a14610076575f80fd5b3461009e578060031936011261009e576001546040516001600160a01b039091168152602090f35b80fd5b503461009e57602036600319011261009e5760206100c56100c061051a565b610548565b6040516001600160a01b039091168152f35b503461009e578060031936011261009e57608060018060a01b038060055416908060065416908060075416906008541691604051938452602084015260408301526060820152f35b503461009e57602036600319011261009e5760206100c561013e61051a565b610658565b503461009e578060031936011261009e576020600454604051908152f35b50604036600319011261009e5767ffffffffffffffff6004351161009e576004356004016040600319600435360301126104c85767ffffffffffffffff602435116104c8573660236024350112156104c85767ffffffffffffffff60243560040135116104c85736602480356004013581350101116104c85760028254146104b657600282556001546001600160a01b031633036104a45761021661013e602061021060246004350185610683565b01610698565b63ffffffff813b1615610487575b6001600160a01b0381163b156104835760405191632608ba8160e01b835260406004840152359060621960043536030182121561047f576040604484015260e483019161027760048035830101806106ac565b6060608487015293849052610104850193865b8181106104615750505060043590810160248181013560a48701526044919091013560c486015281013590360360c2190181121561045d578383036043190160648501528492919060c08301906102e760048035830101806106ac565b60c086529283905260e0850192865b81811061043557506001600160a01b03915061031a90506004358301602401610534565b1660208501526001600160a01b036103386004358301604401610534565b166040850152600435810160648101359036036022190181121561043157600435820101906024600483013592019067ffffffffffffffff831161042d57823603821361042d578560a060a461039f878c9a976103d4978c9a998b9a036060880152610701565b936084600435820101356080850152600435010135910152600319838203016024840152602435600401356024803501610701565b039134906001600160a01b03165af18015610422576103f6575b506001815580f35b67ffffffffffffffff811161040e576040525f6103ee565b634e487b7160e01b82526041600452602482fd5b6040513d84823e3d90fd5b8680fd5b8580fd5b919495965091926040808261044c600194896106e1565b0195019101918896959493926102f6565b8480fd5b909194604080826104746001948a6106e1565b01960192910161028a565b8380fd5b8280fd5b61049e6100c0602061021060246004350186610683565b50610224565b604051631aacd19160e31b8152600490fd5b604051633ee5aeb560e01b8152600490fd5b5080fd5b503461009e578060031936011261009e576003546040516001600160a01b039091168152602090f35b9050346104c857816003193601126104c8576002546001600160a01b03168152602090f35b600435906001600160a01b038216820361053057565b5f80fd5b35906001600160a01b038216820361053057565b60018060a01b038091168160015416908260025416836003541690604093845192608084019267ffffffffffffffff948085108686111761064457606087959186928a52858152836020820152848a82015201526bffffffffffffffffffffffff60a01b928360055416176005558260065416176006558160075416176007556008541617600855611b6d90835190601f19603f84011682019082821090821117610644578452818152602081019161072283398051156106335751905ff59182161561062357505f6005555f6006555f6007555f60085590565b51633a0ba96160e11b8152600490fd5b8351631328927760e21b8152600490fd5b634e487b7160e01b5f52604160045260245ffd5b600b6055916004549060405191604083015260018060a01b031660208201523081520160ff81532090565b90359060be1981360301821215610530570190565b356001600160a01b03811681036105305790565b9035601e198236030181121561053057016020813591019167ffffffffffffffff8211610530578160061b3603831361053057565b60209081906001600160a01b036106f782610534565b1684520135910152565b908060209392818452848401375f828201840152601f01601f191601019056fe610120806040523462000171575f60018155608091338352630890357360e41b81528281600481335afa908115620001665782918391848092620000c6575b505060a05261010092835260e05260c052604051906119e292836200018b843951826103a1015260a05182818160e1015281816101ac0152818161026601526103f4015260c051828181609c015261157e015260e051828181610c0801528181610eba01528181611546015261168c0152518181816104330152818161070101526108540152f35b935093505050823d84116200015e575b601f8101601f191683016001600160401b038111848210176200014a5784918491604052810103126200014757506200010f8162000175565b906200011e6020820162000175565b906200013b6060620001336040840162000175565b920162000175565b929190925f806200003e565b80fd5b634e487b7160e01b83526041600452602483fd5b503d620000d6565b6040513d84823e3d90fd5b5f80fd5b51906001600160a01b0382168203620001715756fe608080604052600436101561001c575b50361561001a575f80fd5b005b5f90813560e01c908163107c279f14610ea657508063156e215214610e765780632608ba811461032257806354fd4d50146102d85780636184196a14610295578063893d20e8146102505780638947606914610182578063a0ef91df146100ce5763c9b4518a0361000f57346100cb57806003193601126100cb576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b80fd5b50346100cb57806003193601126100cb577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163381900361017057818080809347905af1610122611295565b501561012b5780f35b60405162461bcd60e51b815260206004820152601860248201527f5769746864726177616c206f6620455448206661696c656400000000000000006044820152606490fd5b6040516308f51d4b60e31b8152600490fd5b50346100cb5760203660031901126100cb576001600160a01b0360043581811690819003610239577f00000000000000000000000000000000000000000000000000000000000000009182163303610170576040516370a0823160e01b815230600482015291602083602481855afa91821561024557849261020c575b61020993506112c4565b80f35b91506020833d821161023d575b8161022660209383610f4a565b81010312610239576102099251916101ff565b5f80fd5b3d9150610219565b6040513d86823e3d90fd5b50346100cb57806003193601126100cb576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b50346100cb5760203660031901126100cb57600435906001600160401b0382116100cb5760206102d06102cb3660048601611153565b611702565b604051908152f35b50346100cb57806003193601126100cb5761031e6040516102f881610eed565b60058152640302e322e360dc1b60208201526040519182916020835260208301906110ea565b0390f35b5060403660031901126100cb57600435906001600160401b0382116100cb57604060031983360301126100cb576001600160401b03602435116100cb573660236024350112156100cb576001600160401b0360243560040135116100cb5736602480356004013581350101116100cb576002815414610e6457600281557f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163303610e52576103ea60206103e460248501856004016113ee565b0161144d565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116911603610e405761043160406103e460248501856004016113ee565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b039081169116148015610e1a575b610e085761048a61048461047e6004850180611438565b80611403565b90611493565b6104a061048461047e60248501856004016113ee565b6104a861166f565b6104be61047e60248695949501866004016113ee565b6104c781611128565b916104d56040519384610f4a565b818352601f196104e483611128565b01366020850137845b828110610d6757506105059150506004860180611438565b9161051660248701876004016113ee565b916105218480611403565b97905061054661053089611128565b9861053e6040519a8b610f4a565b808a52611128565b865b601f1982018110610d44575050855b6105618680611403565b90508110156106d6578060206105846106509361057e8a80611403565b9061146f565b0135816105ab6105a66105978b80611403565b6001600160a01b03949161146f565b61144d565b168b6105cc84604051926105be84610eed565b308452856020850152611527565b526105d7838d611527565b506105e46040890161144d565b60405163095ea7b360e01b602082018181526001600160a01b038416602484015260448084019690965294825293909291908c908190610625606487610f4a565b85519082865af1610634611295565b816106a7575b508061069d575b15610655575b50505050611461565b610557565b60405160208101949094526001600160a01b0316602484015260448084018c905283526106949261068f9061068981610f2f565b8261131a565b61131a565b5f808080610647565b50813b1515610641565b80518015925082156106bc575b50505f61063a565b6106cf9250602080918301019101611302565b5f806106b4565b508686868a876106f66102cb6106ee6020840161144d565b923690611153565b6106fe610f86565b917f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163b15610d405760405163fe8ec1a760e01b815260c060048201529480359036819003601e1901821215610d3c576001600160401b038183013511610d3c578082013560061b360360208284010113610d3c579187959391879593606060c4880152610124870181830135905261014487019160208282010190895b838201358110610cf657505050806020604092013560e4890152013561010487015260031986820301602487015260208086519283815201950190875b818110610cc5575050506001600160a01b031660448501526064840152828203600319016084840152602091839161081991906110ea565b6003198282030160a4830152602480356004810135808452910184830137600460243501358181018401869052601f01601f191601030181837f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af18015610cba57610cab575b5090608061089d60248501856004016113ee565b0135610c06575b6108b960406103e460248601866004016113ee565b6108c960248501856004016113ee565b606081013590601e1981360301821215610c0257018035906001600160401b038211610c02576020018136038113610c0257918492918392608061091360248a018a6004016113ee565b013590826040519384928337810185815203925af1610930611295565b9015610bd957506109446004840180611438565b9461095a60406103e460248701876004016113ee565b93835b6109678880611403565b9050811015610a5e57806109e7916109856105a66105978c80611403565b1660405160208101915f8063095ea7b360e01b9485815260018060a01b038d166024860152816044860152604485526109bd85610f2f565b84519082855af16109cc611295565b81610a2f575b5080610a25575b156109ec575b505050611461565b61095d565b61068f610a1d9360405190602082015260018060a01b038c1660248201525f60448201526044815261068981610f2f565b8980806109df565b50803b15156109d9565b8051801592508215610a44575b50508d6109d2565b610a579250602080918301019101611302565b8d80610a3c565b506103e486610a7f60a0610a7860248601866004016113ee565b013561153b565b610aa76020610a9761047e60248701876004016113ee565b94909560248101906004016113ee565b92865b838110610aef57878787610abc61166f565b9211918215610ae5575b5050610ad3576001815580f35b604051631979776d60e01b8152600490fd5b1090508280610ac6565b6001600160a01b03610b056105a683878661146f565b6040516370a0823160e01b8152306004820152929116602083602481845afa928315610bce578a93610b9a575b50610b3d8286611527565b516020610b4b84898861146f565b01358101809111610b86578310610b7457610b6f9287610b6a926112c4565b611461565b610aaa565b604051632578a3d560e11b8152600490fd5b634e487b7160e01b5f52601160045260245ffd5b9092506020813d602011610bc6575b81610bb660209383610f4a565b810103126102395751918a610b32565b3d9150610ba9565b6040513d8c823e3d90fd5b60405163549964bd60e11b815260206004820152908190610bfe9060248301906110ea565b0390fd5b8480fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166080610c4260248601600487016113ee565b0135813b15610ca757838092602482936040519586938492632e1a7d4d60e01b845260048401525af19182610c8f575b5050610c8a57604051631794833560e21b8152600490fd5b6108a4565b610c9890610f1c565b610ca3578287610c72565b8280fd5b8380fd5b610cb490610f1c565b85610889565b6040513d84823e3d90fd5b825180516001600160a01b03168852602090810151818901528b99508a9850604090970196909201916001016107e1565b929496985092849195979950604080600192838060a01b03610d178a61113f565b1681526020890135602082015201960192018a98969450928b999795939291926107a4565b8780fd5b8580fd5b602090604051610d5381610eed565b898152898382015282828d01015201610548565b60249060206001600160a01b03610d826105a684888861146f565b16604051938480926370a0823160e01b82523060048301525afa8015610dfd578790610dc3575b610dbe9250610db88287611527565b52611461565b6104ed565b50906020813d602011610df5575b81610dde60209383610f4a565b81010312610df15790610dbe9151610da9565b8680fd5b3d9150610dd1565b6040513d89823e3d90fd5b604051634e4372cf60e11b8152600490fd5b50610e3060406103e460248501856004016113ee565b6001600160a01b03163014610467565b60405163446f3eeb60e01b8152600490fd5b604051632c090db360e21b8152600490fd5b604051633ee5aeb560e01b8152600490fd5b50346100cb57806003193601126100cb5761031e610e92610f86565b6040519182916020835260208301906110ea565b905034610ee95781600319360112610ee9577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5080fd5b604081019081106001600160401b03821117610f0857604052565b634e487b7160e01b5f52604160045260245ffd5b6001600160401b038111610f0857604052565b608081019081106001600160401b03821117610f0857604052565b90601f801991011681019081106001600160401b03821117610f0857604052565b6001600160401b038111610f0857601f01601f191660200190565b6040519061014082018281106001600160401b03821117610f0857604052610104825263756e742960e01b610120837f4f70706f7274756e6974795769746e657373207769746e657373294f70706f7260208201527f74756e6974795769746e65737328546f6b656e416d6f756e745b5d206275795460408201527f6f6b656e732c61646472657373206578656375746f722c61646472657373207460608201527f6172676574436f6e74726163742c62797465732074617267657443616c6c646160808201527f74612c75696e743235362074617267657443616c6c56616c75652c75696e743260a08201527f353620626964416d6f756e7429546f6b656e416d6f756e74286164647265737360c08201527f20746f6b656e2c75696e7432353620616d6f756e7429546f6b656e5065726d6960e08201527f7373696f6e73286164647265737320746f6b656e2c75696e7432353620616d6f6101008201520152565b91908251928382525f5b848110611114575050825f602080949584010152601f8019910116010190565b6020818301810151848301820152016110f4565b6001600160401b038111610f085760051b60200190565b35906001600160a01b038216820361023957565b919060c0838203126102395760409283519160c08301916001600160401b039284811084821117610f08578652839581358481116102395782019383601f86011215610239578435946111a586611128565b906111b284519283610f4a565b868252602096878084019160061b83010191878311610239578801905b8282106112605750505086526111e685840161113f565b858701526111f582840161113f565b82870152606083013590811161023957820183601f820112156102395780359361122a61122186610f6b565b93519384610f4a565b84835285858301011161023957848460a0969587965f940183860137830101526060850152608081013560808501520135910152565b858289031261023957888691825161127781610eed565b6112808561113f565b815282850135838201528152019101906111cf565b3d156112bf573d906112a682610f6b565b916112b46040519384610f4a565b82523d5f602084013e565b606090565b60405163a9059cbb60e01b60208201526001600160a01b039290921660248301526044808301939093529181526113009161068f606483610f4a565b565b90816020910312610239575180151581036102395790565b5f806113429260018060a01b03169360208151910182865af161133b611295565b908361138b565b8051908115159182611370575b50506113585750565b60249060405190635274afe760e01b82526004820152fd5b6113839250602080918301019101611302565b155f8061134f565b906113b257508051156113a057805190602001fd5b604051630a12f52160e11b8152600490fd5b815115806113e5575b6113c3575090565b604051639996b31560e01b81526001600160a01b039091166004820152602490fd5b50803b156113bb565b90359060be1981360301821215610239570190565b903590601e198136030182121561023957018035906001600160401b03821161023957602001918160061b3603831361023957565b903590605e1981360301821215610239570190565b356001600160a01b03811681036102395790565b5f198114610b865760010190565b919081101561147f5760061b0190565b634e487b7160e01b5f52603260045260245ffd5b5f90815b8381106114a45750505050565b60018101808211611513575b8481106114c657506114c190611461565b611497565b6114d46105a683878661146f565b6001600160a01b03806114eb6105a6858a8961146f565b16911614611501576114fc90611461565b6114b0565b6040516323271fb560e11b8152600490fd5b634e487b7160e01b84526011600452602484fd5b805182101561147f5760209160051b010190565b5f90801561166b57817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031647838110611600575b50508080927f00000000000000000000000000000000000000000000000000000000000000005af16115a7611295565b50156115af57565b60405162461bcd60e51b8152602060048201526024808201527f426964207472616e7366657220746f20657870726573732072656c61792066616044820152631a5b195960e21b6064820152608490fd5b909150820382811161151357813b15610ca7578391602483926040519485938492632e1a7d4d60e01b845260048401525af19081611658575b5061165057604051632031c40f60e11b8152600490fd5b818080611577565b61166490939193610f1c565b915f611639565b5050565b6040516370a0823160e01b815230600482015290476020836024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa9283156116f7575f936116c857509190565b90926020823d82116116ef575b816116e260209383610f4a565b810103126100cb57505190565b3d91506116d5565b6040513d5f823e3d90fd5b604091825160e081016001600160401b039082811082821117610f0857855260bb8252602060bb8184017f4f70706f7274756e6974795769746e65737328546f6b656e416d6f756e745b5d81527f20627579546f6b656e732c61646472657373206578656375746f722c61646472888601527f647265737320746f6b656e2c75696e7432353620616d6f756e7429000000000060c06060967f65737320746172676574436f6e74726163742c62797465732074617267657443888201527f616c6c646174612c75696e743235362074617267657443616c6c56616c75652c60808201527f75696e7432353620626964416d6f756e7429546f6b656e416d6f756e7428616460a08201520152209385519081519561183661182188611128565b9761182e8b51998a610f4a565b808952611128565b97848801601f19809a013682375f5b85518110156118ef576118588187611527565b51908c51918a83018381108b821117610f08576118ea938f918252602990818152683620616d6f756e742960b81b838d8301927f546f6b656e416d6f756e74286164647265737320746f6b656e2c75696e7432358452015220918a60018060a01b03825116910151908251928c84019485528301528c8201528b81526118dd81610f2f565b519020610db8828d611527565b611845565b5090935098949593969198979097855191828981018095519093905f5b8c82821061199557505050506119289203908101835282610f4a565b5190209160018060a01b0380878401511690858401511690828401518881519101209260a06080860151950151958751998a019a8b52878a0152880152608087015260a086015260c085015260e084015260e0835261010083019183831090831117610f08575251902090565b83518752958601958794509092019160010161190c56fea2646970667358221220797322f89790945f9447121f12f2c5f8b9fb27cdcaa77d6df10908917f7348ed64736f6c63430008140033a264697066735822122026fba97d0c60980bb3a7ca4ba9350b1cbff5283b96ff5cee14361083da22f93f64736f6c63430008140033610120806040523462000171575f60018155608091338352630890357360e41b81528281600481335afa908115620001665782918391848092620000c6575b505060a05261010092835260e05260c052604051906119e292836200018b843951826103a1015260a05182818160e1015281816101ac0152818161026601526103f4015260c051828181609c015261157e015260e051828181610c0801528181610eba01528181611546015261168c0152518181816104330152818161070101526108540152f35b935093505050823d84116200015e575b601f8101601f191683016001600160401b038111848210176200014a5784918491604052810103126200014757506200010f8162000175565b906200011e6020820162000175565b906200013b6060620001336040840162000175565b920162000175565b929190925f806200003e565b80fd5b634e487b7160e01b83526041600452602483fd5b503d620000d6565b6040513d84823e3d90fd5b5f80fd5b51906001600160a01b0382168203620001715756fe608080604052600436101561001c575b50361561001a575f80fd5b005b5f90813560e01c908163107c279f14610ea657508063156e215214610e765780632608ba811461032257806354fd4d50146102d85780636184196a14610295578063893d20e8146102505780638947606914610182578063a0ef91df146100ce5763c9b4518a0361000f57346100cb57806003193601126100cb576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b80fd5b50346100cb57806003193601126100cb577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163381900361017057818080809347905af1610122611295565b501561012b5780f35b60405162461bcd60e51b815260206004820152601860248201527f5769746864726177616c206f6620455448206661696c656400000000000000006044820152606490fd5b6040516308f51d4b60e31b8152600490fd5b50346100cb5760203660031901126100cb576001600160a01b0360043581811690819003610239577f00000000000000000000000000000000000000000000000000000000000000009182163303610170576040516370a0823160e01b815230600482015291602083602481855afa91821561024557849261020c575b61020993506112c4565b80f35b91506020833d821161023d575b8161022660209383610f4a565b81010312610239576102099251916101ff565b5f80fd5b3d9150610219565b6040513d86823e3d90fd5b50346100cb57806003193601126100cb576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b50346100cb5760203660031901126100cb57600435906001600160401b0382116100cb5760206102d06102cb3660048601611153565b611702565b604051908152f35b50346100cb57806003193601126100cb5761031e6040516102f881610eed565b60058152640302e322e360dc1b60208201526040519182916020835260208301906110ea565b0390f35b5060403660031901126100cb57600435906001600160401b0382116100cb57604060031983360301126100cb576001600160401b03602435116100cb573660236024350112156100cb576001600160401b0360243560040135116100cb5736602480356004013581350101116100cb576002815414610e6457600281557f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163303610e52576103ea60206103e460248501856004016113ee565b0161144d565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116911603610e405761043160406103e460248501856004016113ee565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b039081169116148015610e1a575b610e085761048a61048461047e6004850180611438565b80611403565b90611493565b6104a061048461047e60248501856004016113ee565b6104a861166f565b6104be61047e60248695949501866004016113ee565b6104c781611128565b916104d56040519384610f4a565b818352601f196104e483611128565b01366020850137845b828110610d6757506105059150506004860180611438565b9161051660248701876004016113ee565b916105218480611403565b97905061054661053089611128565b9861053e6040519a8b610f4a565b808a52611128565b865b601f1982018110610d44575050855b6105618680611403565b90508110156106d6578060206105846106509361057e8a80611403565b9061146f565b0135816105ab6105a66105978b80611403565b6001600160a01b03949161146f565b61144d565b168b6105cc84604051926105be84610eed565b308452856020850152611527565b526105d7838d611527565b506105e46040890161144d565b60405163095ea7b360e01b602082018181526001600160a01b038416602484015260448084019690965294825293909291908c908190610625606487610f4a565b85519082865af1610634611295565b816106a7575b508061069d575b15610655575b50505050611461565b610557565b60405160208101949094526001600160a01b0316602484015260448084018c905283526106949261068f9061068981610f2f565b8261131a565b61131a565b5f808080610647565b50813b1515610641565b80518015925082156106bc575b50505f61063a565b6106cf9250602080918301019101611302565b5f806106b4565b508686868a876106f66102cb6106ee6020840161144d565b923690611153565b6106fe610f86565b917f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163b15610d405760405163fe8ec1a760e01b815260c060048201529480359036819003601e1901821215610d3c576001600160401b038183013511610d3c578082013560061b360360208284010113610d3c579187959391879593606060c4880152610124870181830135905261014487019160208282010190895b838201358110610cf657505050806020604092013560e4890152013561010487015260031986820301602487015260208086519283815201950190875b818110610cc5575050506001600160a01b031660448501526064840152828203600319016084840152602091839161081991906110ea565b6003198282030160a4830152602480356004810135808452910184830137600460243501358181018401869052601f01601f191601030181837f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af18015610cba57610cab575b5090608061089d60248501856004016113ee565b0135610c06575b6108b960406103e460248601866004016113ee565b6108c960248501856004016113ee565b606081013590601e1981360301821215610c0257018035906001600160401b038211610c02576020018136038113610c0257918492918392608061091360248a018a6004016113ee565b013590826040519384928337810185815203925af1610930611295565b9015610bd957506109446004840180611438565b9461095a60406103e460248701876004016113ee565b93835b6109678880611403565b9050811015610a5e57806109e7916109856105a66105978c80611403565b1660405160208101915f8063095ea7b360e01b9485815260018060a01b038d166024860152816044860152604485526109bd85610f2f565b84519082855af16109cc611295565b81610a2f575b5080610a25575b156109ec575b505050611461565b61095d565b61068f610a1d9360405190602082015260018060a01b038c1660248201525f60448201526044815261068981610f2f565b8980806109df565b50803b15156109d9565b8051801592508215610a44575b50508d6109d2565b610a579250602080918301019101611302565b8d80610a3c565b506103e486610a7f60a0610a7860248601866004016113ee565b013561153b565b610aa76020610a9761047e60248701876004016113ee565b94909560248101906004016113ee565b92865b838110610aef57878787610abc61166f565b9211918215610ae5575b5050610ad3576001815580f35b604051631979776d60e01b8152600490fd5b1090508280610ac6565b6001600160a01b03610b056105a683878661146f565b6040516370a0823160e01b8152306004820152929116602083602481845afa928315610bce578a93610b9a575b50610b3d8286611527565b516020610b4b84898861146f565b01358101809111610b86578310610b7457610b6f9287610b6a926112c4565b611461565b610aaa565b604051632578a3d560e11b8152600490fd5b634e487b7160e01b5f52601160045260245ffd5b9092506020813d602011610bc6575b81610bb660209383610f4a565b810103126102395751918a610b32565b3d9150610ba9565b6040513d8c823e3d90fd5b60405163549964bd60e11b815260206004820152908190610bfe9060248301906110ea565b0390fd5b8480fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166080610c4260248601600487016113ee565b0135813b15610ca757838092602482936040519586938492632e1a7d4d60e01b845260048401525af19182610c8f575b5050610c8a57604051631794833560e21b8152600490fd5b6108a4565b610c9890610f1c565b610ca3578287610c72565b8280fd5b8380fd5b610cb490610f1c565b85610889565b6040513d84823e3d90fd5b825180516001600160a01b03168852602090810151818901528b99508a9850604090970196909201916001016107e1565b929496985092849195979950604080600192838060a01b03610d178a61113f565b1681526020890135602082015201960192018a98969450928b999795939291926107a4565b8780fd5b8580fd5b602090604051610d5381610eed565b898152898382015282828d01015201610548565b60249060206001600160a01b03610d826105a684888861146f565b16604051938480926370a0823160e01b82523060048301525afa8015610dfd578790610dc3575b610dbe9250610db88287611527565b52611461565b6104ed565b50906020813d602011610df5575b81610dde60209383610f4a565b81010312610df15790610dbe9151610da9565b8680fd5b3d9150610dd1565b6040513d89823e3d90fd5b604051634e4372cf60e11b8152600490fd5b50610e3060406103e460248501856004016113ee565b6001600160a01b03163014610467565b60405163446f3eeb60e01b8152600490fd5b604051632c090db360e21b8152600490fd5b604051633ee5aeb560e01b8152600490fd5b50346100cb57806003193601126100cb5761031e610e92610f86565b6040519182916020835260208301906110ea565b905034610ee95781600319360112610ee9577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5080fd5b604081019081106001600160401b03821117610f0857604052565b634e487b7160e01b5f52604160045260245ffd5b6001600160401b038111610f0857604052565b608081019081106001600160401b03821117610f0857604052565b90601f801991011681019081106001600160401b03821117610f0857604052565b6001600160401b038111610f0857601f01601f191660200190565b6040519061014082018281106001600160401b03821117610f0857604052610104825263756e742960e01b610120837f4f70706f7274756e6974795769746e657373207769746e657373294f70706f7260208201527f74756e6974795769746e65737328546f6b656e416d6f756e745b5d206275795460408201527f6f6b656e732c61646472657373206578656375746f722c61646472657373207460608201527f6172676574436f6e74726163742c62797465732074617267657443616c6c646160808201527f74612c75696e743235362074617267657443616c6c56616c75652c75696e743260a08201527f353620626964416d6f756e7429546f6b656e416d6f756e74286164647265737360c08201527f20746f6b656e2c75696e7432353620616d6f756e7429546f6b656e5065726d6960e08201527f7373696f6e73286164647265737320746f6b656e2c75696e7432353620616d6f6101008201520152565b91908251928382525f5b848110611114575050825f602080949584010152601f8019910116010190565b6020818301810151848301820152016110f4565b6001600160401b038111610f085760051b60200190565b35906001600160a01b038216820361023957565b919060c0838203126102395760409283519160c08301916001600160401b039284811084821117610f08578652839581358481116102395782019383601f86011215610239578435946111a586611128565b906111b284519283610f4a565b868252602096878084019160061b83010191878311610239578801905b8282106112605750505086526111e685840161113f565b858701526111f582840161113f565b82870152606083013590811161023957820183601f820112156102395780359361122a61122186610f6b565b93519384610f4a565b84835285858301011161023957848460a0969587965f940183860137830101526060850152608081013560808501520135910152565b858289031261023957888691825161127781610eed565b6112808561113f565b815282850135838201528152019101906111cf565b3d156112bf573d906112a682610f6b565b916112b46040519384610f4a565b82523d5f602084013e565b606090565b60405163a9059cbb60e01b60208201526001600160a01b039290921660248301526044808301939093529181526113009161068f606483610f4a565b565b90816020910312610239575180151581036102395790565b5f806113429260018060a01b03169360208151910182865af161133b611295565b908361138b565b8051908115159182611370575b50506113585750565b60249060405190635274afe760e01b82526004820152fd5b6113839250602080918301019101611302565b155f8061134f565b906113b257508051156113a057805190602001fd5b604051630a12f52160e11b8152600490fd5b815115806113e5575b6113c3575090565b604051639996b31560e01b81526001600160a01b039091166004820152602490fd5b50803b156113bb565b90359060be1981360301821215610239570190565b903590601e198136030182121561023957018035906001600160401b03821161023957602001918160061b3603831361023957565b903590605e1981360301821215610239570190565b356001600160a01b03811681036102395790565b5f198114610b865760010190565b919081101561147f5760061b0190565b634e487b7160e01b5f52603260045260245ffd5b5f90815b8381106114a45750505050565b60018101808211611513575b8481106114c657506114c190611461565b611497565b6114d46105a683878661146f565b6001600160a01b03806114eb6105a6858a8961146f565b16911614611501576114fc90611461565b6114b0565b6040516323271fb560e11b8152600490fd5b634e487b7160e01b84526011600452602484fd5b805182101561147f5760209160051b010190565b5f90801561166b57817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031647838110611600575b50508080927f00000000000000000000000000000000000000000000000000000000000000005af16115a7611295565b50156115af57565b60405162461bcd60e51b8152602060048201526024808201527f426964207472616e7366657220746f20657870726573732072656c61792066616044820152631a5b195960e21b6064820152608490fd5b909150820382811161151357813b15610ca7578391602483926040519485938492632e1a7d4d60e01b845260048401525af19081611658575b5061165057604051632031c40f60e11b8152600490fd5b818080611577565b61166490939193610f1c565b915f611639565b5050565b6040516370a0823160e01b815230600482015290476020836024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa9283156116f7575f936116c857509190565b90926020823d82116116ef575b816116e260209383610f4a565b810103126100cb57505190565b3d91506116d5565b6040513d5f823e3d90fd5b604091825160e081016001600160401b039082811082821117610f0857855260bb8252602060bb8184017f4f70706f7274756e6974795769746e65737328546f6b656e416d6f756e745b5d81527f20627579546f6b656e732c61646472657373206578656375746f722c61646472888601527f647265737320746f6b656e2c75696e7432353620616d6f756e7429000000000060c06060967f65737320746172676574436f6e74726163742c62797465732074617267657443888201527f616c6c646174612c75696e743235362074617267657443616c6c56616c75652c60808201527f75696e7432353620626964416d6f756e7429546f6b656e416d6f756e7428616460a08201520152209385519081519561183661182188611128565b9761182e8b51998a610f4a565b808952611128565b97848801601f19809a013682375f5b85518110156118ef576118588187611527565b51908c51918a83018381108b821117610f08576118ea938f918252602990818152683620616d6f756e742960b81b838d8301927f546f6b656e416d6f756e74286164647265737320746f6b656e2c75696e7432358452015220918a60018060a01b03825116910151908251928c84019485528301528c8201528b81526118dd81610f2f565b519020610db8828d611527565b611845565b5090935098949593969198979097855191828981018095519093905f5b8c82821061199557505050506119289203908101835282610f4a565b5190209160018060a01b0380878401511690858401511690828401518881519101209260a06080860151950151958751998a019a8b52878a0152880152608087015260a086015260c085015260e084015260e0835261010083019183831090831117610f08575251902090565b83518752958601958794509092019160010161190c56fea2646970667358221220797322f89790945f9447121f12f2c5f8b9fb27cdcaa77d6df10908917f7348ed64736f6c63430008140033","sourceMap":"330:3317:88:-:0;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;:::i;:::-;1713:1:56;-1:-1:-1;330:3317:88;;;;;;;;;;;;;;;;;;1713:1:56;330:3317:88;;;1713:1:56;330:3317:88;;;1031:12;330:3317;;;1031:12;330:3317;;;1053:18;330:3317;;;1053:18;330:3317;1103:37;;330:3317;1103:37;;;:::i;:::-;;;;330:3317;1103:37;;;;;;330:3317;1093:48;;1081:60;330:3317;;;;;;;;;;;-1:-1:-1;330:3317:88;;;;;;;;;-1:-1:-1;;330:3317:88;;;-1:-1:-1;;;;;330:3317:88;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;-1:-1:-1;;;;;330:3317:88;;;;;;:::o","linkReferences":{}},"deployedBytecode":{"object":"0x6080806040526004361015610012575f80fd5b5f90813560e01c908163107c279f146104f5575080631bbf2e23146104cc5780632608ba81146101615780633e239349146101435780634e1d91d81461011f57806389035730146100d7578063acf461f9146100a15763c9b4518a14610076575f80fd5b3461009e578060031936011261009e576001546040516001600160a01b039091168152602090f35b80fd5b503461009e57602036600319011261009e5760206100c56100c061051a565b610548565b6040516001600160a01b039091168152f35b503461009e578060031936011261009e57608060018060a01b038060055416908060065416908060075416906008541691604051938452602084015260408301526060820152f35b503461009e57602036600319011261009e5760206100c561013e61051a565b610658565b503461009e578060031936011261009e576020600454604051908152f35b50604036600319011261009e5767ffffffffffffffff6004351161009e576004356004016040600319600435360301126104c85767ffffffffffffffff602435116104c8573660236024350112156104c85767ffffffffffffffff60243560040135116104c85736602480356004013581350101116104c85760028254146104b657600282556001546001600160a01b031633036104a45761021661013e602061021060246004350185610683565b01610698565b63ffffffff813b1615610487575b6001600160a01b0381163b156104835760405191632608ba8160e01b835260406004840152359060621960043536030182121561047f576040604484015260e483019161027760048035830101806106ac565b6060608487015293849052610104850193865b8181106104615750505060043590810160248181013560a48701526044919091013560c486015281013590360360c2190181121561045d578383036043190160648501528492919060c08301906102e760048035830101806106ac565b60c086529283905260e0850192865b81811061043557506001600160a01b03915061031a90506004358301602401610534565b1660208501526001600160a01b036103386004358301604401610534565b166040850152600435810160648101359036036022190181121561043157600435820101906024600483013592019067ffffffffffffffff831161042d57823603821361042d578560a060a461039f878c9a976103d4978c9a998b9a036060880152610701565b936084600435820101356080850152600435010135910152600319838203016024840152602435600401356024803501610701565b039134906001600160a01b03165af18015610422576103f6575b506001815580f35b67ffffffffffffffff811161040e576040525f6103ee565b634e487b7160e01b82526041600452602482fd5b6040513d84823e3d90fd5b8680fd5b8580fd5b919495965091926040808261044c600194896106e1565b0195019101918896959493926102f6565b8480fd5b909194604080826104746001948a6106e1565b01960192910161028a565b8380fd5b8280fd5b61049e6100c0602061021060246004350186610683565b50610224565b604051631aacd19160e31b8152600490fd5b604051633ee5aeb560e01b8152600490fd5b5080fd5b503461009e578060031936011261009e576003546040516001600160a01b039091168152602090f35b9050346104c857816003193601126104c8576002546001600160a01b03168152602090f35b600435906001600160a01b038216820361053057565b5f80fd5b35906001600160a01b038216820361053057565b60018060a01b038091168160015416908260025416836003541690604093845192608084019267ffffffffffffffff948085108686111761064457606087959186928a52858152836020820152848a82015201526bffffffffffffffffffffffff60a01b928360055416176005558260065416176006558160075416176007556008541617600855611b6d90835190601f19603f84011682019082821090821117610644578452818152602081019161072283398051156106335751905ff59182161561062357505f6005555f6006555f6007555f60085590565b51633a0ba96160e11b8152600490fd5b8351631328927760e21b8152600490fd5b634e487b7160e01b5f52604160045260245ffd5b600b6055916004549060405191604083015260018060a01b031660208201523081520160ff81532090565b90359060be1981360301821215610530570190565b356001600160a01b03811681036105305790565b9035601e198236030181121561053057016020813591019167ffffffffffffffff8211610530578160061b3603831361053057565b60209081906001600160a01b036106f782610534565b1684520135910152565b908060209392818452848401375f828201840152601f01601f191601019056fe610120806040523462000171575f60018155608091338352630890357360e41b81528281600481335afa908115620001665782918391848092620000c6575b505060a05261010092835260e05260c052604051906119e292836200018b843951826103a1015260a05182818160e1015281816101ac0152818161026601526103f4015260c051828181609c015261157e015260e051828181610c0801528181610eba01528181611546015261168c0152518181816104330152818161070101526108540152f35b935093505050823d84116200015e575b601f8101601f191683016001600160401b038111848210176200014a5784918491604052810103126200014757506200010f8162000175565b906200011e6020820162000175565b906200013b6060620001336040840162000175565b920162000175565b929190925f806200003e565b80fd5b634e487b7160e01b83526041600452602483fd5b503d620000d6565b6040513d84823e3d90fd5b5f80fd5b51906001600160a01b0382168203620001715756fe608080604052600436101561001c575b50361561001a575f80fd5b005b5f90813560e01c908163107c279f14610ea657508063156e215214610e765780632608ba811461032257806354fd4d50146102d85780636184196a14610295578063893d20e8146102505780638947606914610182578063a0ef91df146100ce5763c9b4518a0361000f57346100cb57806003193601126100cb576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b80fd5b50346100cb57806003193601126100cb577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163381900361017057818080809347905af1610122611295565b501561012b5780f35b60405162461bcd60e51b815260206004820152601860248201527f5769746864726177616c206f6620455448206661696c656400000000000000006044820152606490fd5b6040516308f51d4b60e31b8152600490fd5b50346100cb5760203660031901126100cb576001600160a01b0360043581811690819003610239577f00000000000000000000000000000000000000000000000000000000000000009182163303610170576040516370a0823160e01b815230600482015291602083602481855afa91821561024557849261020c575b61020993506112c4565b80f35b91506020833d821161023d575b8161022660209383610f4a565b81010312610239576102099251916101ff565b5f80fd5b3d9150610219565b6040513d86823e3d90fd5b50346100cb57806003193601126100cb576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b50346100cb5760203660031901126100cb57600435906001600160401b0382116100cb5760206102d06102cb3660048601611153565b611702565b604051908152f35b50346100cb57806003193601126100cb5761031e6040516102f881610eed565b60058152640302e322e360dc1b60208201526040519182916020835260208301906110ea565b0390f35b5060403660031901126100cb57600435906001600160401b0382116100cb57604060031983360301126100cb576001600160401b03602435116100cb573660236024350112156100cb576001600160401b0360243560040135116100cb5736602480356004013581350101116100cb576002815414610e6457600281557f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163303610e52576103ea60206103e460248501856004016113ee565b0161144d565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116911603610e405761043160406103e460248501856004016113ee565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b039081169116148015610e1a575b610e085761048a61048461047e6004850180611438565b80611403565b90611493565b6104a061048461047e60248501856004016113ee565b6104a861166f565b6104be61047e60248695949501866004016113ee565b6104c781611128565b916104d56040519384610f4a565b818352601f196104e483611128565b01366020850137845b828110610d6757506105059150506004860180611438565b9161051660248701876004016113ee565b916105218480611403565b97905061054661053089611128565b9861053e6040519a8b610f4a565b808a52611128565b865b601f1982018110610d44575050855b6105618680611403565b90508110156106d6578060206105846106509361057e8a80611403565b9061146f565b0135816105ab6105a66105978b80611403565b6001600160a01b03949161146f565b61144d565b168b6105cc84604051926105be84610eed565b308452856020850152611527565b526105d7838d611527565b506105e46040890161144d565b60405163095ea7b360e01b602082018181526001600160a01b038416602484015260448084019690965294825293909291908c908190610625606487610f4a565b85519082865af1610634611295565b816106a7575b508061069d575b15610655575b50505050611461565b610557565b60405160208101949094526001600160a01b0316602484015260448084018c905283526106949261068f9061068981610f2f565b8261131a565b61131a565b5f808080610647565b50813b1515610641565b80518015925082156106bc575b50505f61063a565b6106cf9250602080918301019101611302565b5f806106b4565b508686868a876106f66102cb6106ee6020840161144d565b923690611153565b6106fe610f86565b917f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163b15610d405760405163fe8ec1a760e01b815260c060048201529480359036819003601e1901821215610d3c576001600160401b038183013511610d3c578082013560061b360360208284010113610d3c579187959391879593606060c4880152610124870181830135905261014487019160208282010190895b838201358110610cf657505050806020604092013560e4890152013561010487015260031986820301602487015260208086519283815201950190875b818110610cc5575050506001600160a01b031660448501526064840152828203600319016084840152602091839161081991906110ea565b6003198282030160a4830152602480356004810135808452910184830137600460243501358181018401869052601f01601f191601030181837f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af18015610cba57610cab575b5090608061089d60248501856004016113ee565b0135610c06575b6108b960406103e460248601866004016113ee565b6108c960248501856004016113ee565b606081013590601e1981360301821215610c0257018035906001600160401b038211610c02576020018136038113610c0257918492918392608061091360248a018a6004016113ee565b013590826040519384928337810185815203925af1610930611295565b9015610bd957506109446004840180611438565b9461095a60406103e460248701876004016113ee565b93835b6109678880611403565b9050811015610a5e57806109e7916109856105a66105978c80611403565b1660405160208101915f8063095ea7b360e01b9485815260018060a01b038d166024860152816044860152604485526109bd85610f2f565b84519082855af16109cc611295565b81610a2f575b5080610a25575b156109ec575b505050611461565b61095d565b61068f610a1d9360405190602082015260018060a01b038c1660248201525f60448201526044815261068981610f2f565b8980806109df565b50803b15156109d9565b8051801592508215610a44575b50508d6109d2565b610a579250602080918301019101611302565b8d80610a3c565b506103e486610a7f60a0610a7860248601866004016113ee565b013561153b565b610aa76020610a9761047e60248701876004016113ee565b94909560248101906004016113ee565b92865b838110610aef57878787610abc61166f565b9211918215610ae5575b5050610ad3576001815580f35b604051631979776d60e01b8152600490fd5b1090508280610ac6565b6001600160a01b03610b056105a683878661146f565b6040516370a0823160e01b8152306004820152929116602083602481845afa928315610bce578a93610b9a575b50610b3d8286611527565b516020610b4b84898861146f565b01358101809111610b86578310610b7457610b6f9287610b6a926112c4565b611461565b610aaa565b604051632578a3d560e11b8152600490fd5b634e487b7160e01b5f52601160045260245ffd5b9092506020813d602011610bc6575b81610bb660209383610f4a565b810103126102395751918a610b32565b3d9150610ba9565b6040513d8c823e3d90fd5b60405163549964bd60e11b815260206004820152908190610bfe9060248301906110ea565b0390fd5b8480fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166080610c4260248601600487016113ee565b0135813b15610ca757838092602482936040519586938492632e1a7d4d60e01b845260048401525af19182610c8f575b5050610c8a57604051631794833560e21b8152600490fd5b6108a4565b610c9890610f1c565b610ca3578287610c72565b8280fd5b8380fd5b610cb490610f1c565b85610889565b6040513d84823e3d90fd5b825180516001600160a01b03168852602090810151818901528b99508a9850604090970196909201916001016107e1565b929496985092849195979950604080600192838060a01b03610d178a61113f565b1681526020890135602082015201960192018a98969450928b999795939291926107a4565b8780fd5b8580fd5b602090604051610d5381610eed565b898152898382015282828d01015201610548565b60249060206001600160a01b03610d826105a684888861146f565b16604051938480926370a0823160e01b82523060048301525afa8015610dfd578790610dc3575b610dbe9250610db88287611527565b52611461565b6104ed565b50906020813d602011610df5575b81610dde60209383610f4a565b81010312610df15790610dbe9151610da9565b8680fd5b3d9150610dd1565b6040513d89823e3d90fd5b604051634e4372cf60e11b8152600490fd5b50610e3060406103e460248501856004016113ee565b6001600160a01b03163014610467565b60405163446f3eeb60e01b8152600490fd5b604051632c090db360e21b8152600490fd5b604051633ee5aeb560e01b8152600490fd5b50346100cb57806003193601126100cb5761031e610e92610f86565b6040519182916020835260208301906110ea565b905034610ee95781600319360112610ee9577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5080fd5b604081019081106001600160401b03821117610f0857604052565b634e487b7160e01b5f52604160045260245ffd5b6001600160401b038111610f0857604052565b608081019081106001600160401b03821117610f0857604052565b90601f801991011681019081106001600160401b03821117610f0857604052565b6001600160401b038111610f0857601f01601f191660200190565b6040519061014082018281106001600160401b03821117610f0857604052610104825263756e742960e01b610120837f4f70706f7274756e6974795769746e657373207769746e657373294f70706f7260208201527f74756e6974795769746e65737328546f6b656e416d6f756e745b5d206275795460408201527f6f6b656e732c61646472657373206578656375746f722c61646472657373207460608201527f6172676574436f6e74726163742c62797465732074617267657443616c6c646160808201527f74612c75696e743235362074617267657443616c6c56616c75652c75696e743260a08201527f353620626964416d6f756e7429546f6b656e416d6f756e74286164647265737360c08201527f20746f6b656e2c75696e7432353620616d6f756e7429546f6b656e5065726d6960e08201527f7373696f6e73286164647265737320746f6b656e2c75696e7432353620616d6f6101008201520152565b91908251928382525f5b848110611114575050825f602080949584010152601f8019910116010190565b6020818301810151848301820152016110f4565b6001600160401b038111610f085760051b60200190565b35906001600160a01b038216820361023957565b919060c0838203126102395760409283519160c08301916001600160401b039284811084821117610f08578652839581358481116102395782019383601f86011215610239578435946111a586611128565b906111b284519283610f4a565b868252602096878084019160061b83010191878311610239578801905b8282106112605750505086526111e685840161113f565b858701526111f582840161113f565b82870152606083013590811161023957820183601f820112156102395780359361122a61122186610f6b565b93519384610f4a565b84835285858301011161023957848460a0969587965f940183860137830101526060850152608081013560808501520135910152565b858289031261023957888691825161127781610eed565b6112808561113f565b815282850135838201528152019101906111cf565b3d156112bf573d906112a682610f6b565b916112b46040519384610f4a565b82523d5f602084013e565b606090565b60405163a9059cbb60e01b60208201526001600160a01b039290921660248301526044808301939093529181526113009161068f606483610f4a565b565b90816020910312610239575180151581036102395790565b5f806113429260018060a01b03169360208151910182865af161133b611295565b908361138b565b8051908115159182611370575b50506113585750565b60249060405190635274afe760e01b82526004820152fd5b6113839250602080918301019101611302565b155f8061134f565b906113b257508051156113a057805190602001fd5b604051630a12f52160e11b8152600490fd5b815115806113e5575b6113c3575090565b604051639996b31560e01b81526001600160a01b039091166004820152602490fd5b50803b156113bb565b90359060be1981360301821215610239570190565b903590601e198136030182121561023957018035906001600160401b03821161023957602001918160061b3603831361023957565b903590605e1981360301821215610239570190565b356001600160a01b03811681036102395790565b5f198114610b865760010190565b919081101561147f5760061b0190565b634e487b7160e01b5f52603260045260245ffd5b5f90815b8381106114a45750505050565b60018101808211611513575b8481106114c657506114c190611461565b611497565b6114d46105a683878661146f565b6001600160a01b03806114eb6105a6858a8961146f565b16911614611501576114fc90611461565b6114b0565b6040516323271fb560e11b8152600490fd5b634e487b7160e01b84526011600452602484fd5b805182101561147f5760209160051b010190565b5f90801561166b57817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031647838110611600575b50508080927f00000000000000000000000000000000000000000000000000000000000000005af16115a7611295565b50156115af57565b60405162461bcd60e51b8152602060048201526024808201527f426964207472616e7366657220746f20657870726573732072656c61792066616044820152631a5b195960e21b6064820152608490fd5b909150820382811161151357813b15610ca7578391602483926040519485938492632e1a7d4d60e01b845260048401525af19081611658575b5061165057604051632031c40f60e11b8152600490fd5b818080611577565b61166490939193610f1c565b915f611639565b5050565b6040516370a0823160e01b815230600482015290476020836024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa9283156116f7575f936116c857509190565b90926020823d82116116ef575b816116e260209383610f4a565b810103126100cb57505190565b3d91506116d5565b6040513d5f823e3d90fd5b604091825160e081016001600160401b039082811082821117610f0857855260bb8252602060bb8184017f4f70706f7274756e6974795769746e65737328546f6b656e416d6f756e745b5d81527f20627579546f6b656e732c61646472657373206578656375746f722c61646472888601527f647265737320746f6b656e2c75696e7432353620616d6f756e7429000000000060c06060967f65737320746172676574436f6e74726163742c62797465732074617267657443888201527f616c6c646174612c75696e743235362074617267657443616c6c56616c75652c60808201527f75696e7432353620626964416d6f756e7429546f6b656e416d6f756e7428616460a08201520152209385519081519561183661182188611128565b9761182e8b51998a610f4a565b808952611128565b97848801601f19809a013682375f5b85518110156118ef576118588187611527565b51908c51918a83018381108b821117610f08576118ea938f918252602990818152683620616d6f756e742960b81b838d8301927f546f6b656e416d6f756e74286164647265737320746f6b656e2c75696e7432358452015220918a60018060a01b03825116910151908251928c84019485528301528c8201528b81526118dd81610f2f565b519020610db8828d611527565b611845565b5090935098949593969198979097855191828981018095519093905f5b8c82821061199557505050506119289203908101835282610f4a565b5190209160018060a01b0380878401511690858401511690828401518881519101209260a06080860151950151958751998a019a8b52878a0152880152608087015260a086015260c085015260e084015260e0835261010083019183831090831117610f08575251902090565b83518752958601958794509092019160010161190c56fea2646970667358221220797322f89790945f9447121f12f2c5f8b9fb27cdcaa77d6df10908917f7348ed64736f6c63430008140033a264697066735822122026fba97d0c60980bb3a7ca4ba9350b1cbff5283b96ff5cee14361083da22f93f64736f6c63430008140033","sourceMap":"330:3317:88:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;330:3317:88;;;;;;;;;;;;;;;;;;-1:-1:-1;;330:3317:88;;;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;330:3317:88;;;;;;;;;;;;;;;;;;;;;;;;;;649:37;330:3317;;;;649:37;330:3317;;;;649:37;330:3317;;;649:37;330:3317;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;330:3317:88;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;330:3317:88;;-1:-1:-1;;330:3317:88;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1755:1:56;330:3317:88;;2558:18:56;2554:86;;1755:1;;;330:3317:88;;-1:-1:-1;;;;;330:3317:88;3134:10;:27;3130:90;;3254:39;3269:23;330:3317;3269:14;330:3317;;;3269:14;;;:::i;:::-;:23;;:::i;3254:39::-;330:3317;1737:58;;330:3317;1812:8;3303:97;;330:3317;-1:-1:-1;;;;;330:3317:88;;3517:121;;;;330:3317;;;;;;3517:121;;330:3317;;3517:121;;330:3317;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;330:3317:88;;;;;;;;;;;;;;;;;;;;;;;;3269:14;;330:3317;;;;-1:-1:-1;;330:3317:88;;;;;;;;;-1:-1:-1;;330:3317:88;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;330:3317:88;-1:-1:-1;330:3317:88;;-1:-1:-1;330:3317:88;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;;;;330:3317:88;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;-1:-1:-1;;330:3317:88;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3517:121;;3600:9;;-1:-1:-1;;;;;330:3317:88;3517:121;;;;;;;;330:3317;1755:1:56;330:3317:88;1755:1:56;;330:3317:88;;3517:121;330:3317;;;;;;;3517:121;;;330:3317;-1:-1:-1;;;330:3317:88;;;;;;;;3517:121;330:3317;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;3517:121;330:3317;;;3303:97;3351:38;3365:23;330:3317;3365:14;330:3317;;;3269:14;3365;;:::i;3351:38::-;;3303:97;;3130:90;330:3317;;-1:-1:-1;;;3184:25:88;;330:3317;;3184:25;2554:86:56;330:3317:88;;-1:-1:-1;;;2599:30:56;;330:3317:88;;2599:30:56;330:3317:88;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;330:3317:88;;;;;;;;;;;;;;;;;;;;;;2223:5;330:3317;-1:-1:-1;;;;;330:3317:88;;;;;;;;;;-1:-1:-1;;;;;330:3317:88;;;;;;:::o;:::-;;;;;;;-1:-1:-1;;;;;330:3317:88;;;;;;:::o;1154:482::-;330:3317;;;;;;;;;;;;;;1369:5;330:3317;;;1397:8;330:3317;;;;;;;;;;;;;;;;;;;;;;;1297:145;330:3317;;;;;;;;;;1297:145;;;;330:3317;1297:145;;;;330:3317;1297:145;330:3317;;;;;;1284:158;330:3317;;;1284:158;330:3317;;;;;;;;;;;;;;;;;;;;;1531:37;330:3317;;;;;;;;;;;;;;;;;;;;;;;;1531:37;;;1297:145;1531:37;;;;;;330:3317;;1662:20:55;1658:80;;1790:100;;-1:-1:-1;1790:100:55;330:3317:88;;;1903:18:55;1899:81;;330:3317:88;-1:-1:-1;1284:158:88;330:3317;-1:-1:-1;330:3317:88;;-1:-1:-1;330:3317:88;;-1:-1:-1;330:3317:88;;1154:482;:::o;1899:81:55:-;330:3317:88;-1:-1:-1;;;1944:25:55;;;;;1658:80;330:3317:88;;-1:-1:-1;;;1705:22:55;;;;;330:3317:88;;;;;;;;;;;;1834:189;2766:1598:55;;1834:189:88;2006:9;330:3317;2766:1598:55;;;;;;;;330:3317:88;;;;;;2766:1598:55;;;;2342:4;2766:1598;;;;;;;1834:189:88;:::o;330:3317::-;;;;;;;;;;;;;;;;;:::o;:::-;;-1:-1:-1;;;;;330:3317:88;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;-1:-1:-1;;;;;330:3317:88;;;:::i;:::-;;;;;;;;;:::o;:::-;;;;;;;;;;;;;-1:-1:-1;330:3317:88;;;;;;;;-1:-1:-1;;330:3317:88;;;;:::o","linkReferences":{}},"methodIdentifiers":{"computeAddress(address)":"4e1d91d8","createAdapter(address)":"acf461f9","executeOpportunity((((address,uint256)[],uint256,uint256),((address,uint256)[],address,address,bytes,uint256,uint256)),bytes)":"2608ba81","getExpressRelay()":"c9b4518a","getOpportunityAdapterCreationCodeHash()":"3e239349","getPermit2()":"1bbf2e23","getWeth()":"107c279f","parameters()":"89035730"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.20+commit.a1b79de6\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"expressRelay\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"weth\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"permit2\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"Create2EmptyBytecode\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Create2FailedDeployment\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"Create2InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotCalledByExpressRelay\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrancyGuardReentrantCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"computeAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"createAdapter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct ISignatureTransfer.TokenPermissions[]\",\"name\":\"permitted\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"}],\"internalType\":\"struct ISignatureTransfer.PermitBatchTransferFrom\",\"name\":\"permit\",\"type\":\"tuple\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct TokenAmount[]\",\"name\":\"buyTokens\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"executor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"targetContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"targetCalldata\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"targetCallValue\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"bidAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct ExecutionWitness\",\"name\":\"witness\",\"type\":\"tuple\"}],\"internalType\":\"struct ExecutionParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"executeOpportunity\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpressRelay\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOpportunityAdapterCreationCodeHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPermit2\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getWeth\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"parameters\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"expressRelay\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"weth\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"permit2\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"errors\":{\"Create2EmptyBytecode()\":[{\"details\":\"There's no code to deploy.\"}],\"Create2FailedDeployment()\":[{\"details\":\"The deployment failed.\"}],\"Create2InsufficientBalance(uint256,uint256)\":[{\"details\":\"Not enough balance for performing a CREATE2 deploy.\"}],\"ReentrancyGuardReentrantCall()\":[{\"details\":\"Unauthorized reentrant call.\"}]},\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"expressRelay\":\": address of express relay\",\"permit2\":\": address of permit2 contract\",\"weth\":\": address of WETH contract\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"OpportunityAdapterFactory constructor\"},\"getExpressRelay()\":{\"notice\":\"getExpressRelay function - returns the address of the express relay authenticated for calling this contract\"},\"getOpportunityAdapterCreationCodeHash()\":{\"notice\":\"getOpportunityAdapterCreationCodeHash - returns the hash of the creation code of the opportunity adapter contract\"},\"getPermit2()\":{\"notice\":\"getPermit2 function - returns the address of the permit2 contract used for token approvals\"},\"getWeth()\":{\"notice\":\"getWeth function - returns the address of the WETH contract used for wrapping and unwrapping ETH\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/opportunity-adapter/OpportunityAdapterFactory.sol\":\"OpportunityAdapterFactory\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@pythnetwork/express-relay-sdk-solidity/=node_modules/@pythnetwork/express-relay-sdk-solidity/\",\":@pythnetwork/pyth-sdk-solidity/=node_modules/@pythnetwork/pyth-sdk-solidity/\",\":ExcessivelySafeCall/=lib/ExcessivelySafeCall/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/\",\":forge-gas-snapshot/=lib/permit2/lib/forge-gas-snapshot/src/\",\":forge-std/=lib/forge-std/src/\",\":halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":openzeppelin/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":permit2/=lib/permit2/src/\",\":solmate/=lib/permit2/lib/solmate/src/\"],\"viaIR\":true},\"sources\":{\"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0xc6a8ff0ea489379b61faa647490411b80102578440ab9d84e9a957cc12164e70\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://0ea104e577e63faea3b69c415637e99e755dcbf64c5833d7140c35a714d6d90c\",\"dweb:/ipfs/Qmau6x4Ns9XdyynRCNNp3RhLqijJjFm7z5fyZazfYFGYdq\"]},\"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"keccak256\":\"0x6008dabfe393240d73d7dd7688033f72740d570aa422254d29a7dce8568f3aff\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f5196ec75139918c6c7bb4251b36395e668f1fa6d206beba7e7520e74913940d\",\"dweb:/ipfs/QmSyqjksXxmm2mCG6qRd1yuwLykypkSVBbnBnGqJRcuJMi\"]},\"lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol\":{\"keccak256\":\"0x37bb49513c49c87c4642a891b13b63571bc87013dde806617aa1efb54605f386\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b3036b3a83b7c48f96641f2a9002b9f2dcb6a5958dd670894ada21ae8229b3d0\",\"dweb:/ipfs/QmUNfSBdoVtjhETaUJCYcaC7pTMgbhht926tJ2uXJbiVd3\"]},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xaf28a975a78550e45f65e559a3ad6a5ad43b9b8a37366999abd1b7084eb70721\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b7bd24e224f67f65bfadf85dc2929fa965456bb2415478bd0125471b5ce35245\",\"dweb:/ipfs/QmRaydGr8BTHs1kvaZfsNU69pKzUAGFrvABn1KiRSbE51y\"]},\"lib/openzeppelin-contracts/contracts/utils/Create2.sol\":{\"keccak256\":\"0x2b9807d194b92f1068d868e9587d27037264a9a067c778486f86ae21c61cbd5e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://22d71f40aa38a20cf466d8647452a6e3f746353474f8c8af40f03aa8cae38420\",\"dweb:/ipfs/QmQ752Hz5av7YDK8pFojzb5qgeXQvfsdkdwkHVzaXoYAZR\"]},\"lib/openzeppelin-contracts/contracts/utils/ReentrancyGuard.sol\":{\"keccak256\":\"0xf980daa263b661ab8ddee7d4fd833c7da7e7995e2c359ff1f17e67e4112f2236\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://7448ab095d6940130bcf76ba47a2eab14148c83119523b93dd89f6d84edd6c02\",\"dweb:/ipfs/QmawrZ4voKQjH3oomXT3Kuheb3Mnmo2VvVpxg8Ne5UJUrd\"]},\"lib/openzeppelin-contracts/contracts/utils/Strings.sol\":{\"keccak256\":\"0x55f102ea785d8399c0e58d1108e2d289506dde18abc6db1b7f68c1f9f9bc5792\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6e52e0a7765c943ef14e5bcf11e46e6139fa044be564881378349236bf2e3453\",\"dweb:/ipfs/QmZEeeXoFPW47amyP35gfzomF9DixqqTEPwzBakv6cZw6i\"]},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0x005ec64c6313f0555d59e278f9a7a5ab2db5bdc72a027f255a37c327af1ec02d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4ece9f0b9c8daca08c76b6b5405a6446b6f73b3a15fab7ff56e296cbd4a2c875\",\"dweb:/ipfs/QmQyRpyPRL5SQuAgj6SHmbir3foX65FJjbVTTQrA2EFg6L\"]},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0x5f7e4076e175393767754387c962926577f1660dd9b810187b9002407656be72\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://7d533a1c97cd43a57cd9c465f7ee8dd0e39ae93a8fb8ff8e5303a356b081cdcc\",\"dweb:/ipfs/QmVBEei6aTnvYNZp2CHYVNKyZS4q1KkjANfY39WVXZXVoT\"]},\"lib/permit2/src/interfaces/ISignatureTransfer.sol\":{\"keccak256\":\"0xbab1c35f0a63761be6b50a9a2ce2459b63f09587dd9c6ac46955252a1a04f43c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://225dca1a3d91c0737fe75c72bfecae391fc2e7b2eb2ebe1a154bfb16a7527972\",\"dweb:/ipfs/QmdGQdUCANKZ6S23TyHDtBnGvr6CtyyqNNcziVTjEHJ5rk\"]},\"src/opportunity-adapter/Errors.sol\":{\"keccak256\":\"0x52dbef88d515328490963ea923d04841d2e80d68c879342c8c05c9a59652f570\",\"license\":\"Apache 2\",\"urls\":[\"bzz-raw://5f825b83839dcc779db5e3735f2ca4854c0f2c0f4f382edb2e7380508cd8d570\",\"dweb:/ipfs/QmSowVpNasgthmBys8g49pDmbLDifLzE22hRejTXHve7sF\"]},\"src/opportunity-adapter/IOpportunityAdapterFactory.sol\":{\"keccak256\":\"0xaa1972242ea4d9c8c55256775945c3db850c7563e4a3ea1e7bf483aa43193fb0\",\"license\":\"Apache 2\",\"urls\":[\"bzz-raw://3ddd9fe69de5917e95218603b68957f1186636149f9c9636054651165de047e5\",\"dweb:/ipfs/QmW8n4vuWCtwAYcU3M5QDSwL4Wvu8Zmq5SCDxHECLfKWzc\"]},\"src/opportunity-adapter/IWETH9.sol\":{\"keccak256\":\"0x06e8fe3818fdbf58152dfd115015cea455cce5e25739d2efd5e0fe4a47fa914e\",\"license\":\"Apache 2\",\"urls\":[\"bzz-raw://2f30048c1be6a967720b48b6d9758c1066df174a1bac8fbf5c46be2119c3e0ba\",\"dweb:/ipfs/QmaxEJZWM5StRWMJQzT6NuqhrQXFi9cNASijjYBKxGdgB1\"]},\"src/opportunity-adapter/OpportunityAdapter.sol\":{\"keccak256\":\"0xb740bc27178fd4764511fb2ce422ad3ec806d5fcf0a5e5b8516c2595bf8189bd\",\"license\":\"Apache 2\",\"urls\":[\"bzz-raw://6693e0a6e5487c10e952a1a7b8e792909272fc0e5a0f24d3f40b3b25b9a978e2\",\"dweb:/ipfs/QmXoELHWPRCZ4M7S6n9MHFCbzrVKTx9HXUw41vnLVKhXKQ\"]},\"src/opportunity-adapter/OpportunityAdapterFactory.sol\":{\"keccak256\":\"0x12ad094e683fef3af4d92d095bb697f486ad7e70663a0effff215c492728b62a\",\"license\":\"Apache 2\",\"urls\":[\"bzz-raw://0a61559a33799d76e98d35af685be70a689888989615085f545b745934d357d3\",\"dweb:/ipfs/QmcjAx9g1tyat5Vb4v3UUDGo7WvZQZfhAqmCYAJBo1qmkA\"]},\"src/opportunity-adapter/OpportunityAdapterHasher.sol\":{\"keccak256\":\"0x3522d08da173a34e19e00680d28896c5baa0a80e1b712fbec385e0a571685196\",\"license\":\"Apache 2\",\"urls\":[\"bzz-raw://d6452f694f3508a3d5e1926c320d55ecb0c129120da3046c61102942eb7c5d8f\",\"dweb:/ipfs/QmS2zLzFmpgqWEYDe4p71ZZJJJuSPwn5uWjYz9XmYjjMXb\"]},\"src/opportunity-adapter/Structs.sol\":{\"keccak256\":\"0xdb445d4e01f554cc6ac18578329fb763487c84e5158f98cf9c34844b8f470f47\",\"license\":\"Apache 2\",\"urls\":[\"bzz-raw://7da599018a0baa466b1f48f14ef4a5741a72678d45079cae4ab4447825b16774\",\"dweb:/ipfs/QmTqe7Y6KMAVisDUm7kcWEHXMvtCKAKuveCWBre3NdiinX\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.20+commit.a1b79de6"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"address","name":"expressRelay","type":"address"},{"internalType":"address","name":"weth","type":"address"},{"internalType":"address","name":"permit2","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"type":"error","name":"Create2EmptyBytecode"},{"inputs":[],"type":"error","name":"Create2FailedDeployment"},{"inputs":[{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"type":"error","name":"Create2InsufficientBalance"},{"inputs":[],"type":"error","name":"NotCalledByExpressRelay"},{"inputs":[],"type":"error","name":"ReentrancyGuardReentrantCall"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function","name":"computeAddress","outputs":[{"internalType":"address","name":"","type":"address"}]},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"createAdapter","outputs":[{"internalType":"address","name":"","type":"address"}]},{"inputs":[{"internalType":"struct ExecutionParams","name":"params","type":"tuple","components":[{"internalType":"struct ISignatureTransfer.PermitBatchTransferFrom","name":"permit","type":"tuple","components":[{"internalType":"struct ISignatureTransfer.TokenPermissions[]","name":"permitted","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}]},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}]},{"internalType":"struct ExecutionWitness","name":"witness","type":"tuple","components":[{"internalType":"struct TokenAmount[]","name":"buyTokens","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}]},{"internalType":"address","name":"executor","type":"address"},{"internalType":"address","name":"targetContract","type":"address"},{"internalType":"bytes","name":"targetCalldata","type":"bytes"},{"internalType":"uint256","name":"targetCallValue","type":"uint256"},{"internalType":"uint256","name":"bidAmount","type":"uint256"}]}]},{"internalType":"bytes","name":"signature","type":"bytes"}],"stateMutability":"payable","type":"function","name":"executeOpportunity"},{"inputs":[],"stateMutability":"view","type":"function","name":"getExpressRelay","outputs":[{"internalType":"address","name":"","type":"address"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"getOpportunityAdapterCreationCodeHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"getPermit2","outputs":[{"internalType":"address","name":"","type":"address"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"getWeth","outputs":[{"internalType":"address","name":"","type":"address"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"parameters","outputs":[{"internalType":"address","name":"expressRelay","type":"address"},{"internalType":"address","name":"weth","type":"address"},{"internalType":"address","name":"permit2","type":"address"},{"internalType":"address","name":"owner","type":"address"}]}],"devdoc":{"kind":"dev","methods":{"constructor":{"params":{"expressRelay":": address of express relay","permit2":": address of permit2 contract","weth":": address of WETH contract"}}},"version":1},"userdoc":{"kind":"user","methods":{"constructor":{"notice":"OpportunityAdapterFactory constructor"},"getExpressRelay()":{"notice":"getExpressRelay function - returns the address of the express relay authenticated for calling this contract"},"getOpportunityAdapterCreationCodeHash()":{"notice":"getOpportunityAdapterCreationCodeHash - returns the hash of the creation code of the opportunity adapter contract"},"getPermit2()":{"notice":"getPermit2 function - returns the address of the permit2 contract used for token approvals"},"getWeth()":{"notice":"getWeth function - returns the address of the WETH contract used for wrapping and unwrapping ETH"}},"version":1}},"settings":{"remappings":["@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/","@pythnetwork/express-relay-sdk-solidity/=node_modules/@pythnetwork/express-relay-sdk-solidity/","@pythnetwork/pyth-sdk-solidity/=node_modules/@pythnetwork/pyth-sdk-solidity/","ExcessivelySafeCall/=lib/ExcessivelySafeCall/src/","ds-test/=lib/forge-std/lib/ds-test/src/","erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/","forge-gas-snapshot/=lib/permit2/lib/forge-gas-snapshot/src/","forge-std/=lib/forge-std/src/","halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/","openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/","openzeppelin-contracts/=lib/openzeppelin-contracts/","openzeppelin/=lib/openzeppelin-contracts-upgradeable/contracts/","permit2/=lib/permit2/src/","solmate/=lib/permit2/lib/solmate/src/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"src/opportunity-adapter/OpportunityAdapterFactory.sol":"OpportunityAdapterFactory"},"evmVersion":"shanghai","libraries":{},"viaIR":true},"sources":{"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol":{"keccak256":"0xc6a8ff0ea489379b61faa647490411b80102578440ab9d84e9a957cc12164e70","urls":["bzz-raw://0ea104e577e63faea3b69c415637e99e755dcbf64c5833d7140c35a714d6d90c","dweb:/ipfs/Qmau6x4Ns9XdyynRCNNp3RhLqijJjFm7z5fyZazfYFGYdq"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol":{"keccak256":"0x6008dabfe393240d73d7dd7688033f72740d570aa422254d29a7dce8568f3aff","urls":["bzz-raw://f5196ec75139918c6c7bb4251b36395e668f1fa6d206beba7e7520e74913940d","dweb:/ipfs/QmSyqjksXxmm2mCG6qRd1yuwLykypkSVBbnBnGqJRcuJMi"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol":{"keccak256":"0x37bb49513c49c87c4642a891b13b63571bc87013dde806617aa1efb54605f386","urls":["bzz-raw://b3036b3a83b7c48f96641f2a9002b9f2dcb6a5958dd670894ada21ae8229b3d0","dweb:/ipfs/QmUNfSBdoVtjhETaUJCYcaC7pTMgbhht926tJ2uXJbiVd3"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/Address.sol":{"keccak256":"0xaf28a975a78550e45f65e559a3ad6a5ad43b9b8a37366999abd1b7084eb70721","urls":["bzz-raw://b7bd24e224f67f65bfadf85dc2929fa965456bb2415478bd0125471b5ce35245","dweb:/ipfs/QmRaydGr8BTHs1kvaZfsNU69pKzUAGFrvABn1KiRSbE51y"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/Create2.sol":{"keccak256":"0x2b9807d194b92f1068d868e9587d27037264a9a067c778486f86ae21c61cbd5e","urls":["bzz-raw://22d71f40aa38a20cf466d8647452a6e3f746353474f8c8af40f03aa8cae38420","dweb:/ipfs/QmQ752Hz5av7YDK8pFojzb5qgeXQvfsdkdwkHVzaXoYAZR"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/ReentrancyGuard.sol":{"keccak256":"0xf980daa263b661ab8ddee7d4fd833c7da7e7995e2c359ff1f17e67e4112f2236","urls":["bzz-raw://7448ab095d6940130bcf76ba47a2eab14148c83119523b93dd89f6d84edd6c02","dweb:/ipfs/QmawrZ4voKQjH3oomXT3Kuheb3Mnmo2VvVpxg8Ne5UJUrd"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/Strings.sol":{"keccak256":"0x55f102ea785d8399c0e58d1108e2d289506dde18abc6db1b7f68c1f9f9bc5792","urls":["bzz-raw://6e52e0a7765c943ef14e5bcf11e46e6139fa044be564881378349236bf2e3453","dweb:/ipfs/QmZEeeXoFPW47amyP35gfzomF9DixqqTEPwzBakv6cZw6i"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/math/Math.sol":{"keccak256":"0x005ec64c6313f0555d59e278f9a7a5ab2db5bdc72a027f255a37c327af1ec02d","urls":["bzz-raw://4ece9f0b9c8daca08c76b6b5405a6446b6f73b3a15fab7ff56e296cbd4a2c875","dweb:/ipfs/QmQyRpyPRL5SQuAgj6SHmbir3foX65FJjbVTTQrA2EFg6L"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol":{"keccak256":"0x5f7e4076e175393767754387c962926577f1660dd9b810187b9002407656be72","urls":["bzz-raw://7d533a1c97cd43a57cd9c465f7ee8dd0e39ae93a8fb8ff8e5303a356b081cdcc","dweb:/ipfs/QmVBEei6aTnvYNZp2CHYVNKyZS4q1KkjANfY39WVXZXVoT"],"license":"MIT"},"lib/permit2/src/interfaces/ISignatureTransfer.sol":{"keccak256":"0xbab1c35f0a63761be6b50a9a2ce2459b63f09587dd9c6ac46955252a1a04f43c","urls":["bzz-raw://225dca1a3d91c0737fe75c72bfecae391fc2e7b2eb2ebe1a154bfb16a7527972","dweb:/ipfs/QmdGQdUCANKZ6S23TyHDtBnGvr6CtyyqNNcziVTjEHJ5rk"],"license":"MIT"},"src/opportunity-adapter/Errors.sol":{"keccak256":"0x52dbef88d515328490963ea923d04841d2e80d68c879342c8c05c9a59652f570","urls":["bzz-raw://5f825b83839dcc779db5e3735f2ca4854c0f2c0f4f382edb2e7380508cd8d570","dweb:/ipfs/QmSowVpNasgthmBys8g49pDmbLDifLzE22hRejTXHve7sF"],"license":"Apache 2"},"src/opportunity-adapter/IOpportunityAdapterFactory.sol":{"keccak256":"0xaa1972242ea4d9c8c55256775945c3db850c7563e4a3ea1e7bf483aa43193fb0","urls":["bzz-raw://3ddd9fe69de5917e95218603b68957f1186636149f9c9636054651165de047e5","dweb:/ipfs/QmW8n4vuWCtwAYcU3M5QDSwL4Wvu8Zmq5SCDxHECLfKWzc"],"license":"Apache 2"},"src/opportunity-adapter/IWETH9.sol":{"keccak256":"0x06e8fe3818fdbf58152dfd115015cea455cce5e25739d2efd5e0fe4a47fa914e","urls":["bzz-raw://2f30048c1be6a967720b48b6d9758c1066df174a1bac8fbf5c46be2119c3e0ba","dweb:/ipfs/QmaxEJZWM5StRWMJQzT6NuqhrQXFi9cNASijjYBKxGdgB1"],"license":"Apache 2"},"src/opportunity-adapter/OpportunityAdapter.sol":{"keccak256":"0xb740bc27178fd4764511fb2ce422ad3ec806d5fcf0a5e5b8516c2595bf8189bd","urls":["bzz-raw://6693e0a6e5487c10e952a1a7b8e792909272fc0e5a0f24d3f40b3b25b9a978e2","dweb:/ipfs/QmXoELHWPRCZ4M7S6n9MHFCbzrVKTx9HXUw41vnLVKhXKQ"],"license":"Apache 2"},"src/opportunity-adapter/OpportunityAdapterFactory.sol":{"keccak256":"0x12ad094e683fef3af4d92d095bb697f486ad7e70663a0effff215c492728b62a","urls":["bzz-raw://0a61559a33799d76e98d35af685be70a689888989615085f545b745934d357d3","dweb:/ipfs/QmcjAx9g1tyat5Vb4v3UUDGo7WvZQZfhAqmCYAJBo1qmkA"],"license":"Apache 2"},"src/opportunity-adapter/OpportunityAdapterHasher.sol":{"keccak256":"0x3522d08da173a34e19e00680d28896c5baa0a80e1b712fbec385e0a571685196","urls":["bzz-raw://d6452f694f3508a3d5e1926c320d55ecb0c129120da3046c61102942eb7c5d8f","dweb:/ipfs/QmS2zLzFmpgqWEYDe4p71ZZJJJuSPwn5uWjYz9XmYjjMXb"],"license":"Apache 2"},"src/opportunity-adapter/Structs.sol":{"keccak256":"0xdb445d4e01f554cc6ac18578329fb763487c84e5158f98cf9c34844b8f470f47","urls":["bzz-raw://7da599018a0baa466b1f48f14ef4a5741a72678d45079cae4ab4447825b16774","dweb:/ipfs/QmTqe7Y6KMAVisDUm7kcWEHXMvtCKAKuveCWBre3NdiinX"],"license":"Apache 2"}},"version":1},"id":88} \ No newline at end of file diff --git a/sdk/rust/abi/WETH9.sol/WETH9.json b/sdk/rust/abi/WETH9.sol/WETH9.json new file mode 100644 index 00000000..363bb0c5 --- /dev/null +++ b/sdk/rust/abi/WETH9.sol/WETH9.json @@ -0,0 +1 @@ +{"abi":[{"type":"receive","stateMutability":"payable"},{"type":"function","name":"allowance","inputs":[{"name":"","type":"address","internalType":"address"},{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"approve","inputs":[{"name":"guy","type":"address","internalType":"address"},{"name":"wad","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"},{"type":"function","name":"balanceOf","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"decimals","inputs":[],"outputs":[{"name":"","type":"uint8","internalType":"uint8"}],"stateMutability":"view"},{"type":"function","name":"deposit","inputs":[],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"name","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"type":"function","name":"symbol","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"type":"function","name":"totalSupply","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"transfer","inputs":[{"name":"dst","type":"address","internalType":"address"},{"name":"wad","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"},{"type":"function","name":"transferFrom","inputs":[{"name":"src","type":"address","internalType":"address"},{"name":"dst","type":"address","internalType":"address"},{"name":"wad","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"},{"type":"function","name":"withdraw","inputs":[{"name":"wad","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"event","name":"Approval","inputs":[{"name":"src","type":"address","indexed":true,"internalType":"address"},{"name":"guy","type":"address","indexed":true,"internalType":"address"},{"name":"wad","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"Deposit","inputs":[{"name":"dst","type":"address","indexed":true,"internalType":"address"},{"name":"wad","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"name":"src","type":"address","indexed":true,"internalType":"address"},{"name":"dst","type":"address","indexed":true,"internalType":"address"},{"name":"wad","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"Withdrawal","inputs":[{"name":"src","type":"address","indexed":true,"internalType":"address"},{"name":"wad","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false}],"bytecode":{"object":"0x60806040523461010a575f610014815461010e565b601f81116100dd575b506081815580805260208120907f633936343538643339336665396465623761376436336130616334316532383982557f386136376137373530646264313636363733323739653036633836386466306160018093015561007e825461010e565b90601f82116100b1575b6008630ae8aa8960e31b0183556002805460ff1916601217905560405161071c90816101478239f35b82815282601f60208320930160051c8301925b8381106100d2575050610088565b8281550183906100c4565b8180526002601f60208420920160051c820191015b8181106100ff575061001d565b8281556001016100f2565b5f80fd5b90600182811c9216801561013c575b602083101461012857565b634e487b7160e01b5f52602260045260245ffd5b91607f169161011d56fe60806040818152600480361015610028575b505050361561001e575f80fd5b610026610598565b005b5f92833560e01c90816306fdde031461040d57508063095ea7b31461039f57806318160ddd1461038457806323b872dd146103525780632e1a7d4d146102c0578063313ce5671461029e57806370a082311461026657806395d89b4114610145578063a9059cbb1461010e578063d0e30db0146100f45763dd62ed3e0361001157346100f057816003193601126100f05760209282916100c6610547565b6100ce610561565b6001600160a01b03918216845291865283832091168252845220549051908152f35b8280fd5b838060031936011261010b57610108610598565b80f35b80fd5b50503461014157806003193601126101415760209061013861012e610547565b60243590336105ec565b90519015158152f35b5080fd5b5091903461014157816003193601126101415780519082600180549081811c9080831692831561025c575b60209384841081146102495783885290811561022d57506001146101d8575b505050829003601f01601f191682019267ffffffffffffffff8411838510176101c557508291826101c1925282610500565b0390f35b634e487b7160e01b815260418552602490fd5b8087529192508591837fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf65b83851061021957505050508301015f808061018f565b805488860183015293019284908201610203565b60ff1916878501525050151560051b84010190505f808061018f565b634e487b7160e01b895260228a52602489fd5b91607f1691610170565b5050346101415760203660031901126101415760209181906001600160a01b0361028e610547565b1681526003845220549051908152f35b50503461014157816003193601126101415760209060ff600254169051908152f35b50346100f05760203660031901126100f05735903383526003602052808320805483811061034e57836102f2916105df565b90558280838015610344575b8280929181923390f11561033957519081527f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b6560203392a280f35b51913d9150823e3d90fd5b6108fc91506102fe565b8480fd5b50503461014157606036600319011261014157602090610138610373610547565b61037b610561565b604435916105ec565b50503461014157816003193601126101415751478152602090f35b50346100f057816003193601126100f0576020926103bb610547565b918360243592839233825287528181209460018060a01b0316948582528752205582519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925843392a35160018152f35b84915083346100f057826003193601126100f057828354600181811c908083169283156104f6575b6020938484108114610249578388529081156104da575060011461048557505050829003601f01601f191682019267ffffffffffffffff8411838510176101c557508291826101c1925282610500565b8680529192508591837f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5635b8385106104c6575050505083010185808061018f565b8054888601830152930192849082016104b0565b60ff1916878501525050151560051b840101905085808061018f565b91607f1691610435565b602080825282518183018190529093925f5b82811061053357505060409293505f838284010152601f8019910116010190565b818101860151848201604001528501610512565b600435906001600160a01b038216820361055d57565b5f80fd5b602435906001600160a01b038216820361055d57565b9190820180921161058457565b634e487b7160e01b5f52601160045260245ffd5b335f52600360205260405f206105af348254610577565b90556040513481527fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c60203392a2565b9190820391821161058457565b91909160018060a01b03809116915f93838552602092600384526040918383882054106106e25733860361067a575b9180917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef959493878952600386528289206106578682546105df565b90551696878152600385522061066e838254610577565b905551908152a3600190565b6004855282872033885285528383882054106106e2579180917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef95949387895260048652828920338a5286528289206106d48682546105df565b90559150919293945061061b565b8680fdfea264697066735822122086c5faa26eb20de45bc784401133ae304cac3f5f13be6f2cacbb4d830e6bfb7764736f6c63430008140033","sourceMap":"779:1968:101:-:0;;;;;;907:66;779:1968;;;;:::i;:::-;;;;;;-1:-1:-1;779:1968:101;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;;;;;779:1968:101;;1062:2;779:1968;;-1:-1:-1;;779:1968:101;1062:2;779:1968;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x60806040818152600480361015610028575b505050361561001e575f80fd5b610026610598565b005b5f92833560e01c90816306fdde031461040d57508063095ea7b31461039f57806318160ddd1461038457806323b872dd146103525780632e1a7d4d146102c0578063313ce5671461029e57806370a082311461026657806395d89b4114610145578063a9059cbb1461010e578063d0e30db0146100f45763dd62ed3e0361001157346100f057816003193601126100f05760209282916100c6610547565b6100ce610561565b6001600160a01b03918216845291865283832091168252845220549051908152f35b8280fd5b838060031936011261010b57610108610598565b80f35b80fd5b50503461014157806003193601126101415760209061013861012e610547565b60243590336105ec565b90519015158152f35b5080fd5b5091903461014157816003193601126101415780519082600180549081811c9080831692831561025c575b60209384841081146102495783885290811561022d57506001146101d8575b505050829003601f01601f191682019267ffffffffffffffff8411838510176101c557508291826101c1925282610500565b0390f35b634e487b7160e01b815260418552602490fd5b8087529192508591837fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf65b83851061021957505050508301015f808061018f565b805488860183015293019284908201610203565b60ff1916878501525050151560051b84010190505f808061018f565b634e487b7160e01b895260228a52602489fd5b91607f1691610170565b5050346101415760203660031901126101415760209181906001600160a01b0361028e610547565b1681526003845220549051908152f35b50503461014157816003193601126101415760209060ff600254169051908152f35b50346100f05760203660031901126100f05735903383526003602052808320805483811061034e57836102f2916105df565b90558280838015610344575b8280929181923390f11561033957519081527f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b6560203392a280f35b51913d9150823e3d90fd5b6108fc91506102fe565b8480fd5b50503461014157606036600319011261014157602090610138610373610547565b61037b610561565b604435916105ec565b50503461014157816003193601126101415751478152602090f35b50346100f057816003193601126100f0576020926103bb610547565b918360243592839233825287528181209460018060a01b0316948582528752205582519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925843392a35160018152f35b84915083346100f057826003193601126100f057828354600181811c908083169283156104f6575b6020938484108114610249578388529081156104da575060011461048557505050829003601f01601f191682019267ffffffffffffffff8411838510176101c557508291826101c1925282610500565b8680529192508591837f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5635b8385106104c6575050505083010185808061018f565b8054888601830152930192849082016104b0565b60ff1916878501525050151560051b840101905085808061018f565b91607f1691610435565b602080825282518183018190529093925f5b82811061053357505060409293505f838284010152601f8019910116010190565b818101860151848201604001528501610512565b600435906001600160a01b038216820361055d57565b5f80fd5b602435906001600160a01b038216820361055d57565b9190820180921161058457565b634e487b7160e01b5f52601160045260245ffd5b335f52600360205260405f206105af348254610577565b90556040513481527fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c60203392a2565b9190820391821161058457565b91909160018060a01b03809116915f93838552602092600384526040918383882054106106e25733860361067a575b9180917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef959493878952600386528289206106578682546105df565b90551696878152600385522061066e838254610577565b905551908152a3600190565b6004855282872033885285528383882054106106e2579180917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef95949387895260048652828920338a5286528289206106d48682546105df565b90559150919293945061061b565b8680fdfea264697066735822122086c5faa26eb20de45bc784401133ae304cac3f5f13be6f2cacbb4d830e6bfb7764736f6c63430008140033","sourceMap":"779:1968:101:-:0;;;;;;;;;;;;-1:-1:-1;779:1968:101;;;;;;;;;;;1434:53;;:::i;:::-;779:1968;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::i;:::-;-1:-1:-1;;;;;779:1968:101;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;2211:34;779:1968;;:::i;:::-;;;2224:10;;2211:34;:::i;:::-;779:1968;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1003:29;779:1968;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;779:1968:101;;;;;-1:-1:-1;;779:1968:101;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;779:1968:101;;;;;;;;;;;;;;-1:-1:-1;779:1968:101;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;779:1968:101;;;;;-1:-1:-1;;779:1968:101;;;;;;;;-1:-1:-1;779:1968:101;;;;;;-1:-1:-1;;;779:1968:101;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;779:1968:101;;;;;;;;-1:-1:-1;;;;;779:1968:101;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1038:26;779:1968;;;;;;;;;;;;;;;-1:-1:-1;;779:1968:101;;;;;1692:10;;779:1968;;;;;;;;;;1682:28;;;779:1968;;1721:28;;;;:::i;:::-;779:1968;;1759:33;;;;;;;779:1968;1692:10;;;;;;;1759:33;;;;;779:1968;;;;1807:27;779:1968;1692:10;1807:27;;779:1968;;1759:33;779:1968;;;;-1:-1:-1;779:1968:101;;;;;1759:33;;;-1:-1:-1;1759:33:101;;779:1968;;;;;;;;;;;;-1:-1:-1;;779:1968:101;;;;;;;;;:::i;:::-;;;:::i;:::-;;;;;:::i;:::-;;;;;;;;;;;;;;;1914:21;779:1968;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;2030:10;;;;779:1968;;;;;;;;;;;;;;;;;;;;;;;;;;;2067:30;2030:10;;2067:30;;779:1968;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;779:1968:101;;;;;-1:-1:-1;;779:1968:101;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;779:1968:101;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;779:1968:101;;;;;-1:-1:-1;;779:1968:101;;;;;;;;-1:-1:-1;779:1968:101;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;779:1968:101;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;779:1968:101;;;;;;:::o;:::-;;;;;;;;-1:-1:-1;;;;;779:1968:101;;;;;;:::o;:::-;;;;;;;;;;:::o;:::-;;;;;;;;;;;;1493:130;1547:10;-1:-1:-1;779:1968:101;1537:9;779:1968;;;-1:-1:-1;779:1968:101;1537:34;1562:9;779:1968;;1537:34;:::i;:::-;779:1968;;;;1562:9;779:1968;;1586:30;779:1968;1547:10;1586:30;;1493:130::o;779:1968::-;;;;;;;;;;:::o;2258:487::-;;;;779:1968;;;;;;;;-1:-1:-1;;779:1968:101;;;;;;2386:9;779:1968;;;;;;;;;2386:21;779:1968;;2430:10;2423:17;;2419:196;;2258:487;779:1968;;;2693:23;779:1968;;;;;;2386:9;779:1968;;;;;2625:21;779:1968;;;2625:21;:::i;:::-;779:1968;;;;;;;2386:9;779:1968;;;2656:21;779:1968;;;2656:21;:::i;:::-;779:1968;;;;;;2693:23;779:1968;2258:487;:::o;2419:196::-;2523:9;779:1968;;;;;2430:10;779:1968;;;;;;;;;2523:33;779:1968;;;;;2693:23;779:1968;;;;;;2523:9;779:1968;;;;;2430:10;779:1968;;;;;;;2571:33;779:1968;;;2571:33;:::i;:::-;779:1968;;2419:196;;;;;;;;;779:1968;;;","linkReferences":{}},"methodIdentifiers":{"allowance(address,address)":"dd62ed3e","approve(address,uint256)":"095ea7b3","balanceOf(address)":"70a08231","decimals()":"313ce567","deposit()":"d0e30db0","name()":"06fdde03","symbol()":"95d89b41","totalSupply()":"18160ddd","transfer(address,uint256)":"a9059cbb","transferFrom(address,address,uint256)":"23b872dd","withdraw(uint256)":"2e1a7d4d"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.20+commit.a1b79de6\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"guy\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"guy\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"deposit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"test/WETH9.sol\":\"WETH9\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@pythnetwork/express-relay-sdk-solidity/=node_modules/@pythnetwork/express-relay-sdk-solidity/\",\":@pythnetwork/pyth-sdk-solidity/=node_modules/@pythnetwork/pyth-sdk-solidity/\",\":ExcessivelySafeCall/=lib/ExcessivelySafeCall/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/\",\":forge-gas-snapshot/=lib/permit2/lib/forge-gas-snapshot/src/\",\":forge-std/=lib/forge-std/src/\",\":halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":openzeppelin/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":permit2/=lib/permit2/src/\",\":solmate/=lib/permit2/lib/solmate/src/\"],\"viaIR\":true},\"sources\":{\"test/WETH9.sol\":{\"keccak256\":\"0x45838966a51bd41ec97df4dae4105b382f00ce18edb4557ff3e3fdc3931804d8\",\"urls\":[\"bzz-raw://66bb5e6ebc76a9ef37621ff59a1146c5693b33caecf45189ae27b6674e6eaffc\",\"dweb:/ipfs/QmfZejvFL9UhdR9MCw7XHpotPJTZ1nNTi4crDbf1L1v4xk\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.20+commit.a1b79de6"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"address","name":"src","type":"address","indexed":true},{"internalType":"address","name":"guy","type":"address","indexed":true},{"internalType":"uint256","name":"wad","type":"uint256","indexed":false}],"type":"event","name":"Approval","anonymous":false},{"inputs":[{"internalType":"address","name":"dst","type":"address","indexed":true},{"internalType":"uint256","name":"wad","type":"uint256","indexed":false}],"type":"event","name":"Deposit","anonymous":false},{"inputs":[{"internalType":"address","name":"src","type":"address","indexed":true},{"internalType":"address","name":"dst","type":"address","indexed":true},{"internalType":"uint256","name":"wad","type":"uint256","indexed":false}],"type":"event","name":"Transfer","anonymous":false},{"inputs":[{"internalType":"address","name":"src","type":"address","indexed":true},{"internalType":"uint256","name":"wad","type":"uint256","indexed":false}],"type":"event","name":"Withdrawal","anonymous":false},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function","name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[{"internalType":"address","name":"guy","type":"address"},{"internalType":"uint256","name":"wad","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}]},{"inputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function","name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}]},{"inputs":[],"stateMutability":"payable","type":"function","name":"deposit"},{"inputs":[],"stateMutability":"view","type":"function","name":"name","outputs":[{"internalType":"string","name":"","type":"string"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"wad","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}]},{"inputs":[{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"wad","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}]},{"inputs":[{"internalType":"uint256","name":"wad","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"withdraw"},{"inputs":[],"stateMutability":"payable","type":"receive"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":["@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/","@pythnetwork/express-relay-sdk-solidity/=node_modules/@pythnetwork/express-relay-sdk-solidity/","@pythnetwork/pyth-sdk-solidity/=node_modules/@pythnetwork/pyth-sdk-solidity/","ExcessivelySafeCall/=lib/ExcessivelySafeCall/src/","ds-test/=lib/forge-std/lib/ds-test/src/","erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/","forge-gas-snapshot/=lib/permit2/lib/forge-gas-snapshot/src/","forge-std/=lib/forge-std/src/","halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/","openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/","openzeppelin-contracts/=lib/openzeppelin-contracts/","openzeppelin/=lib/openzeppelin-contracts-upgradeable/contracts/","permit2/=lib/permit2/src/","solmate/=lib/permit2/lib/solmate/src/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"test/WETH9.sol":"WETH9"},"evmVersion":"shanghai","libraries":{},"viaIR":true},"sources":{"test/WETH9.sol":{"keccak256":"0x45838966a51bd41ec97df4dae4105b382f00ce18edb4557ff3e3fdc3931804d8","urls":["bzz-raw://66bb5e6ebc76a9ef37621ff59a1146c5693b33caecf45189ae27b6674e6eaffc","dweb:/ipfs/QmfZejvFL9UhdR9MCw7XHpotPJTZ1nNTi4crDbf1L1v4xk"],"license":null}},"version":1},"id":101} \ No newline at end of file diff --git a/sdk/rust/simple-searcher/Cargo.toml b/sdk/rust/simple-searcher/Cargo.toml new file mode 100644 index 00000000..1822430b --- /dev/null +++ b/sdk/rust/simple-searcher/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "express-relay-simple-searcher" +version = "0.1.0" +edition = "2021" + +[dependencies] +express-relay-client = { path = ".." } +anyhow = { workspace = true } +tokio = { version = "1.42.0", features = ["macros", "rt-multi-thread"] } +time = { workspace = true } +tokio-stream = { workspace = true } +rand = "0.8.5" +clap = { version = "4.5.23", features = ["derive", "env"] } diff --git a/sdk/rust/simple-searcher/src/main.rs b/sdk/rust/simple-searcher/src/main.rs new file mode 100644 index 00000000..62a7c9de --- /dev/null +++ b/sdk/rust/simple-searcher/src/main.rs @@ -0,0 +1,228 @@ +use { + anyhow::{ + anyhow, + Result, + }, + clap::Parser, + express_relay_client::{ + api_types::{ + opportunity::{ + self, + GetOpportunitiesQueryParams, + Opportunity, + OpportunityMode, + }, + ws::ServerUpdateResponse, + }, + ethers::{ + signers::LocalWallet, + types::U256, + }, + evm::BidParamsEvm, + Client, + ClientConfig, + WsClient, + }, + rand::Rng, + std::collections::HashMap, + time::{ + Duration, + OffsetDateTime, + }, + tokio_stream::StreamExt, +}; + + +#[derive(Parser, Clone, Debug)] +pub struct RunOptions { + /// The http url of the express relay server. + #[arg(long = "server-url")] + #[arg(env = "SERVER_URL")] + pub server_url: String, + + /// EVM private key in hex format. + #[arg(long = "private-key-evm")] + #[arg(env = "PRIVATE_KEY_EVM")] + pub private_key_evm: Option, + + /// SVM private key in base58 format. + #[arg(long = "private-key-svm")] + #[arg(env = "PRIVATE_KEY_SVM")] + pub private_key_svm: Option, + + /// Chain ids to subscribe to. + #[arg(long = "chain-ids", required = true)] + #[arg(env = "CHAIN_IDS")] + pub chains: Vec, + + /// The API key to use for authentication. + #[arg(long = "api-key")] + #[arg(env = "API_KEY")] + pub api_key: Option, +} + + +async fn random() -> U256 { + let mut rng = rand::thread_rng(); + U256::from(rng.gen::()) +} + +async fn submit_opportunity( + ws_client: WsClient, + opportunity: Opportunity, + private_key: String, +) -> Result<()> { + let bid = match opportunity { + opportunity::Opportunity::Evm(opportunity) => { + Client::new_bid( + opportunity, + BidParamsEvm { + amount: U256::from(5_000_000_000_000_000_000_i128), + nonce: random().await, + deadline: U256::from( + (OffsetDateTime::now_utc() + Duration::days(1)).unix_timestamp(), + ), + }, + private_key, + ) + .await + } + opportunity::Opportunity::Svm(opportunity) => { + Client::new_bid(opportunity, 2, private_key).await + } + } + .map_err(|e| { + eprintln!("Failed to create bid: {:?}", e); + anyhow!("Failed to create bid: {:?}", e) + })?; + + let result = ws_client.submit_bid(bid).await; + match result { + Ok(_) => println!("Bid submitted"), + Err(e) => eprintln!("Failed to submit bid: {:?}", e), + }; + Ok(()) +} + +async fn handle_opportunity(ws_client: WsClient, opportunity: Opportunity, args: RunOptions) { + // Assess the opportunity to see if it is worth bidding + // For the sake of this example, we will always bid + let private_key = match opportunity { + Opportunity::Evm(_) => { + println!("EVM opportunity Received"); + args.private_key_evm.clone() + } + Opportunity::Svm(_) => { + println!("SVM opportunity Received"); + args.private_key_svm.clone() + } + }; + + match private_key { + Some(private_key) => { + if let Err(e) = submit_opportunity(ws_client, opportunity, private_key).await { + eprintln!("Failed to submit opportunity: {:?}", e); + } + } + None => { + eprintln!("Private key not provided"); + } + } +} + +async fn bid_on_existing_opps( + client: &Client, + ws_client: WsClient, + args: RunOptions, +) -> Result<()> { + let opportunities = client + .get_opportunities(Some(GetOpportunitiesQueryParams { + chain_id: Some(args.chains[0].clone()), + mode: OpportunityMode::Live, + permission_key: None, + limit: 100, + from_time: Some(OffsetDateTime::now_utc() - Duration::days(1)), + })) + .await + .map_err(|e| { + eprintln!("Failed to get opportunities: {:?}", e); + anyhow!("Failed to get opportunities") + })?; + opportunities.iter().for_each(|opportunity| { + tokio::spawn(handle_opportunity( + ws_client.clone(), + opportunity.clone(), + args.clone(), + )); + }); + Ok(()) +} + +#[tokio::main] +async fn main() -> Result<()> { + let args: RunOptions = RunOptions::parse(); + if let Some(private_key) = args.private_key_evm.clone() { + private_key + .parse::() + .map_err(|e| anyhow!("Invalid evm private key: {}", e))?; + } + + let client = Client::try_new(ClientConfig { + http_url: args.server_url.clone(), + api_key: args.api_key.clone(), + }) + .map_err(|e| { + eprintln!("Failed to create client: {:?}", e); + anyhow!("Failed to create client") + })?; + + let ws_client = client.connect_websocket().await.map_err(|e| { + eprintln!("Failed to connect websocket: {:?}", e); + anyhow!("Failed to connect websocket") + })?; + + bid_on_existing_opps(&client, ws_client.clone(), args.clone()).await?; + + ws_client + .chain_subscribe(args.chains.clone()) + .await + .map_err(|e| { + eprintln!("Failed to subscribe chains: {:?}", e); + anyhow!("Failed to subscribe chains") + })?; + + let mut stream = ws_client.get_update_stream(); + let mut block_hash_map = HashMap::new(); + while let Some(update) = stream.next().await { + let update = match update { + Ok(update) => update, + Err(e) => { + eprintln!("The stream is fallen behind: {:?}", e); + continue; + } + }; + + match update { + ServerUpdateResponse::NewOpportunity { opportunity } => { + tokio::spawn(handle_opportunity( + ws_client.clone(), + opportunity, + args.clone(), + )); + } + ServerUpdateResponse::SvmChainUpdate { update } => { + block_hash_map.insert(update.chain_id.clone(), update.blockhash); + println!("SVM chain update: {:?}", update); + } + ServerUpdateResponse::RemoveOpportunities { opportunity_delete } => { + println!("Remove opportunities: {:?}", opportunity_delete); + } + ServerUpdateResponse::BidStatusUpdate { status } => { + println!("Bid status update: {:?}", status); + } + } + } + + println!("Websocket closed"); + Ok(()) +} diff --git a/sdk/rust/src/evm.rs b/sdk/rust/src/evm.rs new file mode 100644 index 00000000..9384b32c --- /dev/null +++ b/sdk/rust/src/evm.rs @@ -0,0 +1,284 @@ +use { + crate::ClientError, + ethers::{ + abi::AbiEncode, + contract::abigen, + signers::{ + LocalWallet, + Signer, + }, + types::{ + transaction::eip712::{ + self, + EIP712Domain, + Eip712, + }, + Address, + Bytes, + Signature, + U256, + }, + utils::{ + get_create2_address_from_hash, + hex, + }, + }, + express_relay_api_types::opportunity::{ + OpportunityCreateV1Evm, + OpportunityEvm, + OpportunityParamsEvm, + OpportunityParamsV1Evm, + }, +}; + +abigen!( + OpportunityAdapter, + "./abi/OpportunityAdapter.sol/OpportunityAdapter.json"; + AdapterFactory, + "./abi/OpportunityAdapterFactory.sol/OpportunityAdapterFactory.json" +); +abigen!(ERC20, "./abi/ERC20.sol/ERC20.json"); +abigen!(WETH9, "./abi/WETH9.sol/WETH9.json"); + +abigen!(ExpressRelay, "./abi/ExpressRelay.sol/ExpressRelay.json"); + +#[derive(Debug, Clone)] +pub struct BidParamsEvm { + pub amount: ethers::types::U256, + pub deadline: ethers::types::U256, + pub nonce: ethers::types::U256, +} + +pub struct Config { + pub weth: Address, + pub adapter_factory_contract: Address, + pub permit2: Address, + pub adapter_bytecode_hash: [u8; 32], + pub chain_id_num: u64, +} + +pub fn get_config(chain_id: &str) -> Result { + match chain_id { + "mode" => Ok(Config { + weth: "0x74A4A85C611679B73F402B36c0F84A7D2CcdFDa3" + .parse() + .expect("Invalid Ethereum address"), + permit2: "0x000000000022D473030F116dDEE9F6B43aC78BA3" + .parse() + .expect("Invalid Ethereum address"), + adapter_factory_contract: "0x59F78DE21a0b05d96Ae00c547BA951a3B905602f" + .parse() + .expect("Invalid Ethereum address"), + adapter_bytecode_hash: hex::decode( + "0xd53b8e32ab2ecba07c3e3a17c3c5e492c62e2f7051b89e5154f52e6bfeb0e38f", + ) + .expect("Invalid bytecode hash") + .try_into() + .expect("Invalid bytecode hash length"), + chain_id_num: 34443, + }), + "op-sepolia" => Ok(Config { + weth: "0x4200000000000000000000000000000000000006" + .parse() + .expect("Invalid Ethereum address"), + permit2: "0x000000000022D473030F116dDEE9F6B43aC78BA3" + .parse() + .expect("Invalid Ethereum address"), + adapter_factory_contract: "0xfA119693864b2F185742A409c66f04865c787754" + .parse() + .expect("Invalid Ethereum address"), + adapter_bytecode_hash: hex::decode( + "0x3d71516d94b96a8fdca4e3a5825a6b41c9268a8e94610367e69a8462cc543533", + ) + .expect("Invalid bytecode hash") + .try_into() + .expect("Invalid bytecode hash length"), + chain_id_num: 11155420, + }), + _ => Err(ClientError::ChainNotSupported), + } +} + +pub fn make_permitted_tokens( + opportunity: OpportunityEvm, + bid_params: BidParamsEvm, +) -> Result, ClientError> { + let config = get_config(opportunity.get_chain_id())?; + let params = get_params(opportunity); + let mut permitted_tokens: Vec = params + .sell_tokens + .clone() + .into_iter() + .map(|token| TokenPermissions { + token: token.token, + amount: token.amount, + }) + .collect(); + + let extra_weth_amount = bid_params.amount + params.target_call_value; + if let Some(weth_position) = permitted_tokens.iter().position(|x| x.token == config.weth) { + permitted_tokens[weth_position] = TokenPermissions { + amount: permitted_tokens[weth_position].amount + extra_weth_amount, + ..permitted_tokens[weth_position] + } + } else if extra_weth_amount > U256::zero() { + permitted_tokens.push(TokenPermissions { + token: config.weth, + amount: extra_weth_amount, + }); + } + Ok(permitted_tokens) +} + +pub fn make_opportunity_execution_params( + opportunity: OpportunityEvm, + bid_params: BidParamsEvm, + executor: Address, +) -> Result { + let params = get_params(opportunity.clone()); + Ok(ExecutionParams { + permit: PermitBatchTransferFrom { + permitted: make_permitted_tokens(opportunity, bid_params.clone())?, + nonce: bid_params.nonce, + deadline: bid_params.deadline, + }, + witness: ExecutionWitness { + buy_tokens: params + .buy_tokens + .clone() + .into_iter() + .map(|token| TokenAmount { + token: token.token, + amount: token.amount, + }) + .collect(), + executor, + target_contract: params.target_contract, + target_calldata: params.target_calldata, + target_call_value: params.target_call_value, + bid_amount: bid_params.amount, + }, + }) +} + +fn get_typed_data( + params: ExecutionParams, + spender: Address, + domain: eip712::EIP712Domain, +) -> eip712::TypedData { + let data_type = serde_json::json!({ + "PermitBatchWitnessTransferFrom": [ + {"name": "permitted", "type": "TokenPermissions[]"}, + {"name": "spender", "type": "address"}, + {"name": "nonce", "type": "uint256"}, + {"name": "deadline", "type": "uint256"}, + {"name": "witness", "type": "OpportunityWitness"}, + ], + "OpportunityWitness": [ + {"name": "buyTokens", "type": "TokenAmount[]"}, + {"name": "executor", "type": "address"}, + {"name": "targetContract", "type": "address"}, + {"name": "targetCalldata", "type": "bytes"}, + {"name": "targetCallValue", "type": "uint256"}, + {"name": "bidAmount", "type": "uint256"}, + ], + "TokenAmount": [ + {"name": "token", "type": "address"}, + {"name": "amount", "type": "uint256"}, + ], + "TokenPermissions": [ + {"name": "token", "type": "address"}, + {"name": "amount", "type": "uint256"}, + ], + }); + let data = serde_json::json!({ + "permitted": params.permit.permitted.into_iter().map(|x| serde_json::json!({ + "token": x.token, + "amount": x.amount, + })).collect::>(), + "spender": spender, + "nonce": params.permit.nonce, + "deadline": params.permit.deadline, + "witness": serde_json::json!({ + "buyTokens": params.witness.buy_tokens.into_iter().map(|x| serde_json::json!({ + "token": x.token, + "amount": x.amount, + })).collect::>(), + "executor": params.witness.executor, + "targetContract": params.witness.target_contract, + "targetCalldata": params.witness.target_calldata, + "targetCallValue": params.witness.target_call_value, + "bidAmount": params.witness.bid_amount, + }), + }); + + eip712::TypedData { + domain, + types: serde_json::from_value(data_type) + .expect("Failed to parse data type for eip712 typed data"), + primary_type: "PermitBatchWitnessTransferFrom".into(), + message: serde_json::from_value(data).expect("Failed to parse data for eip712 typed data"), + } +} + +fn get_signature( + opportunity: OpportunityEvm, + bid_params: BidParamsEvm, + wallet: LocalWallet, +) -> Result { + let config = get_config(opportunity.get_chain_id())?; + let mut salt = [0u8; 32]; + salt[12..32].copy_from_slice(wallet.address().as_bytes()); + let executor_adapter_address = get_create2_address_from_hash( + config.adapter_factory_contract, + salt, + config.adapter_bytecode_hash, + ); + + let eip_712_domain = EIP712Domain { + name: Some("Permit2".to_string()), + version: None, + chain_id: Some(config.chain_id_num.into()), + verifying_contract: Some(config.permit2), + salt: None, + }; + + let params = make_opportunity_execution_params( + opportunity.clone(), + bid_params.clone(), + wallet.address(), + )?; + + let typed_data: eip712::TypedData = + get_typed_data(params.clone(), executor_adapter_address, eip_712_domain); + let hashed_data = typed_data + .encode_eip712() + .map_err(|e| ClientError::NewBidError(format!("Failed to encode eip712 data: {:?}", e)))?; + + wallet + .sign_hash(hashed_data.into()) + .map_err(|e| ClientError::NewBidError(format!("Failed to sign eip712 data: {:?}", e))) +} + +pub fn make_adapter_calldata( + opportunity: OpportunityEvm, + bid_params: BidParamsEvm, + wallet: LocalWallet, +) -> Result { + let signature = get_signature(opportunity.clone(), bid_params.clone(), wallet.clone())?; + let params = make_opportunity_execution_params(opportunity, bid_params, wallet.address())?; + + let calldata = opportunity_adapter::ExecuteOpportunityCall::encode( + opportunity_adapter::ExecuteOpportunityCall { + params, + signature: signature.to_vec().into(), + }, + ); + + Ok(calldata.into()) +} + +pub fn get_params(opportunity: OpportunityEvm) -> OpportunityCreateV1Evm { + let OpportunityParamsEvm::V1(OpportunityParamsV1Evm(params)) = opportunity.params; + params +} diff --git a/sdk/rust/src/lib.rs b/sdk/rust/src/lib.rs new file mode 100644 index 00000000..b4e2aecf --- /dev/null +++ b/sdk/rust/src/lib.rs @@ -0,0 +1,496 @@ +pub use { + ethers, + express_relay_api_types as api_types, +}; +use { + ethers::signers::LocalWallet, + evm::{ + get_config, + get_params, + make_adapter_calldata, + BidParamsEvm, + }, + express_relay_api_types::{ + bid::{ + BidCreate, + BidCreateEvm, + }, + opportunity::{ + GetOpportunitiesQueryParams, + Opportunity, + Route, + }, + ws::ServerResultMessage, + ErrorBodyResponse, + Routable, + }, + futures_util::{ + SinkExt, + Stream, + StreamExt, + }, + reqwest::Response, + serde::{ + de::DeserializeOwned, + Deserialize, + Serialize, + }, + std::{ + collections::HashMap, + marker::PhantomData, + pin::Pin, + sync::Arc, + task::{ + Context, + Poll, + }, + time::Duration, + }, + tokio::{ + net::TcpStream, + sync::{ + broadcast, + mpsc, + oneshot, + RwLock, + }, + }, + tokio_stream::wrappers::{ + errors::BroadcastStreamRecvError, + BroadcastStream, + }, + tokio_tungstenite::{ + connect_async, + tungstenite::{ + client::IntoClientRequest, + Message, + }, + MaybeTlsStream, + WebSocketStream, + }, + url::Url, +}; + +pub mod evm; + +pub struct Client { + http_url: Url, + ws_url: Url, + api_key: Option, + client: reqwest::Client, +} + +pub struct ClientConfig { + pub http_url: String, + pub api_key: Option, +} + +#[derive(Debug)] +pub enum ClientError { + InvalidHttpUrl(String), + RequestFailed(reqwest::Error), + RequestError(String), + DecodeResponseFailed(reqwest::Error), + WsConnectFailed(String), + WsRequestFailed(String), + InvalidResponse(String), + ChainNotSupported, + NewBidError(String), +} + +enum DecodedResponse { + Ok(T), + Err(ErrorBodyResponse), +} + +impl<'de, T: DeserializeOwned> serde::Deserialize<'de> for DecodedResponse { + fn deserialize(deserializer: D) -> Result, D::Error> + where + D: ::serde::Deserializer<'de>, + { + let json_value = serde_json::Value::deserialize(deserializer)?; + let value: Result = serde_json::from_value(json_value.clone()); + match value { + Ok(response) => Ok(DecodedResponse::Ok(response)), + Err(error) => serde_json::from_value(json_value) + .map(DecodedResponse::Err) + .map_err(|_| serde::de::Error::custom(error)), + } + } +} + +type WsRequest = ( + api_types::ws::ClientRequest, + oneshot::Sender, +); + +pub struct WsClientInner { + #[allow(dead_code)] + ws: tokio::task::JoinHandle<()>, + request_sender: mpsc::UnboundedSender, + request_id: RwLock, + + update_receiver: broadcast::Receiver, +} + +#[derive(Clone)] +pub struct WsClient { + inner: Arc, +} + +#[derive(Deserialize)] +#[serde(untagged)] +enum MessageType { + Response(api_types::ws::ServerResultResponse), + Update(api_types::ws::ServerUpdateResponse), +} + +pub struct WsClientUpdateStream<'a> { + stream: BroadcastStream, + _lifetime: PhantomData<&'a ()>, +} + +impl WsClientUpdateStream<'_> { + pub fn new(stream: BroadcastStream) -> Self { + Self { + stream, + _lifetime: PhantomData, + } + } +} + +// Implementing Stream trait +impl Stream for WsClientUpdateStream<'_> { + type Item = Result; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let stream = &mut self.get_mut().stream; + stream.poll_next_unpin(cx) + } +} + +impl WsClient { + pub fn get_update_stream(&self) -> WsClientUpdateStream { + WsClientUpdateStream::new(BroadcastStream::new( + self.inner.update_receiver.resubscribe(), + )) + } + + async fn run( + mut ws_stream: WebSocketStream>, + mut request_receiver: mpsc::UnboundedReceiver, + update_sender: broadcast::Sender, + ) { + let mut connection_check = tokio::time::interval(Duration::from_secs(1)); + let ping_duration = Duration::from_secs(32); // 30 seconds + 2 seconds to account for extra latency + let mut latest_ping = tokio::time::Instant::now(); + let mut requests_map = HashMap::>::new(); + loop { + tokio::select! { + message = ws_stream.next() => { + let message = match message { + Some(message) => { + match message { + Ok(message) => message, + Err(_) => continue, + } + } + None => break, + }; + + let message = match message { + Message::Text(text) => { + let response: Result = serde_json::from_str(&text); + match response { + Ok(response) => response, + Err(_) => continue, + } + } + Message::Binary(binary) => { + let response: Result = serde_json::from_slice(binary.as_slice()); + match response { + Ok(response) => response, + Err(_) => continue, + } + } + Message::Close(_) => break, + Message::Pong(_) => continue, + Message::Ping(data) => { + latest_ping = tokio::time::Instant::now(); + let _ = ws_stream.send(Message::Pong(data)).await; + continue; + }, + Message::Frame(_) => continue, + }; + + match message { + MessageType::Response(response) => { + response.id.and_then(|id| requests_map.remove(&id)).map(|sender| sender.send(response.result)); + } + MessageType::Update(update) => { + _ = update_sender.send(update); + continue; + } + } + } + request = request_receiver.recv() => { + match request { + Some((request, response_sender)) => { + if ws_stream.send(Message::Text(serde_json::to_string(&request).unwrap())).await.is_ok() { + requests_map.insert(request.id.clone(), response_sender); + } + } + None => break, + } + } + _ = connection_check.tick() => { + if latest_ping.elapsed() > ping_duration { + break; + } + }, + } + } + } + + async fn fetch_add_request_id(&self) -> u64 { + let mut write_gaurd = self.inner.request_id.write().await; + *write_gaurd += 1; + *write_gaurd + } + + async fn send( + &self, + message: api_types::ws::ClientMessage, + ) -> Result { + let request_id = self.fetch_add_request_id().await; + let request = api_types::ws::ClientRequest { + id: request_id.to_string(), + msg: message, + }; + + let (response_sender, response_receiver) = oneshot::channel(); + if self + .inner + .request_sender + .send((request, response_sender)) + .is_err() + { + return Err(ClientError::WsRequestFailed( + "Failed to send request".to_string(), + )); + } + + match tokio::time::timeout(Duration::from_secs(5), response_receiver).await { + Ok(response) => match response { + Ok(response) => Ok(response), + Err(_) => Err(ClientError::WsRequestFailed( + "Response channel closed".to_string(), + )), + }, + // TODO: Clear this request from the requests_map + Err(_) => Err(ClientError::WsRequestFailed( + "Ws request timeout".to_string(), + )), + } + } + + pub async fn chain_subscribe(&self, chain_ids: Vec) -> Result<(), ClientError> { + let message = api_types::ws::ClientMessage::Subscribe { + chain_ids: chain_ids + .iter() + .map(|chain_id| chain_id.to_string()) + .collect(), + }; + let result = self.send(message).await?; + match result { + ServerResultMessage::Success(_) => Ok(()), + ServerResultMessage::Err(error) => Err(ClientError::WsRequestFailed(error)), + } + } + + pub async fn chain_unsubscribe(&self, chain_ids: Vec) -> Result<(), ClientError> { + let message = api_types::ws::ClientMessage::Unsubscribe { + chain_ids: chain_ids + .iter() + .map(|chain_id| chain_id.to_string()) + .collect(), + }; + let result = self.send(message).await?; + match result { + ServerResultMessage::Success(_) => Ok(()), + ServerResultMessage::Err(error) => Err(ClientError::WsRequestFailed(error)), + } + } + + pub async fn submit_bid( + &self, + bid: api_types::bid::BidCreate, + ) -> Result { + let message = api_types::ws::ClientMessage::PostBid { bid }; + let result = self.send(message).await?; + match result { + ServerResultMessage::Success(response) => { + let response = response.ok_or(ClientError::InvalidResponse( + "Invalid server response: Expected BidResult but got None.".to_string(), + ))?; + let api_types::ws::APIResponse::BidResult(response) = response; + Ok(response) + } + ServerResultMessage::Err(error) => Err(ClientError::WsRequestFailed(error)), + } + } +} + +impl Client { + async fn decode(response: Response) -> Result { + match response.json().await { + Ok(DecodedResponse::Ok(response)) => Ok(response), + Ok(DecodedResponse::Err(response)) => Err(ClientError::RequestError(response.error)), + Err(e) => Err(ClientError::DecodeResponseFailed(e)), + } + } + + async fn send( + &self, + route: impl Routable, + query: Option, + ) -> Result { + let properties = route.properties(); + let url = self + .http_url + .join(properties.full_path.as_str()) + .map_err(|e| ClientError::InvalidHttpUrl(e.to_string()))?; + let mut request = self.client.request(properties.method, url); + if let Some(api_key) = self.api_key.clone() { + request = request.bearer_auth(api_key); + } + if let Some(query) = query { + request = request.query(&query); + } + let response = request.send().await.map_err(ClientError::RequestFailed)?; + Client::decode(response).await + } + + pub fn try_new(config: ClientConfig) -> Result { + let http_url = Url::parse(config.http_url.as_str()) + .map_err(|e| ClientError::InvalidHttpUrl(e.to_string()))?; + + if http_url.scheme() != "http" && http_url.scheme() != "https" { + return Err(ClientError::InvalidHttpUrl(format!( + "Invalid scheme {}", + http_url.scheme() + ))); + } + + let ws_url_string = if http_url.scheme() == "http" { + config.http_url.replace("http", "ws") + } else { + config.http_url.replace("https", "wss") + }; + let ws_url = Url::parse(ws_url_string.as_str()).expect("Failed to parse ws url"); + + Ok(Self { + http_url, + ws_url, + api_key: config.api_key, + client: reqwest::Client::new(), + }) + } + + pub async fn connect_websocket(&self) -> Result { + let url = self + .ws_url + .join(api_types::ws::Route::Ws.properties().full_path.as_str()) + .map_err(|e| ClientError::WsConnectFailed(e.to_string()))?; + let mut request = url + .as_str() + .into_client_request() + .map_err(|e| ClientError::WsConnectFailed(e.to_string()))?; + if let Some(api_key) = self.api_key.clone() { + let bearer_token = format!("Bearer {}", api_key); + request.headers_mut().insert( + "Authorization", + bearer_token.parse().map_err(|_| { + ClientError::WsConnectFailed("Failed to parse api key".to_string()) + })?, + ); + } + let (ws_stream, _) = connect_async(request) + .await + .map_err(|e| ClientError::WsConnectFailed(e.to_string()))?; + + let (request_sender, request_receiver) = mpsc::unbounded_channel(); + let (update_sender, update_receiver) = broadcast::channel(1000); + + Ok(WsClient { + inner: Arc::new(WsClientInner { + request_sender, + update_receiver, + request_id: RwLock::new(0), + ws: tokio::spawn(WsClient::run(ws_stream, request_receiver, update_sender)), + }), + }) + } + + pub async fn get_opportunities( + &self, + params: Option, + ) -> Result, ClientError> { + self.send(Route::GetOpportunities, params).await + } + + pub async fn new_bid( + opportunity: T, + params: T::Params, + private_key: String, + ) -> Result { + T::new_bid(opportunity, params, private_key) + } +} + +pub trait Biddable { + type Params; + + fn new_bid( + opportunity: Self, + params: Self::Params, + private_key: String, + ) -> Result; +} + +impl Biddable for api_types::opportunity::OpportunityEvm { + type Params = BidParamsEvm; + + fn new_bid( + opportunity: Self, + bid_params: Self::Params, + private_key: String, + ) -> Result { + let private_key = private_key.parse::().map_err(|e| { + ClientError::NewBidError(format!("Failed to parse private key: {:?}", e)) + })?; + let params = get_params(opportunity.clone()); + let config = get_config(params.chain_id.as_str())?; + let wallet = LocalWallet::from(private_key); + let bid = BidCreateEvm { + permission_key: params.permission_key, + chain_id: params.chain_id, + target_contract: config.adapter_factory_contract, + amount: bid_params.amount, + target_calldata: make_adapter_calldata(opportunity.clone(), bid_params, wallet)?, + }; + Ok(BidCreate::Evm(bid)) + } +} + +impl Biddable for api_types::opportunity::OpportunitySvm { + type Params = i64; + + fn new_bid( + _opportunity: Self, + _params: Self::Params, + _private_key: String, + ) -> Result { + todo!() + } +}