diff --git a/.github/workflows/sdk-wheels.yml b/.github/workflows/sdk-wheels.yml index 62a9cbe4..36db9fc0 100644 --- a/.github/workflows/sdk-wheels.yml +++ b/.github/workflows/sdk-wheels.yml @@ -119,7 +119,7 @@ jobs: - name: Smoke test wheel shell: bash run: | - pip install --find-links sdk/dist aleo + pip install --find-links sdk/dist aleo-sdk python -c " from aleo.mainnet import PrivateKey as MainnetPrivateKey from aleo.testnet import PrivateKey as TestnetPrivateKey @@ -185,7 +185,7 @@ jobs: - name: Smoke test wheel shell: bash run: | - pip install --find-links sdk-abi/dist aleo-abi + pip install --find-links sdk-abi/dist aleo-contract-abi-generator python -c "import aleo_abi; print(aleo_abi.generate_abi.__name__)" - name: Upload wheel uses: actions/upload-artifact@v4 diff --git a/.github/workflows/sdk.yml b/.github/workflows/sdk.yml index 7a8379ae..6cee53f7 100644 --- a/.github/workflows/sdk.yml +++ b/.github/workflows/sdk.yml @@ -74,7 +74,7 @@ jobs: python ../.github/scripts/merge_testnet_so.py dist dist-testnet - name: Install wheel + test deps run: | - pip install --find-links dist aleo + pip install --find-links dist aleo-sdk pip install pytest pytest-xdist httpx pynacl responses pytest-asyncio # Fast, offline tests; -n auto parallelizes across cores. - name: pytest (fast suite) @@ -116,7 +116,7 @@ jobs: python ../.github/scripts/merge_testnet_so.py dist dist-testnet - name: Install wheel + test deps run: | - pip install --find-links dist aleo + pip install --find-links dist aleo-sdk pip install pytest httpx pynacl responses pytest-asyncio # The two slow tests share one module-scoped proven execution; xdist # would prove twice, so they run in a single worker on purpose. @@ -129,7 +129,7 @@ jobs: run: python -m pytest python/tests/test_testnet.py -v test-abi: - name: Test (aleo-abi package) + name: Test (aleo-contract-abi-generator package) runs-on: ubuntu-latest defaults: run: @@ -155,10 +155,10 @@ jobs: exit 1 fi # Build the aleo two-network wheel (mainnet + testnet merged) plus the - # aleo-abi wheel. The testnet .so must be spliced into the aleo wheel - # BEFORE the aleo-abi wheel lands in dist, so the merge sees only the + # aleo-contract-abi-generator wheel. The testnet .so must be spliced into the aleo wheel + # BEFORE the aleo-contract-abi-generator wheel lands in dist, so the merge sees only the # aleo wheel. - - name: Build wheels (aleo two-network + aleo-abi) + - name: Build wheels (aleo two-network + aleo-contract-abi-generator) run: | pip install maturin pytest requests maturin build --release --features mainnet --manifest-path sdk/Cargo.toml --out dist @@ -169,11 +169,11 @@ jobs: maturin build --release --manifest-path sdk-abi/Cargo.toml --out dist - name: Install wheels run: | - pip install --find-links dist aleo aleo-abi + pip install --find-links dist aleo-sdk aleo-contract-abi-generator # Run each suite from inside its package dir so pytest uses that # package's own pytest.ini (sdk-abi/pytest.ini, sdk/pytest.ini) rather # than walking up to the stale legacy root setup.cfg. - - name: pytest (aleo-abi package suite) + - name: pytest (aleo-contract-abi-generator package suite) run: | cd sdk-abi python -m pytest python/tests -v diff --git a/sdk-abi/Cargo.lock b/sdk-abi/Cargo.lock index bc5e2b72..2ca04c21 100644 --- a/sdk-abi/Cargo.lock +++ b/sdk-abi/Cargo.lock @@ -19,13 +19,16 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "aleo-abi" -version = "0.1.0" +version = "0.2.0" dependencies = [ "anyhow", "leo-abi", "leo-ast", + "leo-disassembler", + "leo-span", "pyo3", "serde_json", + "snarkvm", ] [[package]] diff --git a/sdk-abi/Cargo.toml b/sdk-abi/Cargo.toml index eff95abe..be0f04fe 100644 --- a/sdk-abi/Cargo.toml +++ b/sdk-abi/Cargo.toml @@ -5,7 +5,7 @@ [package] name = "aleo-abi" -version = "0.1.0" +version = "0.2.0" edition = "2024" license = "GPL-3.0-or-later" description = "Python bindings for ABI generation from Aleo bytecode (via Leo's leo-abi crate)" @@ -20,3 +20,8 @@ pyo3 = { version = "0.20.0", features = ["extension-module", "abi3-py37", "anyho serde_json = "1" leo-abi = { git = "https://github.com/ProvableHQ/leo", rev = "ba2c01722a48f84b4d90b93aeaf8305b7c03dbce", package = "leo-abi", features = ["aleo-bytecode"] } leo-ast = { git = "https://github.com/ProvableHQ/leo", rev = "ba2c01722a48f84b4d90b93aeaf8305b7c03dbce", package = "leo-ast" } +leo-disassembler = { git = "https://github.com/ProvableHQ/leo", rev = "ba2c01722a48f84b4d90b93aeaf8305b7c03dbce", package = "leo-disassembler" } +leo-span = { git = "https://github.com/ProvableHQ/leo", rev = "ba2c01722a48f84b4d90b93aeaf8305b7c03dbce", package = "leo-span" } +# Same tag + feature set leo pins, so `Process`/`Program` are the same +# types leo-disassembler's signatures expect. +snarkvm = { git = "https://github.com/ProvableHQ/snarkVM", tag = "v4.8.1", features = ["test_consensus_heights", "dev_skip_checks", "test_targets", "history"] } diff --git a/sdk-abi/README.md b/sdk-abi/README.md new file mode 100644 index 00000000..2b882453 --- /dev/null +++ b/sdk-abi/README.md @@ -0,0 +1,93 @@ +# aleo-contract-abi-generator + +Generates a JSON ABI from deployed Aleo bytecode, and checks one ABI against +another for compatibility. Rust bindings around Leo's ABI generation with +full snarkVM validation — a program that does not validate does not get an +ABI. Everything runs locally; nothing touches the network. + +The distribution is `aleo-contract-abi-generator`; the import module is +`aleo_abi`. + +```python +import aleo_abi + +abi_json = aleo_abi.generate_abi("simple.aleo", bytecode, "testnet", None) +violations = aleo_abi.check_compatibility(candidate_json, standard_json) +``` + +## Install + +```bash +pip install aleo-contract-abi-generator +``` + +Most callers want the friendlier hook in the main SDK instead — +`aleo.abi.generate_abi` accepts a `Program` object or a raw bytecode string, +infers the program name, and returns a dict: + +```python +from aleo import abi +from aleo.mainnet import Program + +result = abi.generate_abi(Program.credits()) +result["program"] # "credits.aleo" +``` + +The hook imports this package lazily and raises `ImportError` with the +install command if it is absent — the main SDK does not depend on it. + +## Generating an ABI + +`generate_abi(program_name, bytecode, network, imports)` returns a +pretty-printed JSON string describing the program: its `structs`, `records`, +`mappings`, and `functions`, each field carrying a structured type +(`{"Primitive": {"Int": "I32"}}`, record ownership, visibility). + +snarkVM validation is **contextual**: a program that declares imports is +rejected unless those imports are supplied. Pass them as +`(program_id, bytecode)` pairs in topological order — dependencies before +dependents: + +```python +abi_json = aleo_abi.generate_abi( + "shield_swap_v3.aleo", amm_bytecode, "testnet", + [("test_shield_swap_multisig_core.aleo", multisig_bytecode)], +) +``` + +`network` is `"mainnet"`, `"testnet"`, or `"canary"` — it selects the +validation rules, not a connection. + +## Checking compatibility + +`check_compatibility(candidate_abi_json, standard_abi_json)` returns a list +of violation strings — empty means the candidate satisfies the standard. +Use it to pin a deployed contract's surface and fail *your* CI when the +deployment drifts, instead of your consumers: + +```python +violations = aleo_abi.check_compatibility(deployed_abi, pinned_abi) +assert not violations, "\n".join(violations) +``` + +This is how `shield-swap-sdk`'s live drift test guards its committed +bindings (`codegen/regen-abi.sh` regenerates the pin from the deployed +program). + +## Downstream: generated Python bindings + +The ABI JSON is the input format for the main SDK's `aleo.codegen`, which +emits typed dataclasses and entrypoint stubs from it: + +```bash +python -m aleo.codegen --abi shield_swap.abi.json --out _generated.py +``` + +## Tests + +```bash +cd sdk-abi && python -m pytest python/tests -v # hermetic — no network +``` + +Fixtures and expected ABIs are vendored from Leo's own test suite, so the +output shape is pinned to upstream. diff --git a/sdk-abi/pyproject.toml b/sdk-abi/pyproject.toml index 26e40784..b3f8ff76 100644 --- a/sdk-abi/pyproject.toml +++ b/sdk-abi/pyproject.toml @@ -3,9 +3,10 @@ requires = ["maturin>=1.0,<2.0"] build-backend = "maturin" [project] -name = "aleo-abi" -version = "0.1.0" +name = "aleo-contract-abi-generator" +version = "0.2.0" description = "Python bindings for ABI generation from Aleo bytecode" +readme = "README.md" license = {text = "GPL-3.0-or-later"} requires-python = ">=3.7" dependencies = [] diff --git a/sdk-abi/python/tests/test_abi.py b/sdk-abi/python/tests/test_abi.py index 47b990d6..658e3b24 100644 --- a/sdk-abi/python/tests/test_abi.py +++ b/sdk-abi/python/tests/test_abi.py @@ -1,6 +1,6 @@ # Copyright (C) 2024 Provable Inc. # SPDX-License-Identifier: GPL-3.0-or-later -"""Tests for the aleo-abi package.""" +"""Tests for the aleo-contract-abi-generator package.""" import json diff --git a/sdk-abi/src/lib.rs b/sdk-abi/src/lib.rs index 63059128..a43a7058 100644 --- a/sdk-abi/src/lib.rs +++ b/sdk-abi/src/lib.rs @@ -21,20 +21,68 @@ fn parse_network(network: &str) -> anyhow::Result { } } +/// Generate an ABI with snarkVM validation, loading `imports` into the +/// process first (in the given order) so import-using programs validate. +fn generate_with_imports( + program_name: &str, + bytecode: &str, + imports: &[(String, String)], +) -> anyhow::Result { + use std::str::FromStr; + leo_span::create_session_if_not_set_then(|_| { + let mut process = snarkvm::prelude::Process::::load() + .map_err(|e| anyhow::anyhow!("failed to load snarkVM process: {e}"))?; + for (dep_name, dep_src) in imports { + let dep = snarkvm::prelude::Program::::from_str(dep_src) + .map_err(|e| anyhow::anyhow!("import {dep_name} failed to parse: {e}"))?; + process + .lock() + .add_program(&dep) + .map_err(|e| anyhow::anyhow!("import {dep_name} failed snarkVM validation: {e}"))?; + } + let aleo = leo_disassembler::disassemble_from_str(program_name, bytecode, &mut process) + .map_err(|e| anyhow::anyhow!("{e}"))?; + Ok(leo_abi::aleo::generate(&aleo)) + }) +} + /// Generate an ABI JSON string from Aleo bytecode. /// /// Args: /// program_name: The program name (e.g. "token.aleo"). /// bytecode: The Aleo bytecode string. /// network: One of "mainnet", "testnet", or "canary". +/// imports: Optional list of (program_id, bytecode) dependencies, in +/// topological order (dependencies before dependents). snarkVM's +/// validation is contextual: a program whose imports are not loaded +/// first is rejected, so import-using programs require this. /// /// Returns: /// A pretty-printed JSON string representing the program ABI. #[pyfunction] -fn generate_abi(program_name: &str, bytecode: &str, network: &str) -> anyhow::Result { +#[pyo3(signature = (program_name, bytecode, network, imports = None))] +fn generate_abi( + program_name: &str, + bytecode: &str, + network: &str, + imports: Option>, +) -> anyhow::Result { let net = parse_network(network)?; - let abi = leo_abi::aleo::generate_from_bytecode(program_name, bytecode, net) - .map_err(|e| anyhow::anyhow!("{}", e))?; + let abi = match imports { + None => leo_abi::aleo::generate_from_bytecode(program_name, bytecode, net) + .map_err(|e| anyhow::anyhow!("{}", e))?, + Some(deps) => match net { + leo_ast::NetworkName::MainnetV0 => { + generate_with_imports::(program_name, bytecode, &deps)? + } + leo_ast::NetworkName::TestnetV0 => { + generate_with_imports::(program_name, bytecode, &deps)? + } + leo_ast::NetworkName::CanaryV0 => { + generate_with_imports::(program_name, bytecode, &deps)? + } + }, + }; Ok(serde_json::to_string_pretty(&abi)?) } diff --git a/sdk/docs/source/usage.rst b/sdk/docs/source/usage.rst index b9f8e83d..e985ecdc 100644 --- a/sdk/docs/source/usage.rst +++ b/sdk/docs/source/usage.rst @@ -6,4 +6,4 @@ To use Aleo SDK, first install it using pip: .. code-block:: console - (.venv) $ pip install aleo + (.venv) $ pip install aleo-sdk diff --git a/sdk/pyproject.toml b/sdk/pyproject.toml index 2fe08340..33b181f2 100644 --- a/sdk/pyproject.toml +++ b/sdk/pyproject.toml @@ -1,6 +1,6 @@ [project] -name = "aleo" -description = "A Python SDK for zero-knowledge cryptography based on Aleo" +name = "aleo-sdk" +description = "Python SDK for building zero-knowledge apps and DeFi on the Aleo network" version = "0.2.0" readme = "Readme.md" license = {file = "LICENSE.md"} diff --git a/sdk/python/aleo/_client_common.py b/sdk/python/aleo/_client_common.py index 6d65450b..f46142a8 100644 --- a/sdk/python/aleo/_client_common.py +++ b/sdk/python/aleo/_client_common.py @@ -53,11 +53,16 @@ def is_provable_host(url: str) -> bool: def package_version() -> str: - try: - from importlib.metadata import version - return version("aleo") - except Exception: - return "0.0.0" + from importlib.metadata import version + + # "aleo" is the pre-0.2 distribution name; keep it as a fallback so + # older installs still report their real version. + for dist in ("aleo-sdk", "aleo"): + try: + return version(dist) + except Exception: + continue + return "0.0.0" def user_agent() -> str: diff --git a/sdk/python/aleo/abi.py b/sdk/python/aleo/abi.py index 7722131a..2896f40c 100644 --- a/sdk/python/aleo/abi.py +++ b/sdk/python/aleo/abi.py @@ -1,7 +1,7 @@ # Copyright (C) 2024 Provable Inc. # SPDX-License-Identifier: GPL-3.0-or-later # pyright: reportUnknownMemberType=false, reportUnknownVariableType=false, reportUnknownArgumentType=false -"""Integration hook: ABI generation via the aleo-abi package.""" +"""Integration hook: ABI generation via the aleo-contract-abi-generator package.""" from __future__ import annotations import json @@ -9,27 +9,35 @@ from typing import Any, Union -def generate_abi(program: object, network: str = "mainnet") -> dict[str, Any]: +def generate_abi( + program: object, + network: str = "mainnet", + imports: "list[tuple[str, str]] | None" = None, +) -> dict[str, Any]: """Generate an ABI dict for an Aleo program. Args: program: Either an aleo Program object (with .source and .id attributes) or a raw bytecode string. network: Network name: "mainnet", "testnet", or "canary". + imports: Optional ``(program_id, bytecode)`` dependencies in + topological order (dependencies before dependents). snarkVM + validation is contextual, so a program that declares imports + is rejected unless they are supplied here. Returns: A dict containing the ABI for the program. Raises: - ImportError: If the aleo-abi package is not installed. + ImportError: If the aleo-contract-abi-generator package is not installed. ValueError: If the program name cannot be determined. """ try: import aleo_abi as _aleo_abi # pyright: ignore[reportMissingImports] except ImportError: raise ImportError( - "The aleo-abi package is required for ABI generation. " - "Install it with: pip install aleo-abi" + "The aleo-contract-abi-generator package is required for ABI generation. " + "Install it with: pip install aleo-contract-abi-generator" ) # Duck-type: if it has .source and .id, treat as Program object @@ -51,7 +59,7 @@ def generate_abi(program: object, network: str = "mainnet") -> dict[str, Any]: f"Expected a Program object or str, got {type(program).__name__}" ) - json_str = _aleo_abi.generate_abi(name, bytecode, network) + json_str = _aleo_abi.generate_abi(name, bytecode, network, imports) return json.loads(json_str) @@ -69,14 +77,14 @@ def check_compatibility( A list of violation strings. Empty list means compatible. Raises: - ImportError: If the aleo-abi package is not installed. + ImportError: If the aleo-contract-abi-generator package is not installed. """ try: import aleo_abi as _aleo_abi # pyright: ignore[reportMissingImports] except ImportError: raise ImportError( - "The aleo-abi package is required for compatibility checking. " - "Install it with: pip install aleo-abi" + "The aleo-contract-abi-generator package is required for compatibility checking. " + "Install it with: pip install aleo-contract-abi-generator" ) if isinstance(candidate, dict): diff --git a/sdk/python/aleo/async_network_client.py b/sdk/python/aleo/async_network_client.py index dbb976a9..32e6cdb7 100644 --- a/sdk/python/aleo/async_network_client.py +++ b/sdk/python/aleo/async_network_client.py @@ -81,7 +81,7 @@ def __init__( except ImportError: raise ImportError( "httpx is required for AsyncAleoNetworkClient. " - "Install with: pip install aleo[async]" + "Install with: pip install aleo-sdk[async]" ) from None self._network: str = network diff --git a/sdk/python/aleo/async_record_scanner.py b/sdk/python/aleo/async_record_scanner.py index b4d39b53..628af59a 100644 --- a/sdk/python/aleo/async_record_scanner.py +++ b/sdk/python/aleo/async_record_scanner.py @@ -76,7 +76,7 @@ def __init__( except ImportError: raise ImportError( "httpx is required for AsyncRecordScanner. " - "Install with: pip install aleo[async]" + "Install with: pip install aleo-sdk[async]" ) from None # Validate: URL must not end with a network suffix diff --git a/sdk/python/aleo/codegen/__init__.py b/sdk/python/aleo/codegen/__init__.py index 77aaaf2b..fa185af1 100644 --- a/sdk/python/aleo/codegen/__init__.py +++ b/sdk/python/aleo/codegen/__init__.py @@ -1,6 +1,6 @@ """aleo.codegen — build-time ABI→Python emitter. -Turns an ``aleo-abi`` JSON description of a program into a module of frozen +Turns an ``aleo-contract-abi-generator`` JSON description of a program into a module of frozen dataclasses with ``to_plaintext()`` encoders and ``from_plaintext()`` decoders. Build-time only: nothing in the ``aleo`` runtime imports this package, and generated modules import only :mod:`aleo.codegen.runtime`. diff --git a/sdk/python/aleo/codegen/_emit.py b/sdk/python/aleo/codegen/_emit.py index e08d797d..08cd8108 100644 --- a/sdk/python/aleo/codegen/_emit.py +++ b/sdk/python/aleo/codegen/_emit.py @@ -2,7 +2,7 @@ """ABI JSON → Python source emitter. Build-time only; the emitted code imports :mod:`aleo.codegen.runtime` for -parsing and formatting. The ABI shape this consumes is the ``aleo-abi`` +parsing and formatting. The ABI shape this consumes is the ``aleo-contract-abi-generator`` output: struct = ``{path: [Name], fields: [{name, ty}]}``, record fields add ``mode``, mapping = ``{name, key: ty, value: ty}``, and ``ty`` is either ``{"Primitive": ...}`` or ``{"Struct": {"path": [...], "program": ...}}``. diff --git a/sdk/python/aleo/facade/async_client.py b/sdk/python/aleo/facade/async_client.py index 0d93f9a1..8d1c7902 100644 --- a/sdk/python/aleo/facade/async_client.py +++ b/sdk/python/aleo/facade/async_client.py @@ -134,7 +134,7 @@ def abi(self) -> dict[str, Any]: """Generate the ABI for this program (object path, sync — local). Delegates to :func:`aleo.abi.generate_abi` with the underlying network - Program object. Raises :exc:`ImportError` if ``aleo-abi`` is absent. + Program object. Raises :exc:`ImportError` if ``aleo-contract-abi-generator`` is absent. """ from .. import abi as _abi return _abi.generate_abi(self._raw, self._client.network_name) @@ -189,7 +189,7 @@ async def abi(self, program_id: str, edition: int | None = None) -> dict[str, An ProgramNotFound If the network has no such program (a 404 from the node). ImportError - If the ``aleo-abi`` package is not installed. + If the ``aleo-contract-abi-generator`` package is not installed. """ async with _async_program_404(program_id): source: str = await self._client.network_client.get_program( @@ -1005,7 +1005,7 @@ def generate_abi( Raises ------ ImportError - If the ``aleo-abi`` package is not installed. + If the ``aleo-contract-abi-generator`` package is not installed. """ from .. import abi as _abi diff --git a/sdk/python/aleo/facade/client.py b/sdk/python/aleo/facade/client.py index e5cf9a26..32998f48 100644 --- a/sdk/python/aleo/facade/client.py +++ b/sdk/python/aleo/facade/client.py @@ -259,7 +259,7 @@ def generate_abi( Raises ------ ImportError - If the ``aleo-abi`` package is not installed. + If the ``aleo-contract-abi-generator`` package is not installed. """ from .. import abi as _abi from .programs import Program as _FacadeProgram diff --git a/sdk/python/aleo/facade/programs.py b/sdk/python/aleo/facade/programs.py index bb69e65e..b00eeb34 100644 --- a/sdk/python/aleo/facade/programs.py +++ b/sdk/python/aleo/facade/programs.py @@ -387,7 +387,7 @@ class Program: The program identifier string (e.g. ``"credits.aleo"``). functions: A :class:`ProgramFunctions` namespace built from the program's real - function set — works without ``aleo-abi`` installed. + function set — works without ``aleo-contract-abi-generator`` installed. """ def __init__(self, client: Any, raw: Any) -> None: @@ -446,7 +446,7 @@ def abi(self) -> dict[str, Any]: Delegates to :func:`aleo.abi.generate_abi` with the underlying network Program object. Lazy: raises :exc:`ImportError` (with an install hint) - only if the ``aleo-abi`` package is absent. + only if the ``aleo-contract-abi-generator`` package is absent. """ from .. import abi as _abi return _abi.generate_abi(self._raw, self._client.network_name) @@ -535,7 +535,7 @@ def abi(self, program_id: str, edition: int | None = None) -> dict[str, Any]: ProgramNotFound If the network has no such program (a 404 from the node). ImportError - If the ``aleo-abi`` package is not installed. + If the ``aleo-contract-abi-generator`` package is not installed. """ with _program_404(program_id): source: str = self._client.network.get_program(program_id, edition) diff --git a/sdk/python/aleo/security.py b/sdk/python/aleo/security.py index a5c981db..70953103 100644 --- a/sdk/python/aleo/security.py +++ b/sdk/python/aleo/security.py @@ -18,7 +18,7 @@ def encrypt_proving_request(public_key_b64: str, pr_bytes: bytes) -> str: except ImportError: raise ImportError( "PyNaCl is required for DPS encryption. " - "Install with: pip install aleo[dps]" + "Install with: pip install aleo-sdk[dps]" ) from None recipient_key = PublicKey(base64.b64decode(public_key_b64)) @@ -38,7 +38,7 @@ def encrypt_registration_request(public_key_b64: str, view_key: Any, start_block except ImportError: raise ImportError( "PyNaCl is required for record scanner registration. " - "Install with: pip install aleo[dps]" + "Install with: pip install aleo-sdk[dps]" ) from None vk_bytes = bytes(view_key.bytes()) # 32 bytes, LE diff --git a/sdk/python/tests/test_abi_hook.py b/sdk/python/tests/test_abi_hook.py index 2c13122b..22390372 100644 --- a/sdk/python/tests/test_abi_hook.py +++ b/sdk/python/tests/test_abi_hook.py @@ -37,7 +37,7 @@ _HAS_ALEO_ABI = importlib.util.find_spec("aleo_abi") is not None requires_aleo_abi = pytest.mark.skipif( - not _HAS_ALEO_ABI, reason="aleo-abi not installed (pip install aleo-abi)" + not _HAS_ALEO_ABI, reason="aleo-contract-abi-generator not installed (pip install aleo-contract-abi-generator)" ) @@ -73,7 +73,7 @@ def test_generate_abi_lazy_import_error(): from aleo import abi import importlib importlib.reload(abi) - with pytest.raises(ImportError, match="pip install aleo-abi"): + with pytest.raises(ImportError, match="pip install aleo-contract-abi-generator"): abi.generate_abi(SIMPLE_ALEO) finally: if saved is None: diff --git a/sdk/python/tests/test_security.py b/sdk/python/tests/test_security.py index dc9ab316..312775d7 100644 --- a/sdk/python/tests/test_security.py +++ b/sdk/python/tests/test_security.py @@ -81,7 +81,7 @@ def test_encrypt_requires_pynacl() -> None: import aleo.security as sec_mod # Force reimport importlib.reload(sec_mod) - with pytest.raises(ImportError, match="aleo\\[dps\\]"): + with pytest.raises(ImportError, match="aleo-sdk\\[dps\\]"): sec_mod.encrypt_proving_request("dGVzdA==", b"msg") finally: if original is None: diff --git a/sdk/python/tests/test_testnet.py b/sdk/python/tests/test_testnet.py index 51a33711..ecf4ba75 100644 --- a/sdk/python/tests/test_testnet.py +++ b/sdk/python/tests/test_testnet.py @@ -13,7 +13,7 @@ # The testnet extension (_aleolib_testnet) is only present in a two-build # install (see sdk/build-both.sh). Mainnet-only builds (e.g. the proving/network -# and aleo-abi CI lanes) don't compile it, so skip this whole module cleanly +# and aleo-contract-abi-generator CI lanes) don't compile it, so skip this whole module cleanly # rather than erroring at collection. pytest.importorskip("aleo._aleolib_testnet") diff --git a/sdk/src/lib.rs b/sdk/src/lib.rs index 60f1736f..ec15e333 100644 --- a/sdk/src/lib.rs +++ b/sdk/src/lib.rs @@ -51,6 +51,7 @@ fn register(_py: Python, m: &PyModule) -> PyResult<()> { m.add_class::()?; m.add_class::()?; m.add_class::()?; + m.add_class::()?; m.add_class::()?; m.add_class::()?; m.add_class::()?; diff --git a/sdk/src/programs/deployment.rs b/sdk/src/programs/deployment.rs new file mode 100644 index 00000000..b495a178 --- /dev/null +++ b/sdk/src/programs/deployment.rs @@ -0,0 +1,126 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the Aleo SDK library. + +// The Aleo SDK library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Aleo SDK library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Aleo SDK library. If not, see . + +use crate::{ + types::{CertificateNative, DeploymentNative, VerifyingKeyNative}, + Address, Field, Program, +}; + +use pyo3::prelude::*; + +use std::str::FromStr; + +// Dummy verifying key + certificate for devnode deployments (the devnode +// skips certificate verification). Copied from the wasm SDK's +// `buildDevnodeDeploymentTransaction`: the key encodes num_public_inputs=64 +// to accommodate functions with many inputs/outputs. +const DEVNODE_VERIFIER_KEY: &str = "verifier1q9qqqqqqqqqqqqyvxgqqqqqqqqq87vsqqqqqqqqqhe7sqqqqqqqqqma4qqqqqqqqqq65yqqqqqqqqqqvqqqqqqqqqqqgtlaj49fmrk2d8slmselaj9tpucgxv6awu6yu4pfcn5xa0yy0tpxpc8wemasjvvxr9248vt3509vpk3u60ejyfd9xtvjmudpp7ljq2csk4yqz70ug3x8xp3xn3ul0yrrw0mvd2g8ju7rts50u3smue03gp99j88f0ky8h6fjlpvh58rmxv53mldmgrxa3fq6spsh8gt5whvsyu2rk4a2wmeyrgvvdf29pwp02srktxnvht3k6ff094usjtllggva2ym75xc4lzuqu9xx8ylfkm3qc7lf7ktk9uu9du5raukh828dzgq26hrarq5ajjl7pz7zk924kekjrp92r6jh9dpp05mxtuffwlmvew84dvnqrkre7lw29mkdzgdxwe7q8z0vnkv2vwwdraekw2va3plu7rkxhtnkuxvce0qkgxcxn5mtg9q2c3vxdf2r7jjse2g68dgvyh85q4mzfnvn07lletrpty3vypus00gfu9m47rzay4mh5w9f03z9zgzgzhkv0mupdqsk8naljqm9tc2qqzhf6yp3mnv2ey89xk7sw9pslzzlkndfd2upzmew4e4vnrkr556kexs9qrykkuhsr260mnrgh7uv0sp2meky0keeukaxgjdsnmy77kl48g3swcvqdjm50ejzr7x04vy7hn7anhd0xeetclxunnl7pd6e52qxdlr3nmutz4zr8f2xqa57a2zkl59a28w842cj4783zpy9hxw03k6vz4a3uu7sm072uqknpxjk8fyq4vxtqd08kd93c2mt40lj9ag35nm4rwcfjayejk57m9qqu83qnkrj3sz90pw808srmf705n2yu6gvqazpvu2mwm8x6mgtlsntxfhr0qas43rqxnccft36z4ygty86390t7vrt08derz8368z8ekn3yywxgp4uq24gm6e58tpp0lcvtpsm3nkwpnmzztx4qvkaf6vk38wg787h8mfpqqqqqqqqqqffkful"; +const DEVNODE_CERTIFICATE: &str = + "certificate1qyqsqqqqqqqqqqxvwszp09v860w62s2l4g6eqf0kzppyax5we36957ywqm2dplzwvvlqg0kwlnmhzfatnax7uaqt7yqqqw0sc4u"; + +/// A program deployment: the program, its synthesized verifying keys and +/// certificates, and (V9+) the program checksum and owner address. +/// +/// Produced by `Process.deploy`; consumed by `Transaction.from_deployment`. +#[pyclass(frozen)] +#[derive(Clone)] +pub struct Deployment(DeploymentNative); + +#[pymethods] +impl Deployment { + /// Constructs a Deployment from a JSON string. + #[staticmethod] + fn from_json(json: &str) -> anyhow::Result { + DeploymentNative::from_str(json).map(Self) + } + + /// Builds a deployment WITHOUT synthesizing circuit keys: every function + /// and record gets a shared dummy verifying key + certificate. Devnodes + /// accept it (they skip certificate verification); real networks reject + /// it. Mirrors the wasm SDK's `buildDevnodeDeploymentTransaction` + /// (V9+ checksum/owner and V14+ record keys are always set). + #[staticmethod] + #[pyo3(signature = (program, owner, edition = 0))] + fn from_program_unproven( + program: &Program, + owner: &Address, + edition: u16, + ) -> anyhow::Result { + if program.functions().is_empty() { + anyhow::bail!( + "Attempted to create an empty deployment: {} has no functions", + program.id() + ); + } + let vk = VerifyingKeyNative::from_str(DEVNODE_VERIFIER_KEY)?; + let cert = CertificateNative::from_str(DEVNODE_CERTIFICATE)?; + let mut verifying_keys = + Vec::with_capacity(program.functions().len() + program.records().len()); + for function_name in program.functions().keys() { + verifying_keys.push((*function_name, (vk.clone(), cert.clone()))); + } + for record_name in program.records().keys() { + verifying_keys.push((*record_name, (vk.clone(), cert.clone()))); + } + let mut deployment = + DeploymentNative::new(edition, (**program).clone(), verifying_keys, None, None)?; + deployment.set_program_checksum_raw(Some(deployment.program().to_checksum())); + deployment.set_program_owner_raw(Some(**owner)); + Ok(Self(deployment)) + } + + /// Returns the JSON string representation of the deployment. + fn to_json(&self) -> anyhow::Result { + Ok(serde_json::to_string(&self.0)?) + } + + /// Returns the deployment ID (the fee's `deployment_or_execution_id`). + fn deployment_id(&self) -> anyhow::Result { + self.0.to_deployment_id().map(Into::into) + } + + /// Returns the program ID being deployed. + fn program_id(&self) -> String { + self.0.program_id().to_string() + } + + /// Returns the number of functions in the deployed program. + fn num_functions(&self) -> usize { + self.0.program().functions().len() + } + + fn __str__(&self) -> anyhow::Result { + self.to_json() + } +} + +impl From for Deployment { + fn from(value: DeploymentNative) -> Self { + Self(value) + } +} + +impl From for DeploymentNative { + fn from(value: Deployment) -> Self { + value.0 + } +} + +impl AsRef for Deployment { + fn as_ref(&self) -> &DeploymentNative { + &self.0 + } +} diff --git a/sdk/src/programs/execution.rs b/sdk/src/programs/execution.rs index e4947936..b19aceed 100644 --- a/sdk/src/programs/execution.rs +++ b/sdk/src/programs/execution.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Aleo SDK library. If not, see . -use crate::{programs::Transition, types::ExecutionNative, Field}; +use crate::{programs::Transition, types::ExecutionNative, Authorization, Field}; use pyo3::prelude::*; use snarkvm::prelude::{FromBytes, ToBytes}; @@ -34,6 +34,23 @@ impl Execution { self.0.to_execution_id().map(Into::into) } + /// Builds an UNPROVEN execution from an authorization — for devnodes + /// only (they skip proof verification); real networks reject it. + /// + /// `state_root` is the node's latest global state root (`sr1…`). + #[staticmethod] + fn from_authorization_unproven( + authorization: &Authorization, + state_root: &str, + ) -> anyhow::Result { + use snarkvm::prelude::Network; + use std::str::FromStr; + + let root = ::StateRoot::from_str(state_root)?; + let native: crate::types::AuthorizationNative = authorization.clone().into(); + ExecutionNative::from(native.transitions().values().cloned(), root, None).map(Self) + } + /// Reads in an Execution from a JSON string. #[staticmethod] fn from_json(json: &str) -> anyhow::Result { diff --git a/sdk/src/programs/fee.rs b/sdk/src/programs/fee.rs index 4651ab19..0fcc6f99 100644 --- a/sdk/src/programs/fee.rs +++ b/sdk/src/programs/fee.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Aleo SDK library. If not, see . -use crate::{types::FeeNative, Address, Transition}; +use crate::{types::FeeNative, Address, Authorization, Transition}; use pyo3::prelude::*; use snarkvm::prelude::{FromBytes, ToBytes}; @@ -50,6 +50,27 @@ impl Fee { self.0.transition().clone().into() } + /// Builds an UNPROVEN fee from a fee authorization — for devnodes only + /// (they skip proof verification); real networks reject it. + #[staticmethod] + fn from_authorization_unproven( + fee_authorization: &Authorization, + state_root: &str, + ) -> anyhow::Result { + use snarkvm::prelude::Network; + use std::str::FromStr; + + let root = ::StateRoot::from_str(state_root)?; + let native: crate::types::AuthorizationNative = fee_authorization.clone().into(); + let transition = native + .transitions() + .values() + .next() + .cloned() + .ok_or_else(|| anyhow::anyhow!("Fee authorization has no transitions"))?; + FeeNative::from(transition, root, None).map(Self) + } + /// Reads in a Fee from a JSON string. #[staticmethod] fn from_json(json: &str) -> anyhow::Result { diff --git a/sdk/src/programs/mod.rs b/sdk/src/programs/mod.rs index 12366254..89128aca 100644 --- a/sdk/src/programs/mod.rs +++ b/sdk/src/programs/mod.rs @@ -17,6 +17,9 @@ mod authorization; pub use authorization::Authorization; +mod deployment; +pub use deployment::Deployment; + mod dynamic_record; pub use dynamic_record::DynamicRecord; diff --git a/sdk/src/programs/process.rs b/sdk/src/programs/process.rs index 99fe4bde..aaff61cb 100644 --- a/sdk/src/programs/process.rs +++ b/sdk/src/programs/process.rs @@ -16,8 +16,8 @@ use crate::{ types::{CurrentAleo, ProcessNative}, - Authorization, Execution, Fee, Field, Identifier, PrivateKey, Program, ProgramID, ProvingKey, - RecordPlaintext, Response, Trace, Value, VerifyingKey, + Address, Authorization, Deployment, Execution, Fee, Field, Identifier, PrivateKey, Program, + ProgramID, ProvingKey, RecordPlaintext, Response, Trace, Value, VerifyingKey, }; use indexmap::IndexMap; @@ -25,7 +25,7 @@ use pyo3::prelude::*; use rand::rngs::StdRng; use snarkvm::algorithms::snark::varuna::VarunaVersion; use snarkvm::console::network::ConsensusVersion; -use snarkvm::synthesizer::process::{execution_cost, InclusionVersion}; +use snarkvm::synthesizer::process::{deployment_cost, execution_cost, InclusionVersion}; /// The Aleo process type. #[pyclass] @@ -202,4 +202,25 @@ impl Process { fn execution_cost(&self, execution: &Execution) -> anyhow::Result<(u64, (u64, u64))> { execution_cost(&self.0, &execution.clone().into(), ConsensusVersion::V17) } + + /// Synthesizes a deployment for the given program (V9+ semantics: the + /// program checksum and owner address are set on the deployment). + /// + /// The program's imports must already be present in this process. Key + /// synthesis is expensive — expect seconds to minutes for large programs. + fn deploy(&self, program: &Program, owner: &Address) -> anyhow::Result { + let mut deployment = self + .0 + .deploy::(program, &mut rand::make_rng::())?; + deployment.set_program_checksum_raw(Some(deployment.program().to_checksum())); + deployment.set_program_owner_raw(Some(**owner)); + Ok(deployment.into()) + } + + /// Returns the *minimum* cost in microcredits to publish the given deployment. + fn deployment_cost(&self, deployment: &Deployment) -> anyhow::Result { + let (minimum_cost, _) = + deployment_cost(&self.0, deployment.as_ref(), ConsensusVersion::V17)?; + Ok(minimum_cost) + } } diff --git a/sdk/src/programs/transaction.rs b/sdk/src/programs/transaction.rs index 11ffa656..581c54e9 100644 --- a/sdk/src/programs/transaction.rs +++ b/sdk/src/programs/transaction.rs @@ -15,9 +15,9 @@ // along with the Aleo SDK library. If not, see . use crate::{ - programs::{Execution, Fee, Program, Transition}, + programs::{Deployment, Execution, Fee, Program, Transition}, types::TransactionNative, - Field, RecordCiphertext, RecordPlaintext, ViewKey, + Field, PrivateKey, RecordCiphertext, RecordPlaintext, ViewKey, }; use pyo3::{ @@ -39,6 +39,22 @@ impl Transaction { TransactionNative::from_execution(execution.into(), fee.map(Into::into)).map(Self) } + /// Constructs a deployment transaction: the deployer signs program + /// ownership over the deployment ID, and the fee pays for publication. + #[staticmethod] + fn from_deployment( + private_key: &PrivateKey, + deployment: Deployment, + fee: Fee, + ) -> anyhow::Result { + use rand::rngs::StdRng; + use snarkvm::prelude::ProgramOwner; + + let deployment_id = deployment.as_ref().to_deployment_id()?; + let owner = ProgramOwner::new(private_key, deployment_id, &mut rand::make_rng::())?; + TransactionNative::from_deployment(owner, deployment.into(), fee.into()).map(Self) + } + /// Parses a Transaction from a JSON string. #[staticmethod] fn from_json(json: &str) -> anyhow::Result { diff --git a/sdk/src/types.rs b/sdk/src/types.rs index a0e952f1..1db3bfa2 100644 --- a/sdk/src/types.rs +++ b/sdk/src/types.rs @@ -27,12 +27,12 @@ use snarkvm::ledger::block::{Fee, Transaction}; use snarkvm::ledger::query::Query; use snarkvm::ledger::store::helpers::memory::BlockMemory; use snarkvm::prelude::{ - Address, Argument, Authorization, Boolean, Ciphertext, ComputeKey, Execution, Field, Future, - GraphKey, Group, Identifier, Literal, Locator, Plaintext, PrivateKey, Program, ProgramID, - ProvingKey, Record, Request, Response, Scalar, Signature, Transition, Value, ValueType, - VerifyingKey, ViewKey, I128, I16, I32, I64, I8, U128, U16, U32, U64, U8, + Address, Argument, Authorization, Boolean, Ciphertext, ComputeKey, Deployment, Execution, + Field, Future, GraphKey, Group, Identifier, Literal, Locator, Plaintext, PrivateKey, Program, + ProgramID, ProvingKey, Record, Request, Response, Scalar, Signature, Transition, Value, + ValueType, VerifyingKey, ViewKey, I128, I16, I32, I64, I8, U128, U16, U32, U64, U8, }; -use snarkvm::synthesizer::{Process, Trace}; +use snarkvm::synthesizer::{snark::Certificate, Process, Trace}; // Network selection (feature-gated; MainnetV0 by default). #[cfg(not(feature = "testnet"))] @@ -73,6 +73,8 @@ pub type U128Native = U128; // Program types pub type CurrentBlockMemory = BlockMemory; pub type AuthorizationNative = Authorization; +pub type CertificateNative = Certificate; +pub type DeploymentNative = Deployment; pub type ExecutionNative = Execution; pub type FeeNative = Fee; pub type IdentifierNative = Identifier; diff --git a/shield-swap-sdk/.gitignore b/shield-swap-sdk/.gitignore new file mode 100644 index 00000000..7a60b85e --- /dev/null +++ b/shield-swap-sdk/.gitignore @@ -0,0 +1,2 @@ +__pycache__/ +*.pyc diff --git a/shield-swap-sdk/README.md b/shield-swap-sdk/README.md new file mode 100644 index 00000000..d1f4a2d0 --- /dev/null +++ b/shield-swap-sdk/README.md @@ -0,0 +1,165 @@ +# shield-swap-sdk + +Typed Python client for the **shield_swap** AMM on Aleo. Sits on top of the +Aleo Python SDK's facade (`aleo.Aleo`): signer, record provider, proving +configuration, and network all come from the client you bind — this package +adds the DEX verbs, the typed results, and the off-chain DEX API, nothing +else. + +```python +from aleo import Aleo +from aleo_shield_swap import ShieldSwap + +aleo = Aleo(Aleo.HTTPProvider("https://api.provable.com")) +aleo.default_account = account +dex = ShieldSwap(aleo) + +pools = dex.api.get_pools() # requires a live DEX API +handle = dex.swap(pool_key=pools[0].key, + token_in_id=pools[0].token0, + amount_in=10**9).delegate() # broadcasts; spends funds +out = dex.claim_swap_output(handle).delegate() # broadcasts; spends funds +``` + +## Install + +```bash +pip install -e shield-swap-sdk # from the repo root +pip install -e "shield-swap-sdk[async]" # + AsyncShieldSwap (httpx) +pip install -e "shield-swap-sdk[mcp]" # + the MCP server +``` + +Requires `aleo-sdk>=0.2` (this repo's SDK; imports as `aleo`) and Python 3.10+. + +## How calls work + +Every read returns a value immediately. Every write returns a prepared +`DexCall` — nothing touches the network until you invoke a terminal verb: + +```python +call = dex.swap(pool_key=key, token_in_id=token, amount_in=10**9) + +call.simulate() # runs locally; no broadcast, no fee +call.transact(account) # proves locally, broadcasts, pays the fee +call.delegate(account) # proves via the delegated proving service +``` + +`transact` and `delegate` return the verb's *typed result* (a `SwapHandle`, +`MintResult`, `ClaimResult`, …) built from the transaction's root-transition +outputs — not a bare transaction id. Local proving downloads SNARK parameters +on first use and takes minutes for the larger entrypoints; `delegate` is the +practical path and requires DPS credentials on the provider +(`api_key=`, `network_client.consumer_id`). + +Chain reads and writes live directly on `ShieldSwap`; the off-chain DEX API +is namespaced under `.api`, so a call site always shows whether a value came +from the chain or the service. + +## The verb surface + +**Chain reads** (node REST API): + +| Verb | Returns | +|---|---| +| `get_pool(pool_key)` | The pool struct from the `pools` mapping. | +| `get_slot(pool_key)` | `SlotView` — current tick, sqrt price, liquidity, spacing. | +| `get_swap_output(swap_id)` | The finalized swap outcome; raises `SwapOutputNotFinalizedError` until the finalize lands (and again after the claim consumes it). | +| `is_pool_initialized(pool_key)` | Whether the pool exists on chain. | +| `get_private_balances(programs)` | Summed unspent record amounts per token program (needs a registered record provider). | +| `get_balances()` | Public + private balances in one shape. | +| `derive_pool_key(token0, token1, fee)` / `derive_tick_key(pool_key, tick)` | Mapping keys derived locally — no network. | + +**Writes** (each returns a `DexCall`): + +| Verb | What it does | +|---|---| +| `swap(...)` | Phase one of the two-transaction private swap: locks the input record against a blinded identity. Returns a `SwapHandle` — persist it if the process might die before the claim. | +| `claim_swap_output(handle)` | Phase two: claims the finalized output as a private record. | +| `create_pool(...)` | Initializes a pool for a token pair + fee tier. | +| `mint(...)` | Opens a position in a tick range; returns a `MintResult` with the position's token id. | +| `increase_liquidity(...)` / `decrease_liquidity(...)` | Resizes a position (spends the position NFT record and returns a fresh one). | +| `collect(...)` | Pays out `tokens_owed` as private records. | +| `burn(...)` | Closes an emptied position and removes it from the `positions` mapping. | + +Quote before you swap: pass `expected_out` from `dex.api.get_route(...)` — +without it a spot estimate is used, which ignores fees and price impact. +Amounts are `u128` base units of the token; fees are microcredits. + +**DEX API** (`dex.api`, standalone as `ApiClient`): `get_pools`, +`get_tokens`, `get_route`, `get_swap`, `get_ohlcv`, `get_public_balances`. +Route quoting, OHLCV, and balances are auth-gated — call +`api.authenticate(address, sign)` once (challenge/verify by signature, no +funds required); some deployments additionally gate them behind an invite +code. + +## Privacy + +The swap flow never puts your address on chain next to the output. `swap` +derives a single-use **blinded identity** from the signer's view key +(`derive_blinding_factor` / `derive_blinded_address` are exported for +verification against the TS SDK's vectors); the claim proves knowledge of the +blinding factor instead of revealing the owner. + +Two conveniences trade secret material for service: + +- `delegate` sends the transaction *authorization* to the proving service — + it can see the transaction's contents (not your private key). Prove + locally with `transact` if that is unacceptable. +- The hosted record scanner behind `get_private_balances` / + `aleo.records.register` shares the account's **view key** with the + scanning service, which can then see everything the account owns. + Self-host the scanner if that is unacceptable. + +## Async + +`AsyncShieldSwap` / `AsyncApiClient` mirror the sync surface verb-for-verb on +`aleo.AsyncAleo` (install the `[async]` extra): + +```python +from aleo_shield_swap import AsyncShieldSwap + +dex = AsyncShieldSwap(async_aleo) +handle = await (await dex.swap(pool_key=key, token_in_id=token, + amount_in=10**9)).delegate() +``` + +## Agent tools and MCP + +`shield_swap_tools()` returns JSON-schema tool definitions for the whole verb +surface; `dispatch_tool(dex, name, args)` executes one. For MCP hosts, the +`[mcp]` extra ships a stdio server over the same definitions: + +```bash +ALEO_PRIVATE_KEY=APrivateKey1... python -m aleo_shield_swap.mcp +``` + +Omit `ALEO_PRIVATE_KEY` for a read-only server. See the module docstring for +the full environment (`ALEO_ENDPOINT`, `ALEO_NETWORK`, DPS credentials). + +## Generated bindings + +The contract surface is pinned, not hand-written: `codegen/` holds the +deployed program source, its ABI, and the DEX API's OpenAPI document. +`_generated.py` (program structs + entrypoints via `aleo.codegen`) and +`_api_models.py` (API response models) are built from those pins. When the +deployed contract or API drifts, rerun `codegen/regen-abi.sh` / +`codegen/regen-openapi.sh` and reconcile. + +## Tests + +```bash +python -m pytest # hermetic tier — no network +python -m pytest -m live # read-only against the REAL testnet + DEX API +python -m pytest -m "live and slow" # spends real testnet funds (DPS proving) +ALEO_DEVNODE_UNPROVEN=1 \ +python -m pytest -m devnode # full AMM lifecycle on a local aleo-devnode +``` + +The devnode tier deploys the vendored `shield_swap_v3.aleo` stack and drives +pool creation, liquidity, swaps, and burn end-to-end, hermetically. It needs +the `aleo-devnode` binary (`ALEO_DEVNODE_BIN` or on `PATH`) and skips +otherwise. Deployments are proofless (dummy verifying keys — the devnode +skips certificate verification); `ALEO_DEVNODE_UNPROVEN=1` extends that to +executions and is the fast path (~5 minutes). Without it, executions are +fully proven locally: expect SNARK parameter downloads and key synthesis on +first use. diff --git a/shield-swap-sdk/codegen/amm_api.openapi.json b/shield-swap-sdk/codegen/amm_api.openapi.json new file mode 100644 index 00000000..f65c1ae7 --- /dev/null +++ b/shield-swap-sdk/codegen/amm_api.openapi.json @@ -0,0 +1,5928 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "Aleo AMM API", + "description": "REST API for the Aleo concentrated-liquidity AMM. Serves indexed pool / position / swap data, routing, swap quotes, swap-settlement status, and on-chain input schemas for building transactions against the deployment-configured shield_swap program and `token_registry.aleo`.\n\n## Numeric wire format\n\nExact financial values are JSON strings, not JSON numbers. Unsigned decimal inputs use ASCII digits and an optional `.` fraction, for example `\"1234.50\"`; base-unit integers use ASCII digits only. Grouping separators, localized decimal commas, signs, exponent notation, whitespace, Unicode digits, and redundant leading zeros are not accepted for those inputs. Signed response metrics may include a leading `-`. Clients should localize only for display and convert user input back to this canonical form before sending it.\n\n## Authentication\n\nExcept for `/health`, `/metrics`, `/auth/*`, `/compliance*`, `GET /tokens*`, and the pool metadata reads (`GET /pools`, `GET /pools/stats`, `GET /pools/{key}`), every endpoint requires `Authorization: Bearer ` from an invited wallet. The credential is either a session JWT from `/auth/verify` (24h) or a long-lived API token (`ss_\u2026`) minted at `POST /api-tokens`. API tokens cover the data and trading surface; token management, code redemption, and admin endpoints accept JWTs only.\n\n## Real-time WebSocket feed\n\nLive updates are pushed over a WebSocket served by the **indexer** service at `GET /ws` (a WebSocket upgrade \u2014 a separate service from this REST API, not one of the paths below). Clients manage subscriptions with JSON frames:\n\n```json\n{\"action\": \"authenticate\", \"token\": \"\"}\n{\"action\": \"subscribe\", \"room\": \"trades:\"}\n{\"action\": \"unsubscribe\", \"room\": \"trades:\"}\n```\n\nThe authentication frame must be first. Balance rooms are restricted to the JWT subject.\n\nRooms:\n- `pool_launches` \u2014 newly created pools\n- `pool_stats:` \u2014 price & liquidity updates\n- `ohlcv:` \u2014 candle updates\n- `trades:` \u2014 swaps / mints / burns\n- `balances:
` \u2014 balance-change hints for an address\n\nEach pushed message is `{\"type\": , \"data\": { \u2026 }}`, where `type` is one of `PoolLaunch`, `PoolStats`, `Ohlcv`, `Trade`, `BalanceChange`. Financial fields use the same exact string format.", + "contact": { + "name": "Aleo AMM" + }, + "license": { + "name": "" + }, + "version": "0.1.0" + }, + "servers": [ + { + "url": "/", + "description": "Current host" + } + ], + "paths": { + "/access/codes": { + "get": { + "tags": [ + "access" + ], + "operationId": "access_list_codes", + "parameters": [ + { + "name": "limit", + "in": "query", + "description": "Page size (1-2000)", + "required": false, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "offset", + "in": "query", + "description": "Page offset", + "required": false, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "responses": { + "200": { + "description": "Access-code inventory", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AccessListResponseDoc" + } + } + } + }, + "400": { + "description": "Invalid query parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "403": { + "description": "Administrator authorization required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/access/generate": { + "post": { + "tags": [ + "access" + ], + "operationId": "access_generate", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AccessGenerateRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Generated access codes", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AccessGenerateResponseDoc" + } + } + } + }, + "400": { + "description": "Malformed JSON request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "403": { + "description": "Administrator authorization required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "413": { + "description": "Request body too large", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "415": { + "description": "Content-Type must be application/json", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "422": { + "description": "Request body does not match schema", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/access/redeem": { + "post": { + "tags": [ + "access" + ], + "operationId": "access_redeem", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AccessRedeemRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Access code redeemed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AccessRedeemResponseDoc" + } + } + } + }, + "400": { + "description": "Invalid or already-used code", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "413": { + "description": "Request body too large", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "415": { + "description": "Content-Type must be application/json", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "422": { + "description": "Request body does not match schema", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/access/status": { + "get": { + "tags": [ + "access" + ], + "operationId": "access_status", + "responses": { + "200": { + "description": "Wallet access status", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AccessStatusResponseDoc" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/airdrop": { + "post": { + "tags": [ + "airdrop" + ], + "summary": "POST /airdrop", + "description": "Mints 1000 (\u00d710^decimals) of every token registered in the DB to the given\naddress by calling `::mint_public` on each. Because each\ntoken's admin is the treasury/deployer key, this never requires the treasury\nto hold a balance \u2014 it mints fresh supply.\n\nProving each token takes ~15-30s and the list can be long, so this returns\nimmediately with `status: \"running\"` + a `job_id`. The mints run in a\ndetached worker (capped concurrency, per-token timeout); poll\n`GET /airdrop/{job_id}` until `status == \"complete\"` to read per-token\nresults.\n\nRequired env: `DEPLOYER_PRIVATE_KEY` (the treasury/admin of every token;\n`AIRDROP_PRIVATE_KEY` honored as a fallback), `RPC_URLS` (first entry used).", + "operationId": "airdrop", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AirdropRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Airdrop job started", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AirdropStartResponseDoc" + } + } + } + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "413": { + "description": "Request body too large", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "415": { + "description": "Content-Type must be application/json", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "422": { + "description": "Request body does not match schema", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Misconfigured server (missing env vars)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/airdrop/{job_id}": { + "get": { + "tags": [ + "airdrop" + ], + "summary": "GET /airdrop/{job_id}", + "description": "Returns the current state of a background airdrop job: `status`\n(`\"running\"` | `\"complete\"`), the expected `total`, and the per-token\n`results` collected so far.", + "operationId": "airdrop_status", + "parameters": [ + { + "name": "job_id", + "in": "path", + "description": "Job id returned by POST /airdrop", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Current airdrop job state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AirdropJobResponseDoc" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "404": { + "description": "Unknown job id", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Internal job-store error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/api-tokens": { + "get": { + "tags": [ + "api-tokens" + ], + "operationId": "api_tokens_list", + "responses": { + "200": { + "description": "API tokens for the authenticated wallet (no secrets)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiTokenListResponseDoc" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "403": { + "description": "Invite access required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + }, + "post": { + "tags": [ + "api-tokens" + ], + "operationId": "api_tokens_create", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiTokenCreateRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "API token created; the token value is shown only once", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiTokenCreatedResponseDoc" + } + } + } + }, + "400": { + "description": "Invalid name, expiry, or active-token limit reached", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "403": { + "description": "Invite access required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "413": { + "description": "Request body too large", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "415": { + "description": "Content-Type must be application/json", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "422": { + "description": "Request body does not match schema", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "429": { + "description": "Too many attempts", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/api-tokens/{id}": { + "delete": { + "tags": [ + "api-tokens" + ], + "operationId": "api_tokens_revoke", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "Token id", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "API token revoked", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiTokenRevokeResponseDoc" + } + } + } + }, + "400": { + "description": "Malformed token id", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "403": { + "description": "Invite access required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "404": { + "description": "Token not found or already revoked", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/auth/challenge": { + "post": { + "tags": [ + "auth" + ], + "operationId": "challenge", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ChallengeRequestDoc" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Challenge nonce + message to sign", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ChallengeResponseDoc" + } + } + } + }, + "400": { + "description": "Malformed JSON or invalid address", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "413": { + "description": "Request body too large", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "415": { + "description": "JSON content type required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "422": { + "description": "Request body schema mismatch", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "429": { + "description": "Rate limit exceeded", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + } + } + }, + "/auth/verify": { + "post": { + "tags": [ + "auth" + ], + "operationId": "verify", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VerifyRequestDoc" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "JWT bearer token", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthTokenResponseDoc" + } + } + } + }, + "400": { + "description": "Malformed JSON", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "401": { + "description": "Invalid / expired signature", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "413": { + "description": "Request body too large", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "415": { + "description": "JSON content type required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "422": { + "description": "Request body schema mismatch", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "429": { + "description": "Rate limit exceeded", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + } + } + }, + "/balances": { + "get": { + "tags": [ + "balances" + ], + "operationId": "list_balances", + "responses": { + "200": { + "description": "Per-token on-chain authorized balances", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BalanceListResponseDoc" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Internal database or RPC error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/compliance": { + "get": { + "tags": [ + "compliance" + ], + "operationId": "get_config", + "responses": { + "200": { + "description": "Global pause / pool-creation gating state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GlobalConfigResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + } + } + }, + "/compliance/pairs/{token0}/{token1}": { + "get": { + "tags": [ + "compliance" + ], + "operationId": "get_pair_status", + "parameters": [ + { + "name": "token0", + "in": "path", + "description": "First token id (Aleo field)", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token1", + "in": "path", + "description": "Second token id (Aleo field)", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Pause state for a token pair (order-independent)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PairComplianceResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + } + } + }, + "/compliance/tokens/{token_id}": { + "get": { + "tags": [ + "compliance" + ], + "operationId": "get_token_status", + "parameters": [ + { + "name": "token_id", + "in": "path", + "description": "On-chain token id (Aleo field)", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Allowlist / pause state for a single token", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenComplianceResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + } + } + }, + "/debug/pool": { + "get": { + "tags": [ + "debug" + ], + "operationId": "pool_debug", + "parameters": [ + { + "name": "pool_key", + "in": "query", + "description": "Pool key", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ticks", + "in": "query", + "description": "Comma-separated list of tick values to verify", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Raw on-chain pool slot + optional tick statuses", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PoolDebugResponseDoc" + } + } + } + }, + "400": { + "description": "Invalid query parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Internal RPC error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/fee-tiers": { + "get": { + "tags": [ + "protocol" + ], + "operationId": "list_fee_tiers", + "responses": { + "200": { + "description": "Registered fee tiers", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FeeTierListResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/pools": { + "get": { + "tags": [ + "pools" + ], + "operationId": "list_pools", + "parameters": [ + { + "name": "limit", + "in": "query", + "description": "Page size (1-100)", + "required": false, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "offset", + "in": "query", + "description": "Page offset", + "required": false, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "responses": { + "200": { + "description": "Paginated pools with token metadata", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PoolListResponseDoc" + } + } + } + }, + "400": { + "description": "Invalid query parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + } + } + }, + "/pools/stats": { + "get": { + "tags": [ + "pools" + ], + "summary": "`GET /pools/stats?keys=key1,key2,\u2026`", + "description": "Batched rolling-24h stats for many pools in one request. Used by the\npools-table page to populate per-row volume / fees / APR without doing\n`N + 1` round-trips. Missing keys are silently dropped from the response\n(they just won't appear in the returned map); the caller treats absence\nas \"no stats yet\" rather than an error.\n\nCap: hard limit of 100 keys per request to avoid run-away DB load.", + "operationId": "get_pool_24h_stats_batch", + "parameters": [ + { + "name": "keys", + "in": "query", + "description": "Comma-separated pool keys (max 100)", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Map of pool key \u2192 24h stats; failed or unknown keys may be omitted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PoolStats24hBatchResponseDoc" + } + } + } + }, + "400": { + "description": "Empty / too-large keys list", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + } + } + }, + "/pools/{key}": { + "get": { + "tags": [ + "pools" + ], + "operationId": "get_pool", + "parameters": [ + { + "name": "key", + "in": "path", + "description": "On-chain pool field key", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Pool state + stats + token metadata", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PoolWithStatsResponseDoc" + } + } + } + }, + "404": { + "description": "Pool not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + } + } + }, + "/pools/{key}/initialized-ticks": { + "get": { + "tags": [ + "pools" + ], + "summary": "Returns the full sorted list of *initialized* ticks for the given pool \u2014 every\n`tick_lower` and `tick_upper` across all non-burned positions, deduplicated.", + "description": "Used by the frontend mint flow to compute the correct\n`tick_lower_hint` / `tick_upper_hint` for the AMM's hint-walk asserts.", + "operationId": "get_pool_initialized_ticks", + "parameters": [ + { + "name": "key", + "in": "path", + "description": "Pool key", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Sorted initialized ticks", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InitializedTicksResponseDoc" + } + } + } + }, + "404": { + "description": "Pool not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/pools/{key}/liquidity-distribution": { + "get": { + "tags": [ + "pools" + ], + "operationId": "get_pool_liquidity_distribution", + "parameters": [ + { + "name": "key", + "in": "path", + "description": "Pool key", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Initialized tick liquidity deltas", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LiquidityDistributionResponseDoc" + } + } + } + }, + "404": { + "description": "Pool not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/pools/{key}/ohlcv": { + "get": { + "tags": [ + "pools" + ], + "operationId": "get_pool_ohlcv", + "parameters": [ + { + "name": "key", + "in": "path", + "description": "Pool key", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "granularity", + "in": "query", + "description": "Candle bucket", + "required": true, + "schema": { + "$ref": "#/components/schemas/GranularityDoc" + } + }, + { + "name": "from", + "in": "query", + "description": "Inclusive unix-second start", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "to", + "in": "query", + "description": "Exclusive unix-second end", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "responses": { + "200": { + "description": "OHLCV candles for the range", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OhlcvResponseDoc" + } + } + } + }, + "400": { + "description": "Invalid granularity", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/pools/{key}/stats": { + "get": { + "tags": [ + "pools" + ], + "operationId": "get_pool_24h_stats", + "parameters": [ + { + "name": "key", + "in": "path", + "description": "Pool key", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Rolling 24h price/volume summary", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PoolStats24hResponseDoc" + } + } + } + }, + "404": { + "description": "Pool not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/pools/{key}/trades": { + "get": { + "tags": [ + "pools" + ], + "operationId": "get_pool_trades", + "parameters": [ + { + "name": "key", + "in": "path", + "description": "Pool key", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "limit", + "in": "query", + "description": "Page size (1-100)", + "required": false, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "offset", + "in": "query", + "description": "Page offset", + "required": false, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "trade_type", + "in": "query", + "description": "Indexed pool trade type filter", + "required": false, + "schema": { + "$ref": "#/components/schemas/PoolTradeFilterDoc" + } + } + ], + "responses": { + "200": { + "description": "Paginated trade history", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PoolTradesResponseDoc" + } + } + } + }, + "400": { + "description": "Invalid query parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "404": { + "description": "Pool not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/positions": { + "get": { + "tags": [ + "positions" + ], + "operationId": "list_positions", + "parameters": [ + { + "name": "limit", + "in": "query", + "description": "Page size (1-100)", + "required": false, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "offset", + "in": "query", + "description": "Page offset", + "required": false, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "responses": { + "200": { + "description": "Paginated LP positions", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PositionListResponseDoc" + } + } + } + }, + "400": { + "description": "Invalid query parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/positions/{token_id}": { + "get": { + "tags": [ + "positions" + ], + "operationId": "get_position", + "parameters": [ + { + "name": "token_id", + "in": "path", + "description": "On-chain position NFT token_id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Position details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PositionResponseDoc" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "404": { + "description": "Position not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/referral/admin": { + "get": { + "tags": [ + "referral" + ], + "operationId": "admin_check", + "responses": { + "200": { + "description": "Wallet administrator status", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReferralAdminResponseDoc" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "403": { + "description": "Invite access required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/referral/codes": { + "get": { + "tags": [ + "referral" + ], + "operationId": "referral_list_codes", + "parameters": [ + { + "name": "limit", + "in": "query", + "description": "Page size (1-2000)", + "required": false, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "offset", + "in": "query", + "description": "Page offset", + "required": false, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "responses": { + "200": { + "description": "Referral-code inventory", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReferralListResponseDoc" + } + } + } + }, + "400": { + "description": "Invalid query parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "403": { + "description": "Administrator authorization required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/referral/generate": { + "post": { + "tags": [ + "referral" + ], + "operationId": "referral_generate", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReferralGenerateRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Generated referral codes", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReferralGenerateResponseDoc" + } + } + } + }, + "400": { + "description": "Malformed JSON request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "403": { + "description": "Administrator authorization required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "413": { + "description": "Request body too large", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "415": { + "description": "Content-Type must be application/json", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "422": { + "description": "Request body does not match schema", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/referral/my-codes": { + "get": { + "tags": [ + "referral" + ], + "operationId": "my_codes", + "responses": { + "200": { + "description": "Codes issued to the wallet", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReferralMyCodesResponseDoc" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "403": { + "description": "Invite access required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/referral/redeem": { + "post": { + "tags": [ + "referral" + ], + "operationId": "referral_redeem", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReferralRedeemRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Referral code redeemed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReferralRedeemResponseDoc" + } + } + } + }, + "400": { + "description": "Invalid, used, or capacity-limited code", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "413": { + "description": "Request body too large", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "415": { + "description": "Content-Type must be application/json", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "422": { + "description": "Request body does not match schema", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "429": { + "description": "Rate limit exceeded", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/referral/settings": { + "get": { + "tags": [ + "referral" + ], + "operationId": "get_settings", + "responses": { + "200": { + "description": "Referral settings", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReferralSettingsResponseDoc" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "403": { + "description": "Administrator authorization required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + }, + "put": { + "tags": [ + "referral" + ], + "operationId": "update_settings", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReferralUpdateSettingsRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Updated referral settings", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReferralSettingsResponseDoc" + } + } + } + }, + "400": { + "description": "Malformed JSON request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "403": { + "description": "Administrator authorization required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "413": { + "description": "Request body too large", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "415": { + "description": "Content-Type must be application/json", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "422": { + "description": "Request body does not match schema", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/referral/status": { + "get": { + "tags": [ + "referral" + ], + "operationId": "referral_status", + "responses": { + "200": { + "description": "Wallet referral status", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReferralStatusResponseDoc" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/route": { + "get": { + "tags": [ + "route" + ], + "operationId": "find_route", + "parameters": [ + { + "name": "token_in", + "in": "query", + "description": "Input token ID", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token_out", + "in": "query", + "description": "Output token ID", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "amount_in", + "in": "query", + "description": "Optional positive canonical decimal amount for output estimation", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Best swap route (max 3 hops)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RouteResponseDoc" + } + } + } + }, + "400": { + "description": "Invalid amount_in", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "404": { + "description": "No route or executable quote for the given tokens", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "503": { + "description": "Routing dependencies are temporarily unavailable or the quote candidate set exceeds the safe limit", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/schema/trading": { + "get": { + "tags": [ + "schema" + ], + "summary": "GET /schema/trading", + "description": "Returns the full list of on-chain trading, liquidity, and token operations\nwith their input signatures. Clients can use this to build transaction\npayloads without hardcoding the Leo function signatures.", + "operationId": "list_trading_schemas", + "responses": { + "200": { + "description": "List of all on-chain operation schemas", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TradingSchemaListResponse" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/schema/trading/{id}": { + "get": { + "tags": [ + "schema" + ], + "summary": "GET /schema/trading/{id}", + "description": "Returns the input schema for a single operation (e.g. `swap`, `mint`, `collect`).", + "operationId": "get_trading_schema", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "Operation ID (swap, mint, create_pool, burn, collect, decrease_liquidity, swap_multi_hop, claim_swap_output, claim_multi_hop_output, register_token, mint_public, mint_private, transfer_public_to_private, add_fee_tier, add_tick_spacing, set_pool_enabled)", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Schema for the requested operation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TradingSchemaResponse" + } + } + } + }, + "404": { + "description": "Unknown operation ID", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/swaps": { + "get": { + "tags": [ + "swaps" + ], + "operationId": "list_swaps", + "parameters": [ + { + "name": "limit", + "in": "query", + "description": "Page size (1-100)", + "required": false, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "offset", + "in": "query", + "description": "Page offset", + "required": false, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "pool", + "in": "query", + "description": "Filter by any pool in the route", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Paginated swap history", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SwapListResponseDoc" + } + } + } + }, + "400": { + "description": "Invalid query parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "404": { + "description": "Pool filter not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/swaps/{swap_id}": { + "get": { + "tags": [ + "swaps" + ], + "operationId": "get_swap", + "parameters": [ + { + "name": "swap_id", + "in": "path", + "description": "On-chain swap ID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Swap details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SwapResponseDoc" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "404": { + "description": "Swap not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/tick-spacings": { + "get": { + "tags": [ + "protocol" + ], + "operationId": "list_tick_spacings", + "responses": { + "200": { + "description": "Registered tick spacings", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TickSpacingListResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/tokens": { + "get": { + "tags": [ + "tokens" + ], + "operationId": "list_tokens", + "responses": { + "200": { + "description": "All registered tokens", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenListResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + } + }, + "post": { + "tags": [ + "tokens" + ], + "operationId": "create_token", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateTokenRequestDoc" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Token stored", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResponseDoc" + } + } + } + }, + "400": { + "description": "Invalid token decimals or request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "401": { + "description": "Administrator authorization required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "403": { + "description": "Administrator authorization required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "413": { + "description": "Request body too large", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "415": { + "description": "Content-Type must be application/json", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "422": { + "description": "Request body does not match schema", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/tokens/deploy": { + "post": { + "tags": [ + "tokens" + ], + "summary": "POST /tokens/deploy", + "description": "Deploys a fresh self-contained ARC-20 token (the treasury/deployer key is its\nbaked-in admin) and mints the initial supply to the creator (`recipient`),\nthen registers it (with `wrapper_program`) so it is swap- and airdrop-ready.\n\nDeploy + mint are two on-chain txs that take minutes, so this returns\nimmediately with `status: \"deploying\"` and finishes in the background. Poll\n`GET /tokens` for a row whose `wrapper_program` equals the returned\n`program_id` to know it completed.\n\nRequired env: `DEPLOYER_PRIVATE_KEY` (treasury/admin; `AIRDROP_PRIVATE_KEY`\nhonored as fallback), `RPC_URLS`. `leo` must be on the server PATH.", + "operationId": "deploy_token", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeployTokenRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Deploy started", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeployTokenResponseDoc" + } + } + } + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "403": { + "description": "Administrator authorization required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "413": { + "description": "Request body too large", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "415": { + "description": "Content-Type must be application/json", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "422": { + "description": "Request body does not match schema", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Misconfigured server", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/tokens/mint": { + "post": { + "tags": [ + "tokens" + ], + "summary": "POST /tokens/mint", + "description": "Admin-mints `amount` (base units) of an existing wrapper to `recipient`,\nsigned by the treasury/deployer key (the token's admin). Synchronous \u2014 a\nsingle mint tx. Reuses scripts/airdrop-helper.mjs (which calls mint_public).", + "operationId": "mint_token", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MintTokenRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Mint broadcast", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MintTokenResponseDoc" + } + } + } + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "403": { + "description": "Administrator authorization required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "413": { + "description": "Request body too large", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "415": { + "description": "Content-Type must be application/json", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "422": { + "description": "Request body does not match schema", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Misconfigured server", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/tokens/{address}": { + "get": { + "tags": [ + "tokens" + ], + "operationId": "get_token", + "parameters": [ + { + "name": "address", + "in": "path", + "description": "Token address (Aleo field ID)", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Token details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResponseDoc" + } + } + } + }, + "404": { + "description": "Token not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + } + } + }, + "/unclaimed": { + "get": { + "tags": [ + "unclaimed" + ], + "summary": "GET /unclaimed", + "description": "Returns everything the user can still claim:\n - Swaps with `claimed_at IS NULL` (user can drive `claim_swap_output`).\n - Positions with `tokens_owed0 > 0` or `tokens_owed1 > 0`\n (post-`decrease_liquidity` accumulations; user calls `collect`).\n\nThe indexer is the source of truth: it stamps `claimed_at` for every claim\nvariant, and the `swaps` row already carries every field the claim tx needs.\nSo we do zero on-chain mapping reads here \u2014 that earlier per-swap RPC loop\nwas both slow (N sequential reads) and wrong (reads went through a balancer\nhitting nodes at different heights, so freshly-claimed swaps flapped back).", + "operationId": "get_unclaimed", + "responses": { + "200": { + "description": "Pending swap and liquidity claims", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnclaimedResponseDoc" + } + } + } + }, + "401": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + }, + "500": { + "description": "Internal error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDoc" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + } + }, + "components": { + "schemas": { + "AccessCodeRow": { + "type": "object", + "required": [ + "code", + "created_at" + ], + "properties": { + "code": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "redeemed_at": { + "type": [ + "string", + "null" + ] + }, + "redeemed_by": { + "type": [ + "string", + "null" + ] + } + } + }, + "AccessGenerateRequest": { + "type": "object", + "required": [ + "count" + ], + "properties": { + "count": { + "type": "integer", + "format": "int32", + "minimum": 0 + } + } + }, + "AccessGenerateResponse": { + "type": "object", + "required": [ + "codes" + ], + "properties": { + "codes": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "AccessGenerateResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/AccessGenerateResponse" + } + } + }, + "AccessListResponse": { + "type": "object", + "required": [ + "total", + "redeemed", + "available", + "codes" + ], + "properties": { + "available": { + "type": "integer", + "format": "int64" + }, + "codes": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AccessCodeRow" + } + }, + "redeemed": { + "type": "integer", + "format": "int64" + }, + "total": { + "type": "integer", + "format": "int64" + } + } + }, + "AccessListResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/AccessListResponse" + } + } + }, + "AccessRedeemRequest": { + "type": "object", + "required": [ + "code" + ], + "properties": { + "code": { + "type": "string" + } + } + }, + "AccessRedeemResponse": { + "type": "object", + "required": [ + "code", + "status", + "token" + ], + "properties": { + "code": { + "type": "string" + }, + "status": { + "type": "string" + }, + "token": { + "type": "string" + } + } + }, + "AccessRedeemResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/AccessRedeemResponse" + } + } + }, + "AccessStatusResponse": { + "type": "object", + "required": [ + "has_access" + ], + "properties": { + "has_access": { + "type": "boolean" + } + } + }, + "AccessStatusResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/AccessStatusResponse" + } + } + }, + "AirdropJob": { + "type": "object", + "description": "Status of a background airdrop job. `status` is `\"running\"` until every token\nhas resolved, then `\"complete\"`. `results` grows as each per-token mint lands,\nso a poller sees live progress (`results.len()` of `total`).", + "required": [ + "status", + "total", + "results" + ], + "properties": { + "results": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AirdropResult" + } + }, + "status": { + "type": "string" + }, + "total": { + "type": "integer", + "minimum": 0 + } + } + }, + "AirdropJobResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/AirdropJob" + } + } + }, + "AirdropRequest": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string", + "description": "Aleo address (`aleo1...`) to receive 1000 of each registered token." + } + } + }, + "AirdropResult": { + "type": "object", + "required": [ + "token_address", + "symbol", + "wrapper_program", + "amount", + "status" + ], + "properties": { + "amount": { + "type": "string", + "description": "Base-unit amount (`1000 * 10^decimals`)." + }, + "error": { + "type": [ + "string", + "null" + ] + }, + "status": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "token_address": { + "type": "string" + }, + "tx_id": { + "type": [ + "string", + "null" + ] + }, + "wrapper_program": { + "type": "string" + } + } + }, + "AirdropStartResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/AirdropStartResult" + } + } + }, + "AirdropStartResult": { + "type": "object", + "description": "Returned by `POST /airdrop` \u2014 the airdrop now runs in the background, so the\ncaller gets a `job_id` to poll `GET /airdrop/{job_id}` with.", + "required": [ + "job_id", + "status" + ], + "properties": { + "job_id": { + "type": "string" + }, + "status": { + "type": "string" + } + } + }, + "ApiTokenCreateRequest": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "expires_in_days": { + "type": [ + "integer", + "null" + ], + "format": "int64" + }, + "name": { + "type": "string" + } + } + }, + "ApiTokenCreatedResponse": { + "type": "object", + "required": [ + "id", + "name", + "token", + "token_prefix", + "created_at" + ], + "properties": { + "created_at": { + "type": "string" + }, + "expires_at": { + "type": [ + "string", + "null" + ] + }, + "id": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "token": { + "type": "string", + "description": "Full secret, returned only once at creation." + }, + "token_prefix": { + "type": "string" + } + } + }, + "ApiTokenCreatedResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/ApiTokenCreatedResponse" + } + } + }, + "ApiTokenListResponse": { + "type": "object", + "required": [ + "tokens" + ], + "properties": { + "tokens": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ApiTokenRow" + } + } + } + }, + "ApiTokenListResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/ApiTokenListResponse" + } + } + }, + "ApiTokenRevokeResponse": { + "type": "object", + "required": [ + "id", + "revoked" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "revoked": { + "type": "boolean" + } + } + }, + "ApiTokenRevokeResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/ApiTokenRevokeResponse" + } + } + }, + "ApiTokenRow": { + "type": "object", + "required": [ + "id", + "name", + "token_prefix", + "created_at" + ], + "properties": { + "created_at": { + "type": "string" + }, + "expires_at": { + "type": [ + "string", + "null" + ] + }, + "id": { + "type": "string", + "format": "uuid" + }, + "last_used_at": { + "type": [ + "string", + "null" + ] + }, + "name": { + "type": "string" + }, + "revoked_at": { + "type": [ + "string", + "null" + ] + }, + "token_prefix": { + "type": "string" + } + } + }, + "AuthTokenPayload": { + "type": "object", + "required": [ + "token" + ], + "properties": { + "token": { + "type": "string" + } + } + }, + "AuthTokenResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/AuthTokenPayload" + } + } + }, + "BalanceListResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TokenBalanceDoc" + } + } + } + }, + "ChallengePayload": { + "type": "object", + "required": [ + "nonce", + "message" + ], + "properties": { + "message": { + "type": "string" + }, + "nonce": { + "type": "string" + } + } + }, + "ChallengeRequestDoc": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + } + }, + "ChallengeResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/ChallengePayload" + } + } + }, + "CreateTokenRequestDoc": { + "type": "object", + "required": [ + "address", + "name", + "symbol", + "decimals" + ], + "properties": { + "address": { + "type": "string", + "description": "Aleo field ID (e.g. `1234567890field`)." + }, + "decimals": { + "type": "integer", + "format": "int32", + "maximum": 18, + "minimum": 0 + }, + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "wrapper_program": { + "type": [ + "string", + "null" + ], + "description": "Deployed ARC-20 wrapper program ID (e.g. `mtk_a1b2c3.aleo`). Optional." + } + } + }, + "DeployTokenRequest": { + "type": "object", + "required": [ + "name", + "symbol", + "decimals", + "recipient" + ], + "properties": { + "decimals": { + "type": "integer", + "format": "int32", + "maximum": 18, + "minimum": 0 + }, + "name": { + "type": "string" + }, + "recipient": { + "type": "string", + "description": "Aleo address (`aleo1...`) of the creator \u2014 receives the initial supply." + }, + "supply": { + "type": [ + "string", + "null" + ], + "description": "Initial supply in whole units (default 1_000_000), minted to `recipient`." + }, + "symbol": { + "type": "string" + } + } + }, + "DeployTokenResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/DeployTokenResult" + } + } + }, + "DeployTokenResult": { + "type": "object", + "required": [ + "program_id", + "status", + "recipient" + ], + "properties": { + "program_id": { + "type": "string", + "description": "`_.aleo` \u2014 the deployed wrapper program id." + }, + "recipient": { + "type": "string" + }, + "status": { + "type": "string", + "description": "Always `\"deploying\"`. Deploy + initial mint run in the background\n(minutes); poll `GET /tokens` until a token with this `wrapper_program`\nappears to know it finished and was registered." + } + } + }, + "ErrorResponseDoc": { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + }, + "ref": { + "type": [ + "string", + "null" + ] + } + } + }, + "FeeTierDoc": { + "type": "object", + "required": [ + "id", + "fee_tier", + "created_at", + "transaction" + ], + "properties": { + "created_at": { + "type": "string" + }, + "fee_tier": { + "type": "integer", + "format": "int32", + "description": "Raw hundredths of a basis point; the fee fraction is this value divided by 1,000,000.", + "maximum": 65535, + "minimum": 0 + }, + "id": { + "type": "string" + }, + "transaction": { + "type": "string" + } + } + }, + "FeeTierListResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FeeTierDoc" + } + } + } + }, + "FunctionSchema": { + "type": "object", + "description": "Full schema for a single trading / liquidity operation on the Aleo AMM.", + "required": [ + "id", + "program", + "function", + "visibility", + "description", + "inputs" + ], + "properties": { + "description": { + "type": "string", + "description": "One-line human summary." + }, + "follow_up": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Optional follow-up transactions that must be executed after this one." + }, + "function": { + "type": "string", + "description": "Function name on-chain." + }, + "id": { + "type": "string", + "description": "Short identifier (`swap`, `mint`, `create_pool`, ...)." + }, + "inputs": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SchemaField" + }, + "description": "Ordered list of inputs \u2014 index in this array == positional argument index." + }, + "program": { + "type": "string", + "description": "Aleo program ID the function lives on (e.g. `shield_swap_v0_0_1.aleo`, `token_registry.aleo`)." + }, + "visibility": { + "type": "string", + "description": "`public` (clear inputs) or `private` (hidden inputs using records)." + } + } + }, + "GlobalConfigResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/GlobalConfigStatus" + } + } + }, + "GlobalConfigStatus": { + "type": "object", + "required": [ + "global_paused", + "pool_creation_is_open" + ], + "properties": { + "global_paused": { + "type": "boolean" + }, + "pool_creation_is_open": { + "type": "boolean" + } + } + }, + "GranularityDoc": { + "type": "string", + "enum": [ + "1m", + "5m", + "15m", + "30m", + "1h", + "6h", + "12h", + "1d" + ] + }, + "InitializedTicksResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "type": "array", + "items": { + "type": "integer", + "format": "int32" + } + } + } + }, + "LiquidityDistributionResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TickLiquidityDoc" + } + } + } + }, + "MintTokenRequest": { + "type": "object", + "required": [ + "wrapper_program", + "recipient", + "amount" + ], + "properties": { + "amount": { + "type": "string", + "description": "Amount in BASE units (already scaled by 10^decimals), as a string." + }, + "recipient": { + "type": "string", + "description": "Recipient Aleo address (`aleo1...`)." + }, + "wrapper_program": { + "type": "string", + "description": "The token's wrapper program id (e.g. `mtk_a1b2c3.aleo`)." + } + } + }, + "MintTokenResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/MintTokenResult" + } + } + }, + "MintTokenResult": { + "type": "object", + "required": [ + "status" + ], + "properties": { + "status": { + "type": "string" + }, + "tx_id": { + "type": [ + "string", + "null" + ] + } + } + }, + "OhlcvDoc": { + "type": "object", + "required": [ + "o", + "h", + "l", + "c", + "v", + "timestamp", + "granularity", + "pool" + ], + "properties": { + "c": { + "type": "string", + "description": "Last normalized token1-per-token0 price; execution price after migration 0028, preserved legacy baseline before it." + }, + "granularity": { + "$ref": "#/components/schemas/GranularityDoc" + }, + "h": { + "type": "string", + "description": "Highest normalized token1-per-token0 price; execution price after migration 0028, preserved legacy baseline before it." + }, + "l": { + "type": "string", + "description": "Lowest normalized token1-per-token0 price; execution price after migration 0028, preserved legacy baseline before it." + }, + "o": { + "type": "string", + "description": "First normalized token1-per-token0 price; execution price after migration 0028, preserved legacy baseline before it." + }, + "pool": { + "type": "string" + }, + "timestamp": { + "type": "integer", + "format": "int64" + }, + "v": { + "type": "string", + "description": "Raw token0 volume; exact consumed units after migration 0028, preserved legacy baseline before it." + } + } + }, + "OhlcvResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/OhlcvDoc" + } + } + } + }, + "PaginationMeta": { + "type": "object", + "required": [ + "total", + "limit", + "offset" + ], + "properties": { + "limit": { + "type": "integer", + "format": "int64" + }, + "offset": { + "type": "integer", + "format": "int64" + }, + "total": { + "type": "integer", + "format": "int64" + } + } + }, + "PairComplianceResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/PairComplianceStatus" + } + } + }, + "PairComplianceStatus": { + "type": "object", + "required": [ + "token0", + "token1", + "paused" + ], + "properties": { + "paused": { + "type": "boolean" + }, + "token0": { + "type": "string" + }, + "token1": { + "type": "string" + } + } + }, + "PendingSwapDoc": { + "type": "object", + "required": [ + "swap_id", + "swap_tx_hash", + "is_private", + "is_multi_hop", + "output" + ], + "properties": { + "is_multi_hop": { + "type": "boolean" + }, + "is_private": { + "type": "boolean" + }, + "output": { + "$ref": "#/components/schemas/PendingSwapOutputDoc" + }, + "swap_id": { + "type": "string" + }, + "swap_tx_hash": { + "type": "string" + }, + "token_in_info": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/TokenDoc" + } + ] + }, + "token_out_info": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/TokenDoc" + } + ] + } + } + }, + "PendingSwapOutputDoc": { + "type": "object", + "required": [ + "recipient", + "token_in", + "token_out", + "amount_out", + "amount_remaining" + ], + "properties": { + "amount_out": { + "type": "string" + }, + "amount_remaining": { + "type": "string" + }, + "amount_remaining_1": { + "type": [ + "string", + "null" + ] + }, + "amount_remaining_2": { + "type": [ + "string", + "null" + ] + }, + "recipient": { + "type": "string" + }, + "token_in": { + "type": "string" + }, + "token_in_1": { + "type": [ + "string", + "null" + ] + }, + "token_in_2": { + "type": [ + "string", + "null" + ] + }, + "token_out": { + "type": "string" + } + } + }, + "PoolDebugInfoDoc": { + "type": "object", + "required": [ + "pool_key", + "tick_statuses" + ], + "properties": { + "active_tick": { + "type": [ + "integer", + "null" + ], + "format": "int32" + }, + "liquidity": { + "type": [ + "string", + "null" + ] + }, + "pool_key": { + "type": "string" + }, + "slot_raw": { + "type": [ + "string", + "null" + ] + }, + "sqrt_price": { + "type": [ + "string", + "null" + ] + }, + "tick_spacing": { + "type": [ + "string", + "null" + ] + }, + "tick_statuses": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TickStatusDoc" + } + } + } + }, + "PoolDebugResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/PoolDebugInfoDoc" + } + } + }, + "PoolListResponseDoc": { + "type": "object", + "required": [ + "data", + "pagination" + ], + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PoolResponseDoc" + } + }, + "pagination": { + "$ref": "#/components/schemas/PaginationMeta" + } + } + }, + "PoolResponseDoc": { + "allOf": [ + { + "$ref": "#/components/schemas/PoolStateDoc" + }, + { + "type": "object", + "properties": { + "token0_info": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/TokenDoc" + } + ] + }, + "token1_info": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/TokenDoc" + } + ] + } + } + } + ] + }, + "PoolStateDoc": { + "type": "object", + "required": [ + "id", + "key", + "token0", + "token1", + "enabled", + "creator", + "fee", + "created_at", + "init_tx", + "scale0", + "scale1" + ], + "properties": { + "created_at": { + "type": "string" + }, + "creator": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "fee": { + "type": "string" + }, + "id": { + "type": "string" + }, + "init_tx": { + "type": "string" + }, + "key": { + "type": "string" + }, + "scale0": { + "type": "string" + }, + "scale1": { + "type": "string" + }, + "token0": { + "type": "string" + }, + "token1": { + "type": "string" + } + } + }, + "PoolStats24hBatchResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/PoolStats24hDoc" + }, + "propertyNames": { + "type": "string" + } + } + } + }, + "PoolStats24hDoc": { + "type": "object", + "required": [ + "price", + "price_reversed", + "liquidity", + "open_24h", + "high_24h", + "low_24h", + "volume_24h" + ], + "properties": { + "change_24h_pct": { + "type": [ + "string", + "null" + ] + }, + "high_24h": { + "type": "string", + "description": "Highest normalized price; execution price after migration 0028, preserved legacy baseline before it." + }, + "liquidity": { + "type": "string" + }, + "low_24h": { + "type": "string", + "description": "Lowest normalized price; execution price after migration 0028, preserved legacy baseline before it." + }, + "open_24h": { + "type": "string", + "description": "Earliest normalized price; execution price after migration 0028, preserved legacy baseline before it." + }, + "price": { + "type": "string" + }, + "price_reversed": { + "type": "string" + }, + "volume_24h": { + "type": "string", + "description": "Raw token0 volume; exact consumed units after migration 0028, preserved legacy baseline before it." + } + } + }, + "PoolStats24hResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/PoolStats24hDoc" + } + } + }, + "PoolStatsDoc": { + "type": "object", + "required": [ + "id", + "price", + "price_reversed", + "active_tick", + "tick_spacing", + "liquidity", + "pool", + "fee_protocol", + "protocol_fees0", + "protocol_fees1", + "fee_growth_global0_x_64", + "fee_growth_global1_x_64", + "max_liquidity_per_tick", + "next_init_below", + "next_init_above" + ], + "properties": { + "active_tick": { + "type": "integer", + "format": "int32" + }, + "fee_growth_global0_x_64": { + "type": "string" + }, + "fee_growth_global1_x_64": { + "type": "string" + }, + "fee_protocol": { + "type": "integer", + "format": "int32" + }, + "id": { + "type": "string" + }, + "liquidity": { + "type": "string" + }, + "max_liquidity_per_tick": { + "type": "string" + }, + "next_init_above": { + "type": "integer", + "format": "int32" + }, + "next_init_below": { + "type": "integer", + "format": "int32" + }, + "pool": { + "type": "string" + }, + "price": { + "type": "string" + }, + "price_reversed": { + "type": "string" + }, + "protocol_fees0": { + "type": "string" + }, + "protocol_fees1": { + "type": "string" + }, + "tick_spacing": { + "type": "integer", + "format": "int32" + } + } + }, + "PoolTradeDoc": { + "type": "object", + "required": [ + "id", + "tradeType", + "amount0", + "amount1", + "executedAt", + "pool" + ], + "properties": { + "amount0": { + "type": "string" + }, + "amount1": { + "type": "string" + }, + "executedAt": { + "type": "string" + }, + "id": { + "type": "string" + }, + "pool": { + "type": "string" + }, + "tradeType": { + "$ref": "#/components/schemas/PoolTradeTypeDoc" + } + } + }, + "PoolTradeFilterDoc": { + "type": "string", + "enum": [ + "mint", + "add_liquidity", + "remove_liquidity", + "burn", + "collect", + "swap" + ] + }, + "PoolTradeTypeDoc": { + "type": "string", + "enum": [ + "mint", + "add_liquidity", + "remove_liquidity", + "burn", + "collect", + "swap", + "swap_multi_hop" + ] + }, + "PoolTradesResponseDoc": { + "type": "object", + "required": [ + "data", + "pagination" + ], + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PoolTradeDoc" + } + }, + "pagination": { + "$ref": "#/components/schemas/PaginationMeta" + } + } + }, + "PoolWithStatsDoc": { + "allOf": [ + { + "$ref": "#/components/schemas/PoolStateDoc" + }, + { + "type": "object", + "properties": { + "stats": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/PoolStatsDoc" + } + ] + }, + "token0_info": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/TokenDoc" + } + ] + }, + "token1_info": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/TokenDoc" + } + ] + } + } + } + ] + }, + "PoolWithStatsResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/PoolWithStatsDoc" + } + } + }, + "PositionDoc": { + "type": "object", + "required": [ + "id", + "token_id", + "tick_lower", + "tick_upper", + "liquidity", + "amount0", + "amount1", + "user", + "pool", + "created_at", + "transaction", + "is_burned", + "fee_growth_inside0_last_64", + "fee_growth_inside1_last_64", + "tokens_owed0", + "tokens_owed1", + "is_private", + "is_frozen" + ], + "properties": { + "amount0": { + "type": "string" + }, + "amount1": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "fee_growth_inside0_last_64": { + "type": "string" + }, + "fee_growth_inside1_last_64": { + "type": "string" + }, + "frozen_at": { + "type": [ + "string", + "null" + ] + }, + "id": { + "type": "string" + }, + "is_burned": { + "type": "boolean" + }, + "is_frozen": { + "type": "boolean" + }, + "is_private": { + "type": "boolean" + }, + "liquidity": { + "type": "string" + }, + "pool": { + "type": "string" + }, + "tick_lower": { + "type": "integer", + "format": "int32" + }, + "tick_upper": { + "type": "integer", + "format": "int32" + }, + "token_id": { + "type": "string" + }, + "tokens_owed0": { + "type": "string" + }, + "tokens_owed1": { + "type": "string" + }, + "transaction": { + "type": "string" + }, + "transaction_hash": { + "type": [ + "string", + "null" + ] + }, + "user": { + "type": "string" + } + } + }, + "PositionListResponseDoc": { + "type": "object", + "required": [ + "data", + "pagination" + ], + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PositionDoc" + } + }, + "pagination": { + "$ref": "#/components/schemas/PaginationMeta" + } + } + }, + "PositionResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/PositionDoc" + } + } + }, + "PositionWithOwedDoc": { + "type": "object", + "required": [ + "token_id", + "pool", + "tick_lower", + "tick_upper", + "tokens_owed0", + "tokens_owed1", + "scale0", + "scale1", + "is_private" + ], + "properties": { + "is_private": { + "type": "boolean" + }, + "pool": { + "type": "string" + }, + "scale0": { + "type": "string" + }, + "scale1": { + "type": "string" + }, + "tick_lower": { + "type": "integer", + "format": "int32" + }, + "tick_upper": { + "type": "integer", + "format": "int32" + }, + "token0_info": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/TokenDoc" + } + ] + }, + "token1_info": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/TokenDoc" + } + ] + }, + "token_id": { + "type": "string" + }, + "tokens_owed0": { + "type": "string" + }, + "tokens_owed1": { + "type": "string" + }, + "transaction_hash": { + "type": [ + "string", + "null" + ] + } + } + }, + "ReferralAdminCheckResponse": { + "type": "object", + "required": [ + "is_admin" + ], + "properties": { + "is_admin": { + "type": "boolean" + } + } + }, + "ReferralAdminResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/ReferralAdminCheckResponse" + } + } + }, + "ReferralCodeRow": { + "type": "object", + "required": [ + "code", + "created_at" + ], + "properties": { + "code": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "issued_to": { + "type": [ + "string", + "null" + ] + }, + "redeemed_at": { + "type": [ + "string", + "null" + ] + }, + "redeemed_by": { + "type": [ + "string", + "null" + ] + } + } + }, + "ReferralGenerateRequest": { + "type": "object", + "required": [ + "count" + ], + "properties": { + "count": { + "type": "integer", + "format": "int32", + "minimum": 0 + } + } + }, + "ReferralGenerateResponse": { + "type": "object", + "required": [ + "codes" + ], + "properties": { + "codes": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "ReferralGenerateResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/ReferralGenerateResponse" + } + } + }, + "ReferralListResponse": { + "type": "object", + "required": [ + "total", + "redeemed", + "available", + "codes" + ], + "properties": { + "available": { + "type": "integer", + "format": "int64" + }, + "codes": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReferralCodeRow" + } + }, + "redeemed": { + "type": "integer", + "format": "int64" + }, + "total": { + "type": "integer", + "format": "int64" + } + } + }, + "ReferralListResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/ReferralListResponse" + } + } + }, + "ReferralMyCodeRow": { + "type": "object", + "required": [ + "code" + ], + "properties": { + "code": { + "type": "string" + }, + "redeemed_at": { + "type": [ + "string", + "null" + ] + }, + "redeemed_by": { + "type": [ + "string", + "null" + ] + } + } + }, + "ReferralMyCodesResponse": { + "type": "object", + "required": [ + "quota", + "codes" + ], + "properties": { + "codes": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReferralMyCodeRow" + } + }, + "quota": { + "type": "integer", + "format": "int32" + } + } + }, + "ReferralMyCodesResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/ReferralMyCodesResponse" + } + } + }, + "ReferralRedeemRequest": { + "type": "object", + "required": [ + "code" + ], + "properties": { + "code": { + "type": "string" + } + } + }, + "ReferralRedeemResponse": { + "type": "object", + "required": [ + "code", + "status", + "token" + ], + "properties": { + "code": { + "type": "string" + }, + "status": { + "type": "string" + }, + "token": { + "type": "string" + } + } + }, + "ReferralRedeemResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/ReferralRedeemResponse" + } + } + }, + "ReferralSettingsResponse": { + "type": "object", + "required": [ + "codes_per_user", + "codes_per_user_limit" + ], + "properties": { + "codes_per_user": { + "type": "integer", + "format": "int32" + }, + "codes_per_user_limit": { + "type": "integer", + "format": "int32" + }, + "max_users": { + "type": [ + "integer", + "null" + ], + "format": "int32" + } + } + }, + "ReferralSettingsResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/ReferralSettingsResponse" + } + } + }, + "ReferralStatusResponse": { + "type": "object", + "required": [ + "has_access" + ], + "properties": { + "code": { + "type": [ + "string", + "null" + ] + }, + "has_access": { + "type": "boolean" + } + } + }, + "ReferralStatusResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/ReferralStatusResponse" + } + } + }, + "ReferralUpdateSettingsRequest": { + "type": "object", + "required": [ + "codes_per_user" + ], + "properties": { + "codes_per_user": { + "type": "integer", + "format": "int32" + }, + "max_users": { + "type": [ + "integer", + "null" + ], + "format": "int32" + } + } + }, + "RouteHopDoc": { + "type": "object", + "required": [ + "pool_key", + "token_in", + "token_out", + "zero_for_one", + "fee", + "initialized_ticks" + ], + "properties": { + "active_tick": { + "type": [ + "integer", + "null" + ], + "format": "int32" + }, + "fee": { + "type": "string" + }, + "initialized_ticks": { + "type": "array", + "items": { + "type": "integer", + "format": "int32" + } + }, + "liquidity": { + "type": [ + "string", + "null" + ] + }, + "pool_key": { + "type": "string" + }, + "price": { + "type": [ + "string", + "null" + ] + }, + "sqrt_price_raw": { + "type": [ + "string", + "null" + ] + }, + "tick_spacing": { + "type": [ + "integer", + "null" + ], + "format": "int32" + }, + "token_in": { + "type": "string" + }, + "token_out": { + "type": "string" + }, + "zero_for_one": { + "type": "boolean" + } + } + }, + "RouteResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/RouteResultDoc" + } + } + }, + "RouteResultDoc": { + "type": "object", + "required": [ + "hops", + "token_in", + "token_out" + ], + "properties": { + "estimated_amount_out": { + "type": [ + "string", + "null" + ] + }, + "hops": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RouteHopDoc" + } + }, + "token_in": { + "type": "string" + }, + "token_out": { + "type": "string" + } + } + }, + "SchemaField": { + "type": "object", + "description": "Describes a single input field of an on-chain function or struct.", + "required": [ + "name", + "type", + "visibility", + "description" + ], + "properties": { + "description": { + "type": "string", + "description": "Human-readable explanation of the field." + }, + "fields": { + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/components/schemas/SchemaField" + }, + "description": "For struct-typed inputs, the nested field list." + }, + "name": { + "type": "string", + "description": "Parameter/field name as used in the Leo/Aleo program." + }, + "type": { + "type": "string", + "description": "Aleo type: `field`, `u128`, `u64`, `u32`, `u16`, `u8`, `i128`, `i32`, `bool`, `address`,\na struct name (e.g. `SwapRequest`), or `record` for Aleo records." + }, + "visibility": { + "type": "string", + "description": "`public` or `private` \u2014 controls whether the value is revealed on-chain." + } + } + }, + "SwapDoc": { + "type": "object", + "required": [ + "id", + "swap_id", + "hops", + "pool", + "input_amount", + "output_amount", + "input_token", + "output_token", + "user", + "nonce", + "recipient", + "executed_at", + "amount_remaining", + "transaction", + "amount_remaining_1", + "amount_remaining_2", + "is_private" + ], + "properties": { + "amount_remaining": { + "type": "string" + }, + "amount_remaining_1": { + "type": "string" + }, + "amount_remaining_2": { + "type": "string" + }, + "claim_tx": { + "type": [ + "string", + "null" + ] + }, + "claimed_at": { + "type": [ + "string", + "null" + ] + }, + "executed_at": { + "type": "string" + }, + "hops": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SwapHopDoc" + }, + "description": "Full ordered route for single-hop and multi-hop swaps." + }, + "id": { + "type": "string" + }, + "input_amount": { + "type": "string" + }, + "input_token": { + "type": "string" + }, + "input_token_info": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/TokenDoc" + } + ] + }, + "is_private": { + "type": "boolean" + }, + "nonce": { + "type": "string" + }, + "output_amount": { + "type": "string" + }, + "output_token": { + "type": "string" + }, + "output_token_info": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/TokenDoc" + } + ] + }, + "pool": { + "type": "string", + "description": "First-hop pool retained for compatibility; use `hops` for the full route." + }, + "recipient": { + "type": "string" + }, + "swap_id": { + "type": "string" + }, + "token_in_1": { + "type": [ + "string", + "null" + ] + }, + "token_in_2": { + "type": [ + "string", + "null" + ] + }, + "trade": { + "type": [ + "string", + "null" + ], + "description": "Pool analytics trade; absent when a route lacks authoritative per-hop amounts." + }, + "transaction": { + "type": "string" + }, + "user": { + "type": "string" + } + } + }, + "SwapHopDoc": { + "type": "object", + "required": [ + "pool", + "zero_for_one" + ], + "properties": { + "pool": { + "type": "string" + }, + "zero_for_one": { + "type": "boolean" + } + } + }, + "SwapListResponseDoc": { + "type": "object", + "required": [ + "data", + "pagination" + ], + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SwapDoc" + } + }, + "pagination": { + "$ref": "#/components/schemas/PaginationMeta" + } + } + }, + "SwapResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/SwapDoc" + } + } + }, + "TickLiquidityDoc": { + "type": "object", + "required": [ + "tick", + "liquidity_net" + ], + "properties": { + "liquidity_net": { + "type": "string" + }, + "tick": { + "type": "integer", + "format": "int32" + } + } + }, + "TickSpacingDoc": { + "type": "object", + "required": [ + "id", + "tick_spacing" + ], + "properties": { + "id": { + "type": "string" + }, + "tick_spacing": { + "type": "integer", + "format": "int32" + } + } + }, + "TickSpacingListResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TickSpacingDoc" + } + } + } + }, + "TickStatusDoc": { + "type": "object", + "required": [ + "tick", + "tick_mapping_key", + "exists" + ], + "properties": { + "exists": { + "type": "boolean" + }, + "raw_value": { + "type": [ + "string", + "null" + ] + }, + "tick": { + "type": "integer", + "format": "int32" + }, + "tick_mapping_key": { + "type": "string" + } + } + }, + "TokenBalanceDoc": { + "type": "object", + "required": [ + "token_id", + "token_address", + "symbol", + "name", + "decimals", + "balance" + ], + "properties": { + "balance": { + "type": "string", + "description": "Base-unit balance (no decimals applied)." + }, + "decimals": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "token_address": { + "type": "string" + }, + "token_id": { + "type": "string" + } + } + }, + "TokenComplianceResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/TokenComplianceStatus" + } + } + }, + "TokenComplianceStatus": { + "type": "object", + "required": [ + "token_id", + "allowed", + "paused" + ], + "properties": { + "allowed": { + "type": "boolean" + }, + "paused": { + "type": "boolean" + }, + "token_id": { + "type": "string" + } + } + }, + "TokenDoc": { + "type": "object", + "required": [ + "id", + "address", + "name", + "symbol", + "decimals" + ], + "properties": { + "address": { + "type": "string" + }, + "decimals": { + "type": "integer", + "format": "int32" + }, + "id": { + "type": "string" + }, + "image": { + "type": [ + "string", + "null" + ] + }, + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "wrapper_program": { + "type": [ + "string", + "null" + ] + } + } + }, + "TokenListResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TokenDoc" + } + } + } + }, + "TokenResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/TokenDoc" + } + } + }, + "TradingSchemaListResponse": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FunctionSchema" + } + } + } + }, + "TradingSchemaResponse": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/FunctionSchema" + } + } + }, + "UnclaimedPayloadDoc": { + "type": "object", + "required": [ + "pending_swaps", + "positions_with_owed" + ], + "properties": { + "pending_swaps": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PendingSwapDoc" + } + }, + "positions_with_owed": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PositionWithOwedDoc" + } + } + } + }, + "UnclaimedResponseDoc": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/UnclaimedPayloadDoc" + } + } + }, + "VerifyRequestDoc": { + "type": "object", + "required": [ + "address", + "signature" + ], + "properties": { + "address": { + "type": "string" + }, + "signature": { + "type": "string" + } + } + } + }, + "securitySchemes": { + "bearer_auth": { + "type": "http", + "scheme": "bearer", + "bearerFormat": "JWT", + "description": "Session JWT from `POST /auth/verify` (24h), or a long-lived API token (`ss_\u2026`) minted at `POST /api-tokens`. API tokens work on data and trading endpoints; token management and admin endpoints accept session JWTs only." + } + } + }, + "tags": [ + { + "name": "schema", + "description": "On-chain function input schemas for trading / liquidity / token operations" + }, + { + "name": "auth", + "description": "Wallet signature challenge / JWT verification" + }, + { + "name": "access", + "description": "Invite access redemption and administration" + }, + { + "name": "api-tokens", + "description": "Long-lived API tokens for programmatic access; send as `Authorization: Bearer ss_\u2026` on any gated endpoint" + }, + { + "name": "referral", + "description": "Referral redemption and administration" + }, + { + "name": "pools", + "description": "Pool metadata, stats, trades, OHLCV" + }, + { + "name": "positions", + "description": "LP positions" + }, + { + "name": "swaps", + "description": "Historical swaps" + }, + { + "name": "tokens", + "description": "Token registry" + }, + { + "name": "balances", + "description": "On-chain token balances" + }, + { + "name": "compliance", + "description": "Token/pair allowlist, pause, and pool-creation gating state" + }, + { + "name": "protocol", + "description": "Fee tiers and tick spacings" + }, + { + "name": "route", + "description": "Swap routing" + }, + { + "name": "debug", + "description": "On-chain introspection helpers" + }, + { + "name": "airdrop", + "description": "Faucet \u2014 sends 1000 of every registered token to a user address" + }, + { + "name": "unclaimed", + "description": "Pending swap outputs and position fees" + } + ] +} diff --git a/shield-swap-sdk/codegen/regen-abi.sh b/shield-swap-sdk/codegen/regen-abi.sh new file mode 100755 index 00000000..04464556 --- /dev/null +++ b/shield-swap-sdk/codegen/regen-abi.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash +# Refetch the deployed program and regenerate the pinned ABI + bindings. +# Run from anywhere; requires the aleo + aleo-contract-abi-generator packages on python3's path. +set -euo pipefail +cd "$(dirname "$0")" +PROGRAM="${1:-shield_swap_v3.aleo}" +PYTHON="${PYTHON:-python3}" +"$PYTHON" - "$PROGRAM" <<'EOF' +import json +import re +import sys + +import requests + +import aleo.abi + +NODE = "https://api.provable.com/v2/testnet/program/{}" + + +def fetch(program_id: str) -> str: + r = requests.get(NODE.format(program_id), timeout=30) + r.raise_for_status() + return r.json() + + +def imports_of(src: str) -> list[str]: + return re.findall(r"^import\s+(\S+?);\s*$", src, re.MULTILINE) + + +def load_deps(program_id: str, seen: dict) -> None: + """Post-order DFS: dependencies land in `seen` before their dependents.""" + src = fetch(program_id) + for dep in imports_of(src): + if dep not in seen and dep != "credits.aleo": # credits is preloaded + load_deps(dep, seen) + seen[program_id] = src + + +program = sys.argv[1] +seen: dict = {} +load_deps(program, seen) +src = seen.pop(program) +deps = list(seen.items()) +print(f"deps (topological): {[d for d, _ in deps] or 'none'}") +abi = aleo.abi.generate_abi(src, "testnet", imports=deps) +json.dump(abi, open("shield_swap.abi.json", "w"), indent=1) +print(f"wrote shield_swap.abi.json ({len(abi['structs'])} structs, " + f"{len(abi['records'])} records, {len(abi['mappings'])} mappings)") +EOF +"$PYTHON" -m aleo.codegen --abi shield_swap.abi.json \ + --out ../python/aleo_shield_swap/_generated.py +echo "regenerated: shield_swap.abi.json + _generated.py — review the git diff" diff --git a/shield-swap-sdk/codegen/regen-openapi.sh b/shield-swap-sdk/codegen/regen-openapi.sh new file mode 100755 index 00000000..73e25e5c --- /dev/null +++ b/shield-swap-sdk/codegen/regen-openapi.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +# Refetch the DEX API's OpenAPI spec and regenerate the response models. +set -euo pipefail +cd "$(dirname "$0")" +BASE="${1:-https://amm-api.dev.provable.com}" +PYTHON="${PYTHON:-python3}" +curl -sf "${BASE}/openapi.json" | "$PYTHON" -m json.tool > amm_api.openapi.json +"$PYTHON" -m datamodel_code_generator \ + --input amm_api.openapi.json --input-file-type openapi \ + --output ../python/aleo_shield_swap/_api_models.py \ + --output-model-type dataclasses.dataclass \ + --target-python-version 3.10 \ + --use-standard-collections \ + --custom-file-header "# Generated by datamodel-code-generator — DO NOT EDIT." +echo "regenerated: amm_api.openapi.json + _api_models.py — review the git diff" diff --git a/shield-swap-sdk/codegen/shield_swap.abi.json b/shield-swap-sdk/codegen/shield_swap.abi.json new file mode 100644 index 00000000..c7d2fa8b --- /dev/null +++ b/shield-swap-sdk/codegen/shield_swap.abi.json @@ -0,0 +1,2777 @@ +{ + "program": "shield_swap_v3.aleo", + "structs": [ + { + "path": [ + "SwapRequest" + ], + "fields": [ + { + "name": "pool", + "ty": { + "Primitive": "Field" + } + }, + { + "name": "zero_for_one", + "ty": { + "Primitive": "Boolean" + } + }, + { + "name": "amount_in", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "amount_out_min", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "sqrt_price_limit", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "recipient", + "ty": { + "Primitive": "Address" + } + }, + { + "name": "nonce", + "ty": { + "Primitive": { + "UInt": "U64" + } + } + }, + { + "name": "deadline", + "ty": { + "Primitive": { + "UInt": "U32" + } + } + } + ] + }, + { + "path": [ + "SwapHop" + ], + "fields": [ + { + "name": "pool", + "ty": { + "Primitive": "Field" + } + }, + { + "name": "zero_for_one", + "ty": { + "Primitive": "Boolean" + } + }, + { + "name": "sqrt_price_limit", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + } + ] + }, + { + "path": [ + "SwapMultiHopRequest" + ], + "fields": [ + { + "name": "token_in", + "ty": { + "Primitive": "Field" + } + }, + { + "name": "token_out", + "ty": { + "Primitive": "Field" + } + }, + { + "name": "amount_in", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "amount_out_min", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "recipient", + "ty": { + "Primitive": "Address" + } + }, + { + "name": "hop0", + "ty": { + "Struct": { + "path": [ + "SwapHop" + ], + "program": "shield_swap_v3.aleo" + } + } + }, + { + "name": "hop1", + "ty": { + "Struct": { + "path": [ + "SwapHop" + ], + "program": "shield_swap_v3.aleo" + } + } + }, + { + "name": "hop2", + "ty": { + "Struct": { + "path": [ + "SwapHop" + ], + "program": "shield_swap_v3.aleo" + } + } + }, + { + "name": "hop_count", + "ty": { + "Primitive": { + "UInt": "U8" + } + } + }, + { + "name": "nonce", + "ty": { + "Primitive": { + "UInt": "U64" + } + } + }, + { + "name": "deadline", + "ty": { + "Primitive": { + "UInt": "U32" + } + } + }, + { + "name": "caller", + "ty": { + "Primitive": "Address" + } + } + ] + }, + { + "path": [ + "MintPositionRequest" + ], + "fields": [ + { + "name": "pool", + "ty": { + "Primitive": "Field" + } + }, + { + "name": "tick_lower", + "ty": { + "Primitive": { + "Int": "I32" + } + } + }, + { + "name": "tick_upper", + "ty": { + "Primitive": { + "Int": "I32" + } + } + }, + { + "name": "amount0_desired", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "amount1_desired", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "amount0_min", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "amount1_min", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "tick_lower_hint", + "ty": { + "Primitive": { + "Int": "I32" + } + } + }, + { + "name": "tick_upper_hint", + "ty": { + "Primitive": { + "Int": "I32" + } + } + } + ] + }, + { + "path": [ + "PoolState" + ], + "fields": [ + { + "name": "token0", + "ty": { + "Primitive": "Field" + } + }, + { + "name": "token1", + "ty": { + "Primitive": "Field" + } + }, + { + "name": "fee", + "ty": { + "Primitive": { + "UInt": "U16" + } + } + }, + { + "name": "enabled", + "ty": { + "Primitive": "Boolean" + } + }, + { + "name": "scale0", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "scale1", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + } + ] + }, + { + "path": [ + "Slot" + ], + "fields": [ + { + "name": "tick", + "ty": { + "Primitive": { + "Int": "I32" + } + } + }, + { + "name": "tick_spacing", + "ty": { + "Primitive": { + "UInt": "U32" + } + } + }, + { + "name": "sqrt_price", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "fee_protocol", + "ty": { + "Primitive": { + "UInt": "U8" + } + } + }, + { + "name": "liquidity", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "fee_growth_global0_x_64", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "fee_growth_global1_x_64", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "fee_residual0_x_64", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "fee_residual1_x_64", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "max_liquidity_per_tick", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "protocol_fees0", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "protocol_fees1", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "next_init_below", + "ty": { + "Primitive": { + "Int": "I32" + } + } + }, + { + "name": "next_init_above", + "ty": { + "Primitive": { + "Int": "I32" + } + } + } + ] + }, + { + "path": [ + "Tick" + ], + "fields": [ + { + "name": "pool", + "ty": { + "Primitive": "Field" + } + }, + { + "name": "liquidity_net", + "ty": { + "Primitive": { + "Int": "I128" + } + } + }, + { + "name": "liquidity_gross", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "tick", + "ty": { + "Primitive": { + "Int": "I32" + } + } + }, + { + "name": "fee_growth_outside0_64", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "fee_growth_outside1_64", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "prev", + "ty": { + "Primitive": { + "Int": "I32" + } + } + }, + { + "name": "next", + "ty": { + "Primitive": { + "Int": "I32" + } + } + } + ] + }, + { + "path": [ + "Position" + ], + "fields": [ + { + "name": "token_id", + "ty": { + "Primitive": "Field" + } + }, + { + "name": "pool", + "ty": { + "Primitive": "Field" + } + }, + { + "name": "tick_lower", + "ty": { + "Primitive": { + "Int": "I32" + } + } + }, + { + "name": "tick_upper", + "ty": { + "Primitive": { + "Int": "I32" + } + } + }, + { + "name": "liquidity", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "fee_growth_inside0_last_64", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "fee_growth_inside1_last_64", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "tokens_owed0", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "tokens_owed1", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + } + ] + }, + { + "path": [ + "PairKey" + ], + "fields": [ + { + "name": "token0", + "ty": { + "Primitive": "Field" + } + }, + { + "name": "token1", + "ty": { + "Primitive": "Field" + } + } + ] + }, + { + "path": [ + "SwapIterCfg" + ], + "fields": [ + { + "name": "z", + "ty": { + "Primitive": "Boolean" + } + }, + { + "name": "lim", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "fee_pips", + "ty": { + "Primitive": { + "UInt": "U32" + } + } + }, + { + "name": "fee_protocol", + "ty": { + "Primitive": { + "UInt": "U8" + } + } + }, + { + "name": "slot_fg0", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "slot_fg1", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + } + ] + }, + { + "path": [ + "SwapIterState" + ], + "fields": [ + { + "name": "sp", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "rem", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "out", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "fg", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "liq", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "tk", + "ty": { + "Primitive": { + "Int": "I32" + } + } + }, + { + "name": "crossed", + "ty": { + "Primitive": "Boolean" + } + }, + { + "name": "pf", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "nb", + "ty": { + "Primitive": { + "Int": "I32" + } + } + }, + { + "name": "na", + "ty": { + "Primitive": { + "Int": "I32" + } + } + }, + { + "name": "resid", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + } + ] + }, + { + "path": [ + "SwapOutput" + ], + "fields": [ + { + "name": "recipient", + "ty": { + "Primitive": "Address" + } + }, + { + "name": "caller", + "ty": { + "Primitive": "Address" + } + }, + { + "name": "token_in", + "ty": { + "Primitive": "Field" + } + }, + { + "name": "token_out", + "ty": { + "Primitive": "Field" + } + }, + { + "name": "amount_out", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "amount_remaining", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "token_in_1", + "ty": { + "Primitive": "Field" + } + }, + { + "name": "amount_remaining_1", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + }, + { + "name": "token_in_2", + "ty": { + "Primitive": "Field" + } + }, + { + "name": "amount_remaining_2", + "ty": { + "Primitive": { + "UInt": "U128" + } + } + } + ] + } + ], + "records": [ + { + "path": [ + "PositionNFT" + ], + "fields": [ + { + "name": "owner", + "ty": { + "Primitive": "Address" + }, + "mode": "Public" + }, + { + "name": "token_id", + "ty": { + "Primitive": "Field" + }, + "mode": "Private" + }, + { + "name": "token0_id", + "ty": { + "Primitive": "Field" + }, + "mode": "Private" + }, + { + "name": "token1_id", + "ty": { + "Primitive": "Field" + }, + "mode": "Private" + }, + { + "name": "pool", + "ty": { + "Primitive": "Field" + }, + "mode": "Private" + }, + { + "name": "tick_lower", + "ty": { + "Primitive": { + "Int": "I32" + } + }, + "mode": "Private" + }, + { + "name": "tick_upper", + "ty": { + "Primitive": { + "Int": "I32" + } + }, + "mode": "Private" + } + ] + }, + { + "path": [ + "SwapComplianceRecord" + ], + "fields": [ + { + "name": "owner", + "ty": { + "Primitive": "Address" + }, + "mode": "Public" + }, + { + "name": "swap_id", + "ty": { + "Primitive": "Field" + }, + "mode": "Private" + }, + { + "name": "token_in", + "ty": { + "Primitive": "Field" + }, + "mode": "Private" + }, + { + "name": "token_out", + "ty": { + "Primitive": "Field" + }, + "mode": "Private" + }, + { + "name": "request", + "ty": { + "Struct": { + "path": [ + "SwapRequest" + ], + "program": "shield_swap_v3.aleo" + } + }, + "mode": "Private" + }, + { + "name": "caller", + "ty": { + "Primitive": "Address" + }, + "mode": "Private" + }, + { + "name": "blinded_address", + "ty": { + "Primitive": "Address" + }, + "mode": "Private" + } + ] + }, + { + "path": [ + "MultiHopSwapComplianceRecord" + ], + "fields": [ + { + "name": "owner", + "ty": { + "Primitive": "Address" + }, + "mode": "Public" + }, + { + "name": "swap_id", + "ty": { + "Primitive": "Field" + }, + "mode": "Private" + }, + { + "name": "request", + "ty": { + "Struct": { + "path": [ + "SwapMultiHopRequest" + ], + "program": "shield_swap_v3.aleo" + } + }, + "mode": "Private" + }, + { + "name": "caller", + "ty": { + "Primitive": "Address" + }, + "mode": "Private" + }, + { + "name": "blinded_address", + "ty": { + "Primitive": "Address" + }, + "mode": "Private" + } + ] + }, + { + "path": [ + "MintComplianceRecord" + ], + "fields": [ + { + "name": "owner", + "ty": { + "Primitive": "Address" + }, + "mode": "Public" + }, + { + "name": "token_id", + "ty": { + "Primitive": "Field" + }, + "mode": "Private" + }, + { + "name": "token0_id", + "ty": { + "Primitive": "Field" + }, + "mode": "Private" + }, + { + "name": "token1_id", + "ty": { + "Primitive": "Field" + }, + "mode": "Private" + }, + { + "name": "request", + "ty": { + "Struct": { + "path": [ + "MintPositionRequest" + ], + "program": "shield_swap_v3.aleo" + } + }, + "mode": "Private" + }, + { + "name": "caller", + "ty": { + "Primitive": "Address" + }, + "mode": "Private" + }, + { + "name": "recipient", + "ty": { + "Primitive": "Address" + }, + "mode": "Private" + } + ] + } + ], + "mappings": [ + { + "name": "pools", + "key": { + "Primitive": "Field" + }, + "value": { + "Struct": { + "path": [ + "PoolState" + ], + "program": "shield_swap_v3.aleo" + } + } + }, + { + "name": "slots", + "key": { + "Primitive": "Field" + }, + "value": { + "Struct": { + "path": [ + "Slot" + ], + "program": "shield_swap_v3.aleo" + } + } + }, + { + "name": "ticks", + "key": { + "Primitive": "Field" + }, + "value": { + "Struct": { + "path": [ + "Tick" + ], + "program": "shield_swap_v3.aleo" + } + } + }, + { + "name": "initialized_pools", + "key": { + "Primitive": "Field" + }, + "value": { + "Primitive": "Boolean" + } + }, + { + "name": "tick_spacings", + "key": { + "Primitive": { + "UInt": "U32" + } + }, + "value": { + "Primitive": "Boolean" + } + }, + { + "name": "fee_tiers", + "key": { + "Primitive": { + "UInt": "U16" + } + }, + "value": { + "Primitive": "Boolean" + } + }, + { + "name": "fee_to_tick_spacing", + "key": { + "Primitive": { + "UInt": "U16" + } + }, + "value": { + "Primitive": { + "UInt": "U32" + } + } + }, + { + "name": "positions", + "key": { + "Primitive": "Field" + }, + "value": { + "Struct": { + "path": [ + "Position" + ], + "program": "shield_swap_v3.aleo" + } + } + }, + { + "name": "swap_outputs", + "key": { + "Primitive": "Field" + }, + "value": { + "Struct": { + "path": [ + "SwapOutput" + ], + "program": "shield_swap_v3.aleo" + } + } + }, + { + "name": "admin", + "key": { + "Primitive": "Boolean" + }, + "value": { + "Primitive": "Address" + } + }, + { + "name": "pending_admin", + "key": { + "Primitive": "Boolean" + }, + "value": { + "Primitive": "Address" + } + }, + { + "name": "used_blinded_addresses", + "key": { + "Primitive": "Address" + }, + "value": { + "Primitive": "Boolean" + } + }, + { + "name": "token_decimals", + "key": { + "Primitive": "Field" + }, + "value": { + "Primitive": { + "UInt": "U8" + } + } + }, + { + "name": "pool_creation_is_open", + "key": { + "Primitive": "Boolean" + }, + "value": { + "Primitive": "Boolean" + } + }, + { + "name": "global_paused", + "key": { + "Primitive": "Boolean" + }, + "value": { + "Primitive": "Boolean" + } + }, + { + "name": "token_allowed", + "key": { + "Primitive": "Field" + }, + "value": { + "Primitive": "Boolean" + } + }, + { + "name": "token_paused", + "key": { + "Primitive": "Field" + }, + "value": { + "Primitive": "Boolean" + } + }, + { + "name": "pair_paused", + "key": { + "Struct": { + "path": [ + "PairKey" + ], + "program": "shield_swap_v3.aleo" + } + }, + "value": { + "Primitive": "Boolean" + } + }, + { + "name": "frozen_position", + "key": { + "Primitive": "Field" + }, + "value": { + "Primitive": { + "UInt": "U32" + } + } + } + ], + "storage_variables": [], + "functions": [ + { + "name": "transfer_admin", + "inputs": [ + { + "Plaintext": { + "ty": { + "Primitive": "Address" + }, + "mode": "Public" + } + } + ], + "outputs": [ + "Final" + ] + }, + { + "name": "accept_admin", + "inputs": [], + "outputs": [ + "Final" + ] + }, + { + "name": "add_tick_spacing", + "inputs": [ + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U32" + } + }, + "mode": "Public" + } + } + ], + "outputs": [ + "Final" + ] + }, + { + "name": "add_fee_tier", + "inputs": [ + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U16" + } + }, + "mode": "Public" + } + } + ], + "outputs": [ + "Final" + ] + }, + { + "name": "bind_fee_to_tick_spacing", + "inputs": [ + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U16" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U32" + } + }, + "mode": "Public" + } + } + ], + "outputs": [ + "Final" + ] + }, + { + "name": "set_token_decimals", + "inputs": [ + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U8" + } + }, + "mode": "Public" + } + } + ], + "outputs": [ + "Final" + ] + }, + { + "name": "set_pool_enabled", + "inputs": [ + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Boolean" + }, + "mode": "Public" + } + } + ], + "outputs": [ + "Final" + ] + }, + { + "name": "set_pool_creation_is_open", + "inputs": [ + { + "Plaintext": { + "ty": { + "Primitive": "Boolean" + }, + "mode": "Public" + } + } + ], + "outputs": [ + "Final" + ] + }, + { + "name": "set_global_paused", + "inputs": [ + { + "Plaintext": { + "ty": { + "Primitive": "Boolean" + }, + "mode": "Public" + } + } + ], + "outputs": [ + "Final" + ] + }, + { + "name": "allow_token", + "inputs": [ + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + } + ], + "outputs": [ + "Final" + ] + }, + { + "name": "set_token_paused", + "inputs": [ + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Boolean" + }, + "mode": "Public" + } + } + ], + "outputs": [ + "Final" + ] + }, + { + "name": "set_pair_paused", + "inputs": [ + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Boolean" + }, + "mode": "Public" + } + } + ], + "outputs": [ + "Final" + ] + }, + { + "name": "freeze_position", + "inputs": [ + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + } + ], + "outputs": [ + "Final" + ] + }, + { + "name": "unfreeze_position", + "inputs": [ + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + } + ], + "outputs": [ + "Final" + ] + }, + { + "name": "set_fee_protocol", + "inputs": [ + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U8" + } + }, + "mode": "Public" + } + } + ], + "outputs": [ + "Final" + ] + }, + { + "name": "collect_protocol", + "inputs": [ + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Address" + }, + "mode": "Public" + } + } + ], + "outputs": [ + "Final" + ] + }, + { + "name": "create_pool", + "inputs": [ + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U16" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U32" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "Int": "I32" + } + }, + "mode": "Public" + } + } + ], + "outputs": [ + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Address" + }, + "mode": "Public" + } + }, + "Final" + ] + }, + { + "name": "mint", + "inputs": [ + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Private" + } + }, + "DynamicRecord", + "DynamicRecord", + { + "Plaintext": { + "ty": { + "Primitive": "Address" + }, + "mode": "Private" + } + }, + { + "Plaintext": { + "ty": { + "Struct": { + "path": [ + "MintPositionRequest" + ], + "program": "shield_swap_v3.aleo" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + } + ], + "outputs": [ + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + { + "Record": { + "path": [ + "PositionNFT" + ], + "program": "shield_swap_v3.aleo" + } + }, + "DynamicRecord", + "DynamicRecord", + { + "Record": { + "path": [ + "MintComplianceRecord" + ], + "program": "shield_swap_v3.aleo" + } + }, + "Final" + ] + }, + { + "name": "decrease_liquidity", + "inputs": [ + { + "Record": { + "path": [ + "PositionNFT" + ], + "program": "shield_swap_v3.aleo" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + } + ], + "outputs": [ + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + { + "Record": { + "path": [ + "PositionNFT" + ], + "program": "shield_swap_v3.aleo" + } + }, + "Final" + ] + }, + { + "name": "increase_liquidity", + "inputs": [ + { + "Record": { + "path": [ + "PositionNFT" + ], + "program": "shield_swap_v3.aleo" + } + }, + "DynamicRecord", + "DynamicRecord", + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "Int": "I32" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "Int": "I32" + } + }, + "mode": "Public" + } + } + ], + "outputs": [ + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + { + "Record": { + "path": [ + "PositionNFT" + ], + "program": "shield_swap_v3.aleo" + } + }, + "DynamicRecord", + "DynamicRecord", + "Final" + ] + }, + { + "name": "collect", + "inputs": [ + { + "Record": { + "path": [ + "PositionNFT" + ], + "program": "shield_swap_v3.aleo" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Address" + }, + "mode": "Private" + } + } + ], + "outputs": [ + { + "Record": { + "path": [ + "PositionNFT" + ], + "program": "shield_swap_v3.aleo" + } + }, + "DynamicRecord", + "DynamicRecord", + "Final" + ] + }, + { + "name": "burn", + "inputs": [ + { + "Record": { + "path": [ + "PositionNFT" + ], + "program": "shield_swap_v3.aleo" + } + } + ], + "outputs": [ + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Address" + }, + "mode": "Public" + } + }, + "Final" + ] + }, + { + "name": "swap", + "inputs": [ + "DynamicRecord", + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Private" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Address" + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Boolean" + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U64" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U32" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + } + ], + "outputs": [ + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + "DynamicRecord", + { + "Record": { + "path": [ + "SwapComplianceRecord" + ], + "program": "shield_swap_v3.aleo" + } + }, + "Final" + ] + }, + { + "name": "claim_swap_output", + "inputs": [ + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Private" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Address" + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + } + ], + "outputs": [ + "DynamicRecord", + "DynamicRecord", + "Final" + ] + }, + { + "name": "swap_multi_hop", + "inputs": [ + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Private" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Address" + }, + "mode": "Public" + } + }, + "DynamicRecord", + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Struct": { + "path": [ + "SwapHop" + ], + "program": "shield_swap_v3.aleo" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Struct": { + "path": [ + "SwapHop" + ], + "program": "shield_swap_v3.aleo" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Struct": { + "path": [ + "SwapHop" + ], + "program": "shield_swap_v3.aleo" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U8" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U64" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U32" + } + }, + "mode": "Public" + } + } + ], + "outputs": [ + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + "DynamicRecord", + { + "Record": { + "path": [ + "MultiHopSwapComplianceRecord" + ], + "program": "shield_swap_v3.aleo" + } + }, + "Final" + ] + }, + { + "name": "claim_multi_hop_output", + "inputs": [ + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Private" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Address" + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Field" + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + } + ], + "outputs": [ + "DynamicRecord", + "DynamicRecord", + "DynamicRecord", + "DynamicRecord", + "Final" + ] + } + ], + "views": [ + { + "name": "view_sqrt_price_at_tick", + "inputs": [ + { + "Plaintext": { + "ty": { + "Primitive": { + "Int": "I32" + } + }, + "mode": "Public" + } + } + ], + "outputs": [ + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + } + ] + }, + { + "name": "view_amounts_for_liquidity", + "inputs": [ + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": "Boolean" + }, + "mode": "Public" + } + } + ], + "outputs": [ + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + } + ] + }, + { + "name": "view_liquidity_for_amounts", + "inputs": [ + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + } + ], + "outputs": [ + { + "Plaintext": { + "ty": { + "Primitive": { + "UInt": "U128" + } + }, + "mode": "Public" + } + } + ] + }, + { + "name": "view_swap_iteration", + "inputs": [ + { + "Plaintext": { + "ty": { + "Struct": { + "path": [ + "SwapIterCfg" + ], + "program": "shield_swap_v3.aleo" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Primitive": { + "Int": "I32" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Struct": { + "path": [ + "Tick" + ], + "program": "shield_swap_v3.aleo" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Struct": { + "path": [ + "SwapIterState" + ], + "program": "shield_swap_v3.aleo" + } + }, + "mode": "Public" + } + } + ], + "outputs": [ + { + "Plaintext": { + "ty": { + "Struct": { + "path": [ + "SwapIterState" + ], + "program": "shield_swap_v3.aleo" + } + }, + "mode": "Public" + } + }, + { + "Plaintext": { + "ty": { + "Struct": { + "path": [ + "Tick" + ], + "program": "shield_swap_v3.aleo" + } + }, + "mode": "Public" + } + } + ] + } + ] +} \ No newline at end of file diff --git a/shield-swap-sdk/codegen/shield_swap.aleo b/shield-swap-sdk/codegen/shield_swap.aleo new file mode 100644 index 00000000..cadaba76 --- /dev/null +++ b/shield-swap-sdk/codegen/shield_swap.aleo @@ -0,0 +1,6437 @@ +import test_shield_swap_multisig_core.aleo; + +program shield_swap_v3.aleo; + +record PositionNFT: + owner as address.private; + token_id as field.private; + token0_id as field.private; + token1_id as field.private; + pool as field.private; + tick_lower as i32.private; + tick_upper as i32.private; + +struct SwapRequest: + pool as field; + zero_for_one as boolean; + amount_in as u128; + amount_out_min as u128; + sqrt_price_limit as u128; + recipient as address; + nonce as u64; + deadline as u32; + +record SwapComplianceRecord: + owner as address.private; + swap_id as field.private; + token_in as field.private; + token_out as field.private; + request as SwapRequest.private; + caller as address.private; + blinded_address as address.private; + +struct SwapHop: + pool as field; + zero_for_one as boolean; + sqrt_price_limit as u128; + +struct SwapMultiHopRequest: + token_in as field; + token_out as field; + amount_in as u128; + amount_out_min as u128; + recipient as address; + hop0 as SwapHop; + hop1 as SwapHop; + hop2 as SwapHop; + hop_count as u8; + nonce as u64; + deadline as u32; + caller as address; + +record MultiHopSwapComplianceRecord: + owner as address.private; + swap_id as field.private; + request as SwapMultiHopRequest.private; + caller as address.private; + blinded_address as address.private; + +struct MintPositionRequest: + pool as field; + tick_lower as i32; + tick_upper as i32; + amount0_desired as u128; + amount1_desired as u128; + amount0_min as u128; + amount1_min as u128; + tick_lower_hint as i32; + tick_upper_hint as i32; + +record MintComplianceRecord: + owner as address.private; + token_id as field.private; + token0_id as field.private; + token1_id as field.private; + request as MintPositionRequest.private; + caller as address.private; + recipient as address.private; + +struct ChecksumEdition: + checksum as [u8; 32u32]; + edition as u16; + +struct PoolState: + token0 as field; + token1 as field; + fee as u16; + enabled as boolean; + scale0 as u128; + scale1 as u128; + +struct Slot: + tick as i32; + tick_spacing as u32; + sqrt_price as u128; + fee_protocol as u8; + liquidity as u128; + fee_growth_global0_x_64 as u128; + fee_growth_global1_x_64 as u128; + fee_residual0_x_64 as u128; + fee_residual1_x_64 as u128; + max_liquidity_per_tick as u128; + protocol_fees0 as u128; + protocol_fees1 as u128; + next_init_below as i32; + next_init_above as i32; + +struct Tick: + pool as field; + liquidity_net as i128; + liquidity_gross as u128; + tick as i32; + fee_growth_outside0_64 as u128; + fee_growth_outside1_64 as u128; + prev as i32; + next as i32; + +struct Position: + token_id as field; + pool as field; + tick_lower as i32; + tick_upper as i32; + liquidity as u128; + fee_growth_inside0_last_64 as u128; + fee_growth_inside1_last_64 as u128; + tokens_owed0 as u128; + tokens_owed1 as u128; + +struct PoolKey: + token0 as field; + token1 as field; + fee as u16; + +struct PairKey: + token0 as field; + token1 as field; + +struct TickKey: + pool as field; + tick as i32; + +struct SwapKey: + pool as field; + zero_for_one as boolean; + amount_in as u128; + sqrt_price_limit as u128; + recipient as address; + nonce as u64; + caller as address; + +struct TokenIDPreimage: + request as MintPositionRequest; + recipient as address; + nonce as field; + +struct SwapIterCfg: + z as boolean; + lim as u128; + fee_pips as u32; + fee_protocol as u8; + slot_fg0 as u128; + slot_fg1 as u128; + +struct SwapIterState: + sp as u128; + rem as u128; + out as u128; + fg as u128; + liq as u128; + tk as i32; + crossed as boolean; + pf as u128; + nb as i32; + na as i32; + resid as u128; + +struct SwapOutput: + recipient as address; + caller as address; + token_in as field; + token_out as field; + amount_out as u128; + amount_remaining as u128; + token_in_1 as field; + amount_remaining_1 as u128; + token_in_2 as field; + amount_remaining_2 as u128; + +mapping pools: + key as field.public; + value as PoolState.public; + +mapping slots: + key as field.public; + value as Slot.public; + +mapping ticks: + key as field.public; + value as Tick.public; + +mapping initialized_pools: + key as field.public; + value as boolean.public; + +mapping tick_spacings: + key as u32.public; + value as boolean.public; + +mapping fee_tiers: + key as u16.public; + value as boolean.public; + +mapping fee_to_tick_spacing: + key as u16.public; + value as u32.public; + +mapping positions: + key as field.public; + value as Position.public; + +mapping swap_outputs: + key as field.public; + value as SwapOutput.public; + +mapping admin: + key as boolean.public; + value as address.public; + +mapping pending_admin: + key as boolean.public; + value as address.public; + +mapping used_blinded_addresses: + key as address.public; + value as boolean.public; + +mapping token_decimals: + key as field.public; + value as u8.public; + +mapping pool_creation_is_open: + key as boolean.public; + value as boolean.public; + +mapping global_paused: + key as boolean.public; + value as boolean.public; + +mapping token_allowed: + key as field.public; + value as boolean.public; + +mapping token_paused: + key as field.public; + value as boolean.public; + +mapping pair_paused: + key as PairKey.public; + value as boolean.public; + +mapping frozen_position: + key as field.public; + value as u32.public; + +function transfer_admin: + input r0 as address.public; + async transfer_admin self.caller r0 into r1; + output r1 as shield_swap_v3.aleo/transfer_admin.future; + +finalize transfer_admin: + input r0 as address.public; + input r1 as address.public; + get admin[true] into r2; + is.eq r0 r2 into r3; + assert.eq r3 true; + set r1 into pending_admin[true]; + +function accept_admin: + async accept_admin self.caller into r0; + output r0 as shield_swap_v3.aleo/accept_admin.future; + +finalize accept_admin: + input r0 as address.public; + get pending_admin[true] into r1; + is.eq r0 r1 into r2; + assert.eq r2 true; + set r0 into admin[true]; + remove pending_admin[true]; + +function add_tick_spacing: + input r0 as u32.public; + async add_tick_spacing self.caller r0 into r1; + output r1 as shield_swap_v3.aleo/add_tick_spacing.future; + +finalize add_tick_spacing: + input r0 as address.public; + input r1 as u32.public; + get admin[true] into r2; + is.eq r0 r2 into r3; + assert.eq r3 true; + gt r1 0u32 into r4; + assert.eq r4 true; + lte r1 400000u32 into r5; + assert.eq r5 true; + set true into tick_spacings[r1]; + +function add_fee_tier: + input r0 as u16.public; + async add_fee_tier self.caller r0 into r1; + output r1 as shield_swap_v3.aleo/add_fee_tier.future; + +finalize add_fee_tier: + input r0 as address.public; + input r1 as u16.public; + get admin[true] into r2; + is.eq r0 r2 into r3; + assert.eq r3 true; + set true into fee_tiers[r1]; + +function bind_fee_to_tick_spacing: + input r0 as u16.public; + input r1 as u32.public; + async bind_fee_to_tick_spacing self.caller r0 r1 into r2; + output r2 as shield_swap_v3.aleo/bind_fee_to_tick_spacing.future; + +finalize bind_fee_to_tick_spacing: + input r0 as address.public; + input r1 as u16.public; + input r2 as u32.public; + get admin[true] into r3; + is.eq r0 r3 into r4; + assert.eq r4 true; + get.or_use fee_tiers[r1] false into r5; + assert.eq r5 true; + get.or_use tick_spacings[r2] false into r6; + assert.eq r6 true; + set r2 into fee_to_tick_spacing[r1]; + +function set_token_decimals: + input r0 as field.public; + input r1 as u8.public; + async set_token_decimals self.caller r1 r0 into r2; + output r2 as shield_swap_v3.aleo/set_token_decimals.future; + +finalize set_token_decimals: + input r0 as address.public; + input r1 as u8.public; + input r2 as field.public; + get admin[true] into r3; + is.eq r0 r3 into r4; + assert.eq r4 true; + lte r1 18u8 into r5; + assert.eq r5 true; + contains token_decimals[r2] into r6; + not r6 into r7; + assert.eq r7 true; + set r1 into token_decimals[r2]; + +function set_pool_enabled: + input r0 as field.public; + input r1 as boolean.public; + async set_pool_enabled self.caller r0 r1 into r2; + output r2 as shield_swap_v3.aleo/set_pool_enabled.future; + +finalize set_pool_enabled: + input r0 as address.public; + input r1 as field.public; + input r2 as boolean.public; + get admin[true] into r3; + is.eq r0 r3 into r4; + assert.eq r4 true; + get pools[r1] into r5; + cast r5.token0 r5.token1 r5.fee r2 r5.scale0 r5.scale1 into r6 as PoolState; + set r6 into pools[r1]; + +function set_pool_creation_is_open: + input r0 as boolean.public; + async set_pool_creation_is_open self.caller r0 into r1; + output r1 as shield_swap_v3.aleo/set_pool_creation_is_open.future; + +finalize set_pool_creation_is_open: + input r0 as address.public; + input r1 as boolean.public; + get admin[true] into r2; + is.eq r0 r2 into r3; + assert.eq r3 true; + set r1 into pool_creation_is_open[true]; + +function set_global_paused: + input r0 as boolean.public; + async set_global_paused self.caller r0 into r1; + output r1 as shield_swap_v3.aleo/set_global_paused.future; + +finalize set_global_paused: + input r0 as address.public; + input r1 as boolean.public; + get admin[true] into r2; + is.eq r0 r2 into r3; + assert.eq r3 true; + set r1 into global_paused[true]; + +function allow_token: + input r0 as field.public; + async allow_token self.caller r0 into r1; + output r1 as shield_swap_v3.aleo/allow_token.future; + +finalize allow_token: + input r0 as address.public; + input r1 as field.public; + get admin[true] into r2; + is.eq r0 r2 into r3; + assert.eq r3 true; + set true into token_allowed[r1]; + +function set_token_paused: + input r0 as field.public; + input r1 as boolean.public; + async set_token_paused self.caller r0 r1 into r2; + output r2 as shield_swap_v3.aleo/set_token_paused.future; + +finalize set_token_paused: + input r0 as address.public; + input r1 as field.public; + input r2 as boolean.public; + get admin[true] into r3; + is.eq r0 r3 into r4; + assert.eq r4 true; + set r2 into token_paused[r1]; + +function set_pair_paused: + input r0 as field.public; + input r1 as field.public; + input r2 as boolean.public; + lt r0 r1 into r3; + ternary r3 r0 r1 into r4; + ternary r3 r1 r0 into r5; + cast r4 r5 into r6 as PairKey; + async set_pair_paused self.caller r6 r2 into r7; + output r7 as shield_swap_v3.aleo/set_pair_paused.future; + +finalize set_pair_paused: + input r0 as address.public; + input r1 as PairKey.public; + input r2 as boolean.public; + get admin[true] into r3; + is.eq r0 r3 into r4; + assert.eq r4 true; + set r2 into pair_paused[r1]; + +view view_sqrt_price_at_tick: + input r0 as i32.public; + gte r0 -873409i32 into r1; + lte r0 873409i32 into r2; + and r1 r2 into r3; + assert.eq r3 true; + lt r0 0i32 into r4; + sub 0i32 r0 into r5; + ternary r4 r5 r0 into r6; + gte r6 0i32 into r7; + assert.eq r7 true; + cast r6 into r8 as u32; + and r8 3u32 into r9; + is.eq r9 0u32 into r10; + is.eq r9 1u32 into r11; + is.eq r9 2u32 into r12; + ternary r12 9222449791875588096u128 9221988703967300608u128 into r13; + ternary r11 9222910902837697536u128 r13 into r14; + ternary r10 9223372036854775808u128 r14 into r15; + and r8 4u32 into r16; + is.neq r16 0u32 into r17; + mul r15 9221527639111677952u128 into r18; + shr r18 63u8 into r19; + ternary r17 r19 r15 into r20; + and r8 8u32 into r21; + is.neq r21 0u32 into r22; + mul r20 9219683610192801792u128 into r23; + shr r23 63u8 into r24; + ternary r22 r24 r20 into r25; + and r8 16u32 into r26; + is.neq r26 0u32 into r27; + mul r25 9215996658532725760u128 into r28; + shr r28 63u8 into r29; + ternary r27 r29 r25 into r30; + and r8 32u32 into r31; + is.neq r31 0u32 into r32; + mul r30 9208627177859081216u128 into r33; + shr r33 63u8 into r34; + ternary r32 r34 r30 into r35; + and r8 64u32 into r36; + is.neq r36 0u32 into r37; + mul r35 9193905890596798464u128 into r38; + shr r38 63u8 into r39; + ternary r37 r39 r35 into r40; + and r8 128u32 into r41; + is.neq r41 0u32 into r42; + mul r40 9164533880601766912u128 into r43; + shr r43 63u8 into r44; + ternary r42 r44 r40 into r45; + and r8 256u32 into r46; + is.neq r46 0u32 into r47; + mul r45 9106071067403056128u128 into r48; + shr r48 63u8 into r49; + ternary r47 r49 r45 into r50; + and r8 512u32 into r51; + is.neq r51 0u32 into r52; + mul r50 8990261907820801024u128 into r53; + shr r53 63u8 into r54; + ternary r52 r54 r50 into r55; + and r8 1024u32 into r56; + is.neq r56 0u32 into r57; + mul r55 8763043369415622656u128 into r58; + shr r58 63u8 into r59; + ternary r57 r59 r55 into r60; + and r8 2048u32 into r61; + is.neq r61 0u32 into r62; + mul r60 8325689215117605888u128 into r63; + shr r63 63u8 into r64; + ternary r62 r64 r60 into r65; + and r8 4096u32 into r66; + is.neq r66 0u32 into r67; + mul r65 7515375139346884608u128 into r68; + shr r68 63u8 into r69; + ternary r67 r69 r65 into r70; + and r8 8192u32 into r71; + is.neq r71 0u32 into r72; + mul r70 6123667489441693696u128 into r73; + shr r73 63u8 into r74; + ternary r72 r74 r70 into r75; + and r8 16384u32 into r76; + is.neq r76 0u32 into r77; + mul r75 4065682634442729984u128 into r78; + shr r78 63u8 into r79; + ternary r77 r79 r75 into r80; + and r8 32768u32 into r81; + is.neq r81 0u32 into r82; + mul r80 1792161827361994496u128 into r83; + shr r83 63u8 into r84; + ternary r82 r84 r80 into r85; + and r8 65536u32 into r86; + is.neq r86 0u32 into r87; + mul r85 348228825923923264u128 into r88; + shr r88 63u8 into r89; + ternary r87 r89 r85 into r90; + and r8 131072u32 into r91; + is.neq r91 0u32 into r92; + mul r90 13147394978735516u128 into r93; + shr r93 63u8 into r94; + ternary r92 r94 r90 into r95; + and r8 262144u32 into r96; + is.neq r96 0u32 into r97; + mul r95 18740867660568u128 into r98; + shr r98 63u8 into r99; + ternary r97 r99 r95 into r100; + and r8 524288u32 into r101; + is.neq r101 0u32 into r102; + mul r100 38079361u128 into r103; + shr r103 63u8 into r104; + ternary r102 r104 r100 into r105; + gt r0 0i32 into r106; + div 85070591730234615865843651857942052864u128 r105 into r107; + ternary r106 r107 r105 into r108; + output r108 as u128.public; + +view view_amounts_for_liquidity: + input r0 as u128.public; + input r1 as u128.public; + input r2 as u128.public; + input r3 as u128.public; + input r4 as boolean.public; + gt r1 r2 into r5; + ternary r5 r2 r1 into r6; + ternary r5 r1 r2 into r7; + lte r0 r6 into r8; + gt r6 r7 into r9; + ternary r9 r7 r6 into r10; + ternary r9 r6 r7 into r11; + and r3 18446744073709551615u128 into r12; + shr r3 64u8 into r13; + mul r12 9223372036854775808u128 into r14; + mul r13 9223372036854775808u128 into r15; + and r14 18446744073709551615u128 into r16; + shr r14 64u8 into r17; + and r15 18446744073709551615u128 into r18; + add r17 r18 into r19; + and r19 18446744073709551615u128 into r20; + shr r19 64u8 into r21; + shr r15 64u8 into r22; + add r22 r21 into r23; + and r23 18446744073709551615u128 into r24; + shr r23 64u8 into r25; + shl r20 64u8 into r26; + add r26 r16 into r27; + shl r25 64u8 into r28; + add r28 r24 into r29; + lt r29 r10 into r30; + assert.eq r30 true; + shr r27 96u8 into r31; + and r31 4294967295u128 into r32; + shl r29 32u8 into r33; + add r33 r32 into r34; + div r34 r10 into r35; + rem r34 r10 into r36; + shr r27 64u8 into r37; + and r37 4294967295u128 into r38; + shl r36 32u8 into r39; + add r39 r38 into r40; + shl r35 32u8 into r41; + div r40 r10 into r42; + add r41 r42 into r43; + rem r40 r10 into r44; + shr r27 32u8 into r45; + and r45 4294967295u128 into r46; + shl r44 32u8 into r47; + add r47 r46 into r48; + shl r43 32u8 into r49; + div r48 r10 into r50; + add r49 r50 into r51; + rem r48 r10 into r52; + shr r27 0u8 into r53; + and r53 4294967295u128 into r54; + shl r52 32u8 into r55; + add r55 r54 into r56; + shl r51 32u8 into r57; + div r56 r10 into r58; + add r57 r58 into r59; + rem r56 r10 into r60; + gt r60 0u128 into r61; + and r4 r61 into r62; + add r59 1u128 into r63; + ternary r62 r63 r59 into r64; + not r4 into r65; + add r17 r18 into r66; + and r66 18446744073709551615u128 into r67; + shr r66 64u8 into r68; + add r22 r68 into r69; + and r69 18446744073709551615u128 into r70; + shr r69 64u8 into r71; + shl r67 64u8 into r72; + add r72 r16 into r73; + shl r71 64u8 into r74; + add r74 r70 into r75; + lt r75 r11 into r76; + assert.eq r76 true; + shr r73 96u8 into r77; + and r77 4294967295u128 into r78; + shl r75 32u8 into r79; + add r79 r78 into r80; + div r80 r11 into r81; + rem r80 r11 into r82; + shr r73 64u8 into r83; + and r83 4294967295u128 into r84; + shl r82 32u8 into r85; + add r85 r84 into r86; + shl r81 32u8 into r87; + div r86 r11 into r88; + add r87 r88 into r89; + rem r86 r11 into r90; + shr r73 32u8 into r91; + and r91 4294967295u128 into r92; + shl r90 32u8 into r93; + add r93 r92 into r94; + shl r89 32u8 into r95; + div r94 r11 into r96; + add r95 r96 into r97; + rem r94 r11 into r98; + shr r73 0u8 into r99; + and r99 4294967295u128 into r100; + shl r98 32u8 into r101; + add r101 r100 into r102; + shl r97 32u8 into r103; + div r102 r11 into r104; + add r103 r104 into r105; + rem r102 r11 into r106; + gt r106 0u128 into r107; + and r65 r107 into r108; + add r105 1u128 into r109; + ternary r108 r109 r105 into r110; + gte r64 r110 into r111; + ternary r111 r64 r110 into r112; + ternary r111 r110 r64 into r113; + sub r112 r113 into r114; + ternary r111 r114 0u128 into r115; + lt r0 r7 into r116; + gt r0 r7 into r117; + ternary r117 r7 r0 into r118; + ternary r117 r0 r7 into r119; + shl r71 64u8 into r120; + add r120 r70 into r121; + lt r121 r118 into r122; + assert.eq r122 true; + shl r121 32u8 into r123; + add r123 r78 into r124; + div r124 r118 into r125; + rem r124 r118 into r126; + shl r126 32u8 into r127; + add r127 r84 into r128; + shl r125 32u8 into r129; + div r128 r118 into r130; + add r129 r130 into r131; + rem r128 r118 into r132; + shl r132 32u8 into r133; + add r133 r92 into r134; + shl r131 32u8 into r135; + div r134 r118 into r136; + add r135 r136 into r137; + rem r134 r118 into r138; + shl r138 32u8 into r139; + add r139 r100 into r140; + shl r137 32u8 into r141; + div r140 r118 into r142; + add r141 r142 into r143; + rem r140 r118 into r144; + gt r144 0u128 into r145; + and r4 r145 into r146; + add r143 1u128 into r147; + ternary r146 r147 r143 into r148; + lt r121 r119 into r149; + assert.eq r149 true; + shl r121 32u8 into r150; + add r150 r78 into r151; + div r151 r119 into r152; + rem r151 r119 into r153; + shl r153 32u8 into r154; + add r154 r84 into r155; + shl r152 32u8 into r156; + div r155 r119 into r157; + add r156 r157 into r158; + rem r155 r119 into r159; + shl r159 32u8 into r160; + add r160 r92 into r161; + shl r158 32u8 into r162; + div r161 r119 into r163; + add r162 r163 into r164; + rem r161 r119 into r165; + shl r165 32u8 into r166; + add r166 r100 into r167; + shl r164 32u8 into r168; + div r167 r119 into r169; + add r168 r169 into r170; + rem r167 r119 into r171; + gt r171 0u128 into r172; + and r65 r172 into r173; + add r170 1u128 into r174; + ternary r173 r174 r170 into r175; + gte r148 r175 into r176; + ternary r176 r148 r175 into r177; + ternary r176 r175 r148 into r178; + sub r177 r178 into r179; + ternary r176 r179 0u128 into r180; + gt r6 r0 into r181; + ternary r181 r0 r6 into r182; + ternary r181 r6 r0 into r183; + sub r183 r182 into r184; + and r184 18446744073709551615u128 into r185; + shr r184 64u8 into r186; + mul r12 r185 into r187; + mul r12 r186 into r188; + mul r13 r185 into r189; + mul r13 r186 into r190; + and r187 18446744073709551615u128 into r191; + shr r187 64u8 into r192; + and r188 18446744073709551615u128 into r193; + add r192 r193 into r194; + and r189 18446744073709551615u128 into r195; + add r194 r195 into r196; + and r196 18446744073709551615u128 into r197; + shr r196 64u8 into r198; + shr r188 64u8 into r199; + shr r189 64u8 into r200; + add r199 r200 into r201; + and r190 18446744073709551615u128 into r202; + add r201 r202 into r203; + add r203 r198 into r204; + and r204 18446744073709551615u128 into r205; + shr r204 64u8 into r206; + shr r190 64u8 into r207; + add r207 r206 into r208; + shl r197 64u8 into r209; + add r209 r191 into r210; + shl r208 64u8 into r211; + add r211 r205 into r212; + shl r212 65u8 into r213; + shr r210 63u8 into r214; + add r213 r214 into r215; + and r210 9223372036854775807u128 into r216; + gt r216 0u128 into r217; + and r4 r217 into r218; + add r215 1u128 into r219; + ternary r218 r219 r215 into r220; + gt r6 r7 into r221; + ternary r221 r7 r6 into r222; + ternary r221 r6 r7 into r223; + sub r223 r222 into r224; + and r224 18446744073709551615u128 into r225; + shr r224 64u8 into r226; + mul r12 r225 into r227; + mul r12 r226 into r228; + mul r13 r225 into r229; + mul r13 r226 into r230; + and r227 18446744073709551615u128 into r231; + shr r227 64u8 into r232; + and r228 18446744073709551615u128 into r233; + add r232 r233 into r234; + and r229 18446744073709551615u128 into r235; + add r234 r235 into r236; + and r236 18446744073709551615u128 into r237; + shr r236 64u8 into r238; + shr r228 64u8 into r239; + shr r229 64u8 into r240; + add r239 r240 into r241; + and r230 18446744073709551615u128 into r242; + add r241 r242 into r243; + add r243 r238 into r244; + and r244 18446744073709551615u128 into r245; + shr r244 64u8 into r246; + shr r230 64u8 into r247; + add r247 r246 into r248; + shl r237 64u8 into r249; + add r249 r231 into r250; + shl r248 64u8 into r251; + add r251 r245 into r252; + shl r252 65u8 into r253; + shr r250 63u8 into r254; + add r253 r254 into r255; + and r250 9223372036854775807u128 into r256; + gt r256 0u128 into r257; + and r4 r257 into r258; + add r255 1u128 into r259; + ternary r258 r259 r255 into r260; + ternary r116 r180 0u128 into r261; + ternary r116 r220 r260 into r262; + ternary r8 r115 r261 into r263; + ternary r8 0u128 r262 into r264; + output r263 as u128.public; + output r264 as u128.public; + +function freeze_position: + input r0 as field.public; + async freeze_position self.caller r0 into r1; + output r1 as shield_swap_v3.aleo/freeze_position.future; + +finalize freeze_position: + input r0 as address.public; + input r1 as field.public; + get admin[true] into r2; + is.eq r0 r2 into r3; + assert.eq r3 true; + contains positions[r1] into r4; + assert.eq r4 true; + contains frozen_position[r1] into r5; + not r5 into r6; + assert.eq r6 true; + get positions[r1] into r7; + gt r7.liquidity 0u128 into r8; + branch.eq r8 false to end_then_0_0; + get positions[r1] into r9; + get slots[r9.pool] into r10; + call view_sqrt_price_at_tick r9.tick_lower into r11; + call view_sqrt_price_at_tick r9.tick_upper into r12; + call view_amounts_for_liquidity r10.sqrt_price r11 r12 r7.liquidity false into r13 r14; + cast r9.pool r9.tick_lower into r15 as TickKey; + hash.bhp256 r15 into r16 as field; + cast r9.pool r9.tick_upper into r17 as TickKey; + hash.bhp256 r17 into r18 as field; + get ticks[r16] into r19; + get ticks[r18] into r20; + gt r19.liquidity_gross 0u128 into r21; + gt r20.liquidity_gross 0u128 into r22; + sub r19.liquidity_gross r7.liquidity into r23; + sub r20.liquidity_gross r7.liquidity into r24; + is.eq r23 0u128 into r25; + and r21 r25 into r26; + is.eq r24 0u128 into r27; + and r22 r27 into r28; + cast r7.liquidity into r29 as i128; + sub r19.liquidity_net r29 into r30; + cast r19.pool r30 r23 r19.tick r19.fee_growth_outside0_64 r19.fee_growth_outside1_64 r19.prev r19.next into r31 as Tick; + set r31 into ticks[r16]; + branch.eq r26 false to end_then_1_2; + cast r9.pool r19.prev into r32 as TickKey; + hash.bhp256 r32 into r33 as field; + get ticks[r33] into r34; + cast r34.pool r34.liquidity_net r34.liquidity_gross r34.tick r34.fee_growth_outside0_64 r34.fee_growth_outside1_64 r34.prev r19.next into r35 as Tick; + set r35 into ticks[r33]; + cast r9.pool r19.next into r36 as TickKey; + hash.bhp256 r36 into r37 as field; + get ticks[r37] into r38; + cast r38.pool r38.liquidity_net r38.liquidity_gross r38.tick r38.fee_growth_outside0_64 r38.fee_growth_outside1_64 r19.prev r38.next into r39 as Tick; + set r39 into ticks[r37]; + branch.eq true true to end_otherwise_1_3; + position end_then_1_2; + position end_otherwise_1_3; + get ticks[r18] into r40; + cast r7.liquidity into r41 as i128; + add r40.liquidity_net r41 into r42; + cast r40.pool r42 r24 r40.tick r40.fee_growth_outside0_64 r40.fee_growth_outside1_64 r40.prev r40.next into r43 as Tick; + set r43 into ticks[r18]; + branch.eq r28 false to end_then_1_4; + cast r9.pool r40.prev into r44 as TickKey; + hash.bhp256 r44 into r45 as field; + get ticks[r45] into r46; + cast r46.pool r46.liquidity_net r46.liquidity_gross r46.tick r46.fee_growth_outside0_64 r46.fee_growth_outside1_64 r46.prev r40.next into r47 as Tick; + set r47 into ticks[r45]; + cast r9.pool r40.next into r48 as TickKey; + hash.bhp256 r48 into r49 as field; + get ticks[r49] into r50; + cast r50.pool r50.liquidity_net r50.liquidity_gross r50.tick r50.fee_growth_outside0_64 r50.fee_growth_outside1_64 r40.prev r50.next into r51 as Tick; + set r51 into ticks[r49]; + branch.eq true true to end_otherwise_1_5; + position end_then_1_4; + position end_otherwise_1_5; + get ticks[r16] into r52; + get ticks[r18] into r53; + gte r10.tick r52.tick into r54; + gte r10.fee_growth_global0_x_64 r52.fee_growth_outside0_64 into r55; + ternary r55 r10.fee_growth_global0_x_64 r52.fee_growth_outside0_64 into r56; + ternary r55 r52.fee_growth_outside0_64 r10.fee_growth_global0_x_64 into r57; + sub r56 r57 into r58; + gt r58 0u128 into r59; + ternary r59 r58 1u128 into r60; + sub 340282366920938463463374607431768211455u128 r60 into r61; + add r61 1u128 into r62; + ternary r55 r58 r62 into r63; + gte r10.fee_growth_global1_x_64 r52.fee_growth_outside1_64 into r64; + ternary r64 r10.fee_growth_global1_x_64 r52.fee_growth_outside1_64 into r65; + ternary r64 r52.fee_growth_outside1_64 r10.fee_growth_global1_x_64 into r66; + sub r65 r66 into r67; + gt r67 0u128 into r68; + ternary r68 r67 1u128 into r69; + sub 340282366920938463463374607431768211455u128 r69 into r70; + add r70 1u128 into r71; + ternary r64 r67 r71 into r72; + ternary r54 r52.fee_growth_outside0_64 r63 into r73; + ternary r54 r52.fee_growth_outside1_64 r72 into r74; + lt r10.tick r53.tick into r75; + gte r10.fee_growth_global0_x_64 r53.fee_growth_outside0_64 into r76; + ternary r76 r10.fee_growth_global0_x_64 r53.fee_growth_outside0_64 into r77; + ternary r76 r53.fee_growth_outside0_64 r10.fee_growth_global0_x_64 into r78; + sub r77 r78 into r79; + gt r79 0u128 into r80; + ternary r80 r79 1u128 into r81; + sub 340282366920938463463374607431768211455u128 r81 into r82; + add r82 1u128 into r83; + ternary r76 r79 r83 into r84; + gte r10.fee_growth_global1_x_64 r53.fee_growth_outside1_64 into r85; + ternary r85 r10.fee_growth_global1_x_64 r53.fee_growth_outside1_64 into r86; + ternary r85 r53.fee_growth_outside1_64 r10.fee_growth_global1_x_64 into r87; + sub r86 r87 into r88; + gt r88 0u128 into r89; + ternary r89 r88 1u128 into r90; + sub 340282366920938463463374607431768211455u128 r90 into r91; + add r91 1u128 into r92; + ternary r85 r88 r92 into r93; + ternary r75 r53.fee_growth_outside0_64 r84 into r94; + ternary r75 r53.fee_growth_outside1_64 r93 into r95; + gte r10.fee_growth_global0_x_64 r73 into r96; + ternary r96 r10.fee_growth_global0_x_64 r73 into r97; + ternary r96 r73 r10.fee_growth_global0_x_64 into r98; + sub r97 r98 into r99; + gt r99 0u128 into r100; + ternary r100 r99 1u128 into r101; + sub 340282366920938463463374607431768211455u128 r101 into r102; + add r102 1u128 into r103; + ternary r96 r99 r103 into r104; + gte r104 r94 into r105; + ternary r105 r104 r94 into r106; + ternary r105 r94 r104 into r107; + sub r106 r107 into r108; + gt r108 0u128 into r109; + ternary r109 r108 1u128 into r110; + sub 340282366920938463463374607431768211455u128 r110 into r111; + add r111 1u128 into r112; + ternary r105 r108 r112 into r113; + gte r10.fee_growth_global1_x_64 r74 into r114; + ternary r114 r10.fee_growth_global1_x_64 r74 into r115; + ternary r114 r74 r10.fee_growth_global1_x_64 into r116; + sub r115 r116 into r117; + gt r117 0u128 into r118; + ternary r118 r117 1u128 into r119; + sub 340282366920938463463374607431768211455u128 r119 into r120; + add r120 1u128 into r121; + ternary r114 r117 r121 into r122; + gte r122 r95 into r123; + ternary r123 r122 r95 into r124; + ternary r123 r95 r122 into r125; + sub r124 r125 into r126; + gt r126 0u128 into r127; + ternary r127 r126 1u128 into r128; + sub 340282366920938463463374607431768211455u128 r128 into r129; + add r129 1u128 into r130; + ternary r123 r126 r130 into r131; + gte r113 r9.fee_growth_inside0_last_64 into r132; + ternary r132 r113 r9.fee_growth_inside0_last_64 into r133; + ternary r132 r9.fee_growth_inside0_last_64 r113 into r134; + sub r133 r134 into r135; + gt r135 0u128 into r136; + ternary r136 r135 1u128 into r137; + sub 340282366920938463463374607431768211455u128 r137 into r138; + add r138 1u128 into r139; + ternary r132 r135 r139 into r140; + and r140 18446744073709551615u128 into r141; + shr r140 64u8 into r142; + and r9.liquidity 18446744073709551615u128 into r143; + shr r9.liquidity 64u8 into r144; + mul r141 r143 into r145; + mul r141 r144 into r146; + mul r142 r143 into r147; + mul r142 r144 into r148; + and r145 18446744073709551615u128 into r149; + shr r145 64u8 into r150; + and r146 18446744073709551615u128 into r151; + add r150 r151 into r152; + and r147 18446744073709551615u128 into r153; + add r152 r153 into r154; + and r154 18446744073709551615u128 into r155; + shr r154 64u8 into r156; + shr r146 64u8 into r157; + shr r147 64u8 into r158; + add r157 r158 into r159; + and r148 18446744073709551615u128 into r160; + add r159 r160 into r161; + add r161 r156 into r162; + and r162 18446744073709551615u128 into r163; + shr r162 64u8 into r164; + shr r148 64u8 into r165; + add r165 r164 into r166; + shl r155 64u8 into r167; + add r167 r149 into r168; + shl r166 64u8 into r169; + add r169 r163 into r170; + shl r170 65u8 into r171; + shr r168 63u8 into r172; + add r171 r172 into r173; + add r9.tokens_owed0 r173 into r174; + add r174 r13 into r175; + gte r131 r9.fee_growth_inside1_last_64 into r176; + ternary r176 r131 r9.fee_growth_inside1_last_64 into r177; + ternary r176 r9.fee_growth_inside1_last_64 r131 into r178; + sub r177 r178 into r179; + gt r179 0u128 into r180; + ternary r180 r179 1u128 into r181; + sub 340282366920938463463374607431768211455u128 r181 into r182; + add r182 1u128 into r183; + ternary r176 r179 r183 into r184; + and r184 18446744073709551615u128 into r185; + shr r184 64u8 into r186; + and r9.liquidity 18446744073709551615u128 into r187; + shr r9.liquidity 64u8 into r188; + mul r185 r187 into r189; + mul r185 r188 into r190; + mul r186 r187 into r191; + mul r186 r188 into r192; + and r189 18446744073709551615u128 into r193; + shr r189 64u8 into r194; + and r190 18446744073709551615u128 into r195; + add r194 r195 into r196; + and r191 18446744073709551615u128 into r197; + add r196 r197 into r198; + and r198 18446744073709551615u128 into r199; + shr r198 64u8 into r200; + shr r190 64u8 into r201; + shr r191 64u8 into r202; + add r201 r202 into r203; + and r192 18446744073709551615u128 into r204; + add r203 r204 into r205; + add r205 r200 into r206; + and r206 18446744073709551615u128 into r207; + shr r206 64u8 into r208; + shr r192 64u8 into r209; + add r209 r208 into r210; + shl r199 64u8 into r211; + add r211 r193 into r212; + shl r210 64u8 into r213; + add r213 r207 into r214; + shl r214 65u8 into r215; + shr r212 63u8 into r216; + add r215 r216 into r217; + add r9.tokens_owed1 r217 into r218; + add r218 r14 into r219; + sub r9.liquidity r7.liquidity into r220; + cast r1 r9.pool r9.tick_lower r9.tick_upper r220 r113 r131 r175 r219 into r221 as Position; + set r221 into positions[r1]; + is.eq r10.next_init_below r9.tick_lower into r222; + and r26 r222 into r223; + ternary r223 r19.prev r10.next_init_below into r224; + is.eq r10.next_init_above r9.tick_lower into r225; + and r26 r225 into r226; + ternary r226 r19.next r10.next_init_above into r227; + is.eq r224 r9.tick_upper into r228; + and r28 r228 into r229; + ternary r229 r40.prev r224 into r230; + is.eq r227 r9.tick_upper into r231; + and r28 r231 into r232; + ternary r232 r40.next r227 into r233; + gte r10.tick r9.tick_lower into r234; + lt r10.tick r9.tick_upper into r235; + and r234 r235 into r236; + ternary r236 r7.liquidity 0u128 into r237; + sub r10.liquidity r237 into r238; + cast r10.tick r10.tick_spacing r10.sqrt_price r10.fee_protocol r238 r10.fee_growth_global0_x_64 r10.fee_growth_global1_x_64 r10.fee_residual0_x_64 r10.fee_residual1_x_64 r10.max_liquidity_per_tick r10.protocol_fees0 r10.protocol_fees1 r230 r233 into r239 as Slot; + set r239 into slots[r9.pool]; + branch.eq r26 false to end_then_1_6; + remove ticks[r16]; + branch.eq true true to end_otherwise_1_7; + position end_then_1_6; + position end_otherwise_1_7; + branch.eq r28 false to end_then_1_8; + remove ticks[r18]; + branch.eq true true to end_otherwise_1_9; + position end_then_1_8; + position end_otherwise_1_9; + branch.eq true true to end_otherwise_0_1; + position end_then_0_0; + position end_otherwise_0_1; + set block.height into frozen_position[r1]; + +function unfreeze_position: + input r0 as field.public; + async unfreeze_position self.caller r0 into r1; + output r1 as shield_swap_v3.aleo/unfreeze_position.future; + +finalize unfreeze_position: + input r0 as address.public; + input r1 as field.public; + get admin[true] into r2; + is.eq r0 r2 into r3; + assert.eq r3 true; + contains frozen_position[r1] into r4; + assert.eq r4 true; + remove frozen_position[r1]; + +function set_fee_protocol: + input r0 as field.public; + input r1 as u8.public; + async set_fee_protocol self.caller r0 r1 into r2; + output r2 as shield_swap_v3.aleo/set_fee_protocol.future; + +finalize set_fee_protocol: + input r0 as address.public; + input r1 as field.public; + input r2 as u8.public; + get admin[true] into r3; + is.eq r0 r3 into r4; + assert.eq r4 true; + is.eq r2 0u8 into r5; + gte r2 4u8 into r6; + lte r2 10u8 into r7; + and r6 r7 into r8; + or r5 r8 into r9; + assert.eq r9 true; + get slots[r1] into r10; + cast r10.tick r10.tick_spacing r10.sqrt_price r2 r10.liquidity r10.fee_growth_global0_x_64 r10.fee_growth_global1_x_64 r10.fee_residual0_x_64 r10.fee_residual1_x_64 r10.max_liquidity_per_tick r10.protocol_fees0 r10.protocol_fees1 r10.next_init_below r10.next_init_above into r11 as Slot; + set r11 into slots[r1]; + +function collect_protocol: + input r0 as field.public; + input r1 as u128.public; + input r2 as u128.public; + input r3 as field.public; + input r4 as field.public; + input r5 as address.public; + assert.neq r5 shield_swap_v3.aleo; + call.dynamic r3 'aleo' 'transfer_public' with r5 r1 (as address.public u128.public) into r6 (as dynamic.future); + call.dynamic r4 'aleo' 'transfer_public' with r5 r2 (as address.public u128.public) into r7 (as dynamic.future); + async collect_protocol r6 r7 self.caller r0 r1 r2 r3 r4 into r8; + output r8 as shield_swap_v3.aleo/collect_protocol.future; + +finalize collect_protocol: + input r0 as dynamic.future; + input r1 as dynamic.future; + input r2 as address.public; + input r3 as field.public; + input r4 as u128.public; + input r5 as u128.public; + input r6 as field.public; + input r7 as field.public; + get admin[true] into r8; + is.eq r2 r8 into r9; + assert.eq r9 true; + get pools[r3] into r10; + is.eq r10.token0 r6 into r11; + is.eq r10.token1 r7 into r12; + and r11 r12 into r13; + assert.eq r13 true; + get slots[r3] into r14; + rem r4 r10.scale0 into r15; + is.eq r15 0u128 into r16; + rem r5 r10.scale1 into r17; + is.eq r17 0u128 into r18; + and r16 r18 into r19; + assert.eq r19 true; + div r4 r10.scale0 into r20; + div r5 r10.scale1 into r21; + lte r20 r14.protocol_fees0 into r22; + assert.eq r22 true; + lte r21 r14.protocol_fees1 into r23; + assert.eq r23 true; + await r0; + await r1; + sub r14.protocol_fees0 r20 into r24; + sub r14.protocol_fees1 r21 into r25; + cast r14.tick r14.tick_spacing r14.sqrt_price r14.fee_protocol r14.liquidity r14.fee_growth_global0_x_64 r14.fee_growth_global1_x_64 r14.fee_residual0_x_64 r14.fee_residual1_x_64 r14.max_liquidity_per_tick r24 r25 r14.next_init_below r14.next_init_above into r26 as Slot; + set r26 into slots[r3]; + +function create_pool: + input r0 as field.public; + input r1 as field.public; + input r2 as u16.public; + input r3 as u128.public; + input r4 as u32.public; + input r5 as i32.public; + lt r0 r1 into r6; + ternary r6 r0 r1 into r7; + ternary r6 r1 r0 into r8; + cast r7 r8 r2 into r9 as PoolKey; + hash.bhp256 r9 into r10 as field; + async create_pool self.caller r0 r1 r2 r3 r4 r5 into r11; + output r10 as field.public; + output self.signer as address.public; + output r11 as shield_swap_v3.aleo/create_pool.future; + +finalize create_pool: + input r0 as address.public; + input r1 as field.public; + input r2 as field.public; + input r3 as u16.public; + input r4 as u128.public; + input r5 as u32.public; + input r6 as i32.public; + get.or_use pool_creation_is_open[true] false into r7; + get admin[true] into r8; + is.eq r0 r8 into r9; + or r7 r9 into r10; + assert.eq r10 true; + get.or_use token_allowed[r1] false into r11; + assert.eq r11 true; + get.or_use token_allowed[r2] false into r12; + assert.eq r12 true; + get.or_use global_paused[true] false into r13; + not r13 into r14; + assert.eq r14 true; + get token_decimals[r1] into r15; + get token_decimals[r2] into r16; + lt r1 r2 into r17; + ternary r17 r1 r2 into r18; + ternary r17 r2 r1 into r19; + lt r1 r2 into r20; + ternary r20 r15 r16 into r21; + ternary r20 r16 r15 into r22; + gt r21 9u8 into r23; + ternary r23 r21 9u8 into r24; + sub r24 9u8 into r25; + lte r25 29u8 into r26; + assert.eq r26 true; + lt 0u8 r25 into r27; + ternary r27 10u128 1u128 into r28; + lt 1u8 r25 into r29; + mul r28 10u128 into r30; + ternary r29 r30 r28 into r31; + lt 2u8 r25 into r32; + mul r31 10u128 into r33; + ternary r32 r33 r31 into r34; + lt 3u8 r25 into r35; + mul r34 10u128 into r36; + ternary r35 r36 r34 into r37; + lt 4u8 r25 into r38; + mul r37 10u128 into r39; + ternary r38 r39 r37 into r40; + lt 5u8 r25 into r41; + mul r40 10u128 into r42; + ternary r41 r42 r40 into r43; + lt 6u8 r25 into r44; + mul r43 10u128 into r45; + ternary r44 r45 r43 into r46; + lt 7u8 r25 into r47; + mul r46 10u128 into r48; + ternary r47 r48 r46 into r49; + lt 8u8 r25 into r50; + mul r49 10u128 into r51; + ternary r50 r51 r49 into r52; + lt 9u8 r25 into r53; + mul r52 10u128 into r54; + ternary r53 r54 r52 into r55; + lt 10u8 r25 into r56; + mul r55 10u128 into r57; + ternary r56 r57 r55 into r58; + lt 11u8 r25 into r59; + mul r58 10u128 into r60; + ternary r59 r60 r58 into r61; + lt 12u8 r25 into r62; + mul r61 10u128 into r63; + ternary r62 r63 r61 into r64; + lt 13u8 r25 into r65; + mul r64 10u128 into r66; + ternary r65 r66 r64 into r67; + lt 14u8 r25 into r68; + mul r67 10u128 into r69; + ternary r68 r69 r67 into r70; + lt 15u8 r25 into r71; + mul r70 10u128 into r72; + ternary r71 r72 r70 into r73; + lt 16u8 r25 into r74; + mul r73 10u128 into r75; + ternary r74 r75 r73 into r76; + lt 17u8 r25 into r77; + mul r76 10u128 into r78; + ternary r77 r78 r76 into r79; + lt 18u8 r25 into r80; + mul r79 10u128 into r81; + ternary r80 r81 r79 into r82; + lt 19u8 r25 into r83; + mul r82 10u128 into r84; + ternary r83 r84 r82 into r85; + lt 20u8 r25 into r86; + mul r85 10u128 into r87; + ternary r86 r87 r85 into r88; + lt 21u8 r25 into r89; + mul r88 10u128 into r90; + ternary r89 r90 r88 into r91; + lt 22u8 r25 into r92; + mul r91 10u128 into r93; + ternary r92 r93 r91 into r94; + lt 23u8 r25 into r95; + mul r94 10u128 into r96; + ternary r95 r96 r94 into r97; + lt 24u8 r25 into r98; + mul r97 10u128 into r99; + ternary r98 r99 r97 into r100; + lt 25u8 r25 into r101; + mul r100 10u128 into r102; + ternary r101 r102 r100 into r103; + lt 26u8 r25 into r104; + mul r103 10u128 into r105; + ternary r104 r105 r103 into r106; + lt 27u8 r25 into r107; + mul r106 10u128 into r108; + ternary r107 r108 r106 into r109; + lt 28u8 r25 into r110; + mul r109 10u128 into r111; + ternary r110 r111 r109 into r112; + gt r22 9u8 into r113; + ternary r113 r22 9u8 into r114; + sub r114 9u8 into r115; + lte r115 29u8 into r116; + assert.eq r116 true; + lt 0u8 r115 into r117; + ternary r117 10u128 1u128 into r118; + lt 1u8 r115 into r119; + mul r118 10u128 into r120; + ternary r119 r120 r118 into r121; + lt 2u8 r115 into r122; + mul r121 10u128 into r123; + ternary r122 r123 r121 into r124; + lt 3u8 r115 into r125; + mul r124 10u128 into r126; + ternary r125 r126 r124 into r127; + lt 4u8 r115 into r128; + mul r127 10u128 into r129; + ternary r128 r129 r127 into r130; + lt 5u8 r115 into r131; + mul r130 10u128 into r132; + ternary r131 r132 r130 into r133; + lt 6u8 r115 into r134; + mul r133 10u128 into r135; + ternary r134 r135 r133 into r136; + lt 7u8 r115 into r137; + mul r136 10u128 into r138; + ternary r137 r138 r136 into r139; + lt 8u8 r115 into r140; + mul r139 10u128 into r141; + ternary r140 r141 r139 into r142; + lt 9u8 r115 into r143; + mul r142 10u128 into r144; + ternary r143 r144 r142 into r145; + lt 10u8 r115 into r146; + mul r145 10u128 into r147; + ternary r146 r147 r145 into r148; + lt 11u8 r115 into r149; + mul r148 10u128 into r150; + ternary r149 r150 r148 into r151; + lt 12u8 r115 into r152; + mul r151 10u128 into r153; + ternary r152 r153 r151 into r154; + lt 13u8 r115 into r155; + mul r154 10u128 into r156; + ternary r155 r156 r154 into r157; + lt 14u8 r115 into r158; + mul r157 10u128 into r159; + ternary r158 r159 r157 into r160; + lt 15u8 r115 into r161; + mul r160 10u128 into r162; + ternary r161 r162 r160 into r163; + lt 16u8 r115 into r164; + mul r163 10u128 into r165; + ternary r164 r165 r163 into r166; + lt 17u8 r115 into r167; + mul r166 10u128 into r168; + ternary r167 r168 r166 into r169; + lt 18u8 r115 into r170; + mul r169 10u128 into r171; + ternary r170 r171 r169 into r172; + lt 19u8 r115 into r173; + mul r172 10u128 into r174; + ternary r173 r174 r172 into r175; + lt 20u8 r115 into r176; + mul r175 10u128 into r177; + ternary r176 r177 r175 into r178; + lt 21u8 r115 into r179; + mul r178 10u128 into r180; + ternary r179 r180 r178 into r181; + lt 22u8 r115 into r182; + mul r181 10u128 into r183; + ternary r182 r183 r181 into r184; + lt 23u8 r115 into r185; + mul r184 10u128 into r186; + ternary r185 r186 r184 into r187; + lt 24u8 r115 into r188; + mul r187 10u128 into r189; + ternary r188 r189 r187 into r190; + lt 25u8 r115 into r191; + mul r190 10u128 into r192; + ternary r191 r192 r190 into r193; + lt 26u8 r115 into r194; + mul r193 10u128 into r195; + ternary r194 r195 r193 into r196; + lt 27u8 r115 into r197; + mul r196 10u128 into r198; + ternary r197 r198 r196 into r199; + lt 28u8 r115 into r200; + mul r199 10u128 into r201; + ternary r200 r201 r199 into r202; + cast r18 r19 r3 into r203 as PoolKey; + hash.bhp256 r203 into r204 as field; + cast r18 r19 r3 true r112 r202 into r205 as PoolState; + get.or_use token_paused[r18] false into r206; + not r206 into r207; + assert.eq r207 true; + get.or_use token_paused[r19] false into r208; + not r208 into r209; + assert.eq r209 true; + cast r18 r19 into r210 as PairKey; + get.or_use pair_paused[r210] false into r211; + not r211 into r212; + assert.eq r212 true; + assert.neq r1 r2; + get.or_use initialized_pools[r204] false into r213; + not r213 into r214; + assert.eq r214 true; + get.or_use tick_spacings[r5] false into r215; + assert.eq r215 true; + get.or_use fee_tiers[r3] false into r216; + assert.eq r216 true; + get fee_to_tick_spacing[r3] into r217; + is.eq r217 r5 into r218; + assert.eq r218 true; + cast r5 into r219 as i32; + rem r6 r219 into r220; + is.eq r220 0i32 into r221; + assert.eq r221 true; + gte r6 -400000i32 into r222; + lt r6 400000i32 into r223; + and r222 r223 into r224; + assert.eq r224 true; + call view_sqrt_price_at_tick r6 into r225; + add r6 1i32 into r226; + call view_sqrt_price_at_tick r226 into r227; + gte r4 r225 into r228; + lt r4 r227 into r229; + and r228 r229 into r230; + assert.eq r230 true; + cast r5 into r231 as u128; + div 800000u128 r231 into r232; + div 340282366920938463463374607431768211455u128 r232 into r233; + lt r233 9223372036854775808u128 into r234; + ternary r234 r233 9223372036854775808u128 into r235; + set true into initialized_pools[r204]; + set r205 into pools[r204]; + cast r204 -400001i32 into r236 as TickKey; + hash.bhp256 r236 into r237 as field; + cast r204 400001i32 into r238 as TickKey; + hash.bhp256 r238 into r239 as field; + cast r204 0i128 0u128 -400001i32 0u128 0u128 -400001i32 400001i32 into r240 as Tick; + set r240 into ticks[r237]; + cast r204 0i128 0u128 400001i32 0u128 0u128 -400001i32 400001i32 into r241 as Tick; + set r241 into ticks[r239]; + cast r6 r5 r4 0u8 0u128 0u128 0u128 0u128 0u128 r235 0u128 0u128 -400001i32 400001i32 into r242 as Slot; + set r242 into slots[r204]; + +view view_liquidity_for_amounts: + input r0 as u128.public; + input r1 as u128.public; + input r2 as u128.public; + input r3 as u128.public; + input r4 as u128.public; + gt r1 r2 into r5; + ternary r5 r2 r1 into r6; + ternary r5 r1 r2 into r7; + lte r0 r6 into r8; + gt r6 r7 into r9; + ternary r9 r7 r6 into r10; + ternary r9 r6 r7 into r11; + and r10 18446744073709551615u128 into r12; + shr r10 64u8 into r13; + and r11 18446744073709551615u128 into r14; + shr r11 64u8 into r15; + mul r12 r14 into r16; + mul r12 r15 into r17; + mul r13 r14 into r18; + mul r13 r15 into r19; + and r16 18446744073709551615u128 into r20; + shr r16 64u8 into r21; + and r17 18446744073709551615u128 into r22; + add r21 r22 into r23; + and r18 18446744073709551615u128 into r24; + add r23 r24 into r25; + and r25 18446744073709551615u128 into r26; + shr r25 64u8 into r27; + shr r17 64u8 into r28; + shr r18 64u8 into r29; + add r28 r29 into r30; + and r19 18446744073709551615u128 into r31; + add r30 r31 into r32; + add r32 r27 into r33; + and r33 18446744073709551615u128 into r34; + shr r33 64u8 into r35; + shr r19 64u8 into r36; + add r36 r35 into r37; + shl r26 64u8 into r38; + add r38 r20 into r39; + shl r37 64u8 into r40; + add r40 r34 into r41; + shl r41 65u8 into r42; + shr r39 63u8 into r43; + add r42 r43 into r44; + sub r11 r10 into r45; + gt r45 0u128 into r46; + ternary r46 r45 1u128 into r47; + ternary r46 r3 0u128 into r48; + and r48 18446744073709551615u128 into r49; + shr r48 64u8 into r50; + and r44 18446744073709551615u128 into r51; + shr r44 64u8 into r52; + mul r49 r51 into r53; + mul r49 r52 into r54; + mul r50 r51 into r55; + mul r50 r52 into r56; + and r53 18446744073709551615u128 into r57; + shr r53 64u8 into r58; + and r54 18446744073709551615u128 into r59; + add r58 r59 into r60; + and r55 18446744073709551615u128 into r61; + add r60 r61 into r62; + and r62 18446744073709551615u128 into r63; + shr r62 64u8 into r64; + shr r54 64u8 into r65; + shr r55 64u8 into r66; + add r65 r66 into r67; + and r56 18446744073709551615u128 into r68; + add r67 r68 into r69; + add r69 r64 into r70; + and r70 18446744073709551615u128 into r71; + shr r70 64u8 into r72; + shr r56 64u8 into r73; + add r73 r72 into r74; + shl r63 64u8 into r75; + add r75 r57 into r76; + shl r74 64u8 into r77; + add r77 r71 into r78; + lt r78 r47 into r79; + assert.eq r79 true; + shr r76 96u8 into r80; + and r80 4294967295u128 into r81; + shl r78 32u8 into r82; + add r82 r81 into r83; + div r83 r47 into r84; + rem r83 r47 into r85; + shr r76 64u8 into r86; + and r86 4294967295u128 into r87; + shl r85 32u8 into r88; + add r88 r87 into r89; + shl r84 32u8 into r90; + div r89 r47 into r91; + add r90 r91 into r92; + rem r89 r47 into r93; + shr r76 32u8 into r94; + and r94 4294967295u128 into r95; + shl r93 32u8 into r96; + add r96 r95 into r97; + shl r92 32u8 into r98; + div r97 r47 into r99; + add r98 r99 into r100; + rem r97 r47 into r101; + shr r76 0u8 into r102; + and r102 4294967295u128 into r103; + shl r101 32u8 into r104; + add r104 r103 into r105; + shl r100 32u8 into r106; + div r105 r47 into r107; + add r106 r107 into r108; + rem r105 r47 into r109; + add r108 1u128 into r110; + lt r0 r7 into r111; + gt r0 r7 into r112; + ternary r112 r7 r0 into r113; + ternary r112 r0 r7 into r114; + and r113 18446744073709551615u128 into r115; + shr r113 64u8 into r116; + and r114 18446744073709551615u128 into r117; + shr r114 64u8 into r118; + mul r115 r117 into r119; + mul r115 r118 into r120; + mul r116 r117 into r121; + mul r116 r118 into r122; + and r119 18446744073709551615u128 into r123; + shr r119 64u8 into r124; + and r120 18446744073709551615u128 into r125; + add r124 r125 into r126; + and r121 18446744073709551615u128 into r127; + add r126 r127 into r128; + and r128 18446744073709551615u128 into r129; + shr r128 64u8 into r130; + shr r120 64u8 into r131; + shr r121 64u8 into r132; + add r131 r132 into r133; + and r122 18446744073709551615u128 into r134; + add r133 r134 into r135; + add r135 r130 into r136; + and r136 18446744073709551615u128 into r137; + shr r136 64u8 into r138; + shr r122 64u8 into r139; + add r139 r138 into r140; + shl r129 64u8 into r141; + add r141 r123 into r142; + shl r140 64u8 into r143; + add r143 r137 into r144; + shl r144 65u8 into r145; + shr r142 63u8 into r146; + add r145 r146 into r147; + sub r114 r113 into r148; + gt r148 0u128 into r149; + ternary r149 r148 1u128 into r150; + ternary r149 r3 0u128 into r151; + and r151 18446744073709551615u128 into r152; + shr r151 64u8 into r153; + and r147 18446744073709551615u128 into r154; + shr r147 64u8 into r155; + mul r152 r154 into r156; + mul r152 r155 into r157; + mul r153 r154 into r158; + mul r153 r155 into r159; + and r156 18446744073709551615u128 into r160; + shr r156 64u8 into r161; + and r157 18446744073709551615u128 into r162; + add r161 r162 into r163; + and r158 18446744073709551615u128 into r164; + add r163 r164 into r165; + and r165 18446744073709551615u128 into r166; + shr r165 64u8 into r167; + shr r157 64u8 into r168; + shr r158 64u8 into r169; + add r168 r169 into r170; + and r159 18446744073709551615u128 into r171; + add r170 r171 into r172; + add r172 r167 into r173; + and r173 18446744073709551615u128 into r174; + shr r173 64u8 into r175; + shr r159 64u8 into r176; + add r176 r175 into r177; + shl r166 64u8 into r178; + add r178 r160 into r179; + shl r177 64u8 into r180; + add r180 r174 into r181; + lt r181 r150 into r182; + assert.eq r182 true; + shr r179 96u8 into r183; + and r183 4294967295u128 into r184; + shl r181 32u8 into r185; + add r185 r184 into r186; + div r186 r150 into r187; + rem r186 r150 into r188; + shr r179 64u8 into r189; + and r189 4294967295u128 into r190; + shl r188 32u8 into r191; + add r191 r190 into r192; + shl r187 32u8 into r193; + div r192 r150 into r194; + add r193 r194 into r195; + rem r192 r150 into r196; + shr r179 32u8 into r197; + and r197 4294967295u128 into r198; + shl r196 32u8 into r199; + add r199 r198 into r200; + shl r195 32u8 into r201; + div r200 r150 into r202; + add r201 r202 into r203; + rem r200 r150 into r204; + shr r179 0u8 into r205; + and r205 4294967295u128 into r206; + shl r204 32u8 into r207; + add r207 r206 into r208; + shl r203 32u8 into r209; + div r208 r150 into r210; + add r209 r210 into r211; + rem r208 r150 into r212; + add r211 1u128 into r213; + gt r6 r0 into r214; + ternary r214 r0 r6 into r215; + ternary r214 r6 r0 into r216; + sub r216 r215 into r217; + gt r217 0u128 into r218; + ternary r218 r217 1u128 into r219; + ternary r218 r4 0u128 into r220; + and r220 18446744073709551615u128 into r221; + shr r220 64u8 into r222; + mul r221 9223372036854775808u128 into r223; + mul r222 9223372036854775808u128 into r224; + and r223 18446744073709551615u128 into r225; + shr r223 64u8 into r226; + and r224 18446744073709551615u128 into r227; + add r226 r227 into r228; + and r228 18446744073709551615u128 into r229; + shr r228 64u8 into r230; + shr r224 64u8 into r231; + add r231 r230 into r232; + and r232 18446744073709551615u128 into r233; + shr r232 64u8 into r234; + shl r229 64u8 into r235; + add r235 r225 into r236; + shl r234 64u8 into r237; + add r237 r233 into r238; + lt r238 r219 into r239; + assert.eq r239 true; + shr r236 96u8 into r240; + and r240 4294967295u128 into r241; + shl r238 32u8 into r242; + add r242 r241 into r243; + div r243 r219 into r244; + rem r243 r219 into r245; + shr r236 64u8 into r246; + and r246 4294967295u128 into r247; + shl r245 32u8 into r248; + add r248 r247 into r249; + shl r244 32u8 into r250; + div r249 r219 into r251; + add r250 r251 into r252; + rem r249 r219 into r253; + shr r236 32u8 into r254; + and r254 4294967295u128 into r255; + shl r253 32u8 into r256; + add r256 r255 into r257; + shl r252 32u8 into r258; + div r257 r219 into r259; + add r258 r259 into r260; + rem r257 r219 into r261; + shr r236 0u8 into r262; + and r262 4294967295u128 into r263; + shl r261 32u8 into r264; + add r264 r263 into r265; + shl r260 32u8 into r266; + div r265 r219 into r267; + add r266 r267 into r268; + rem r265 r219 into r269; + add r268 1u128 into r270; + lt r211 r268 into r271; + ternary r271 r211 r268 into r272; + gt r6 r7 into r273; + ternary r273 r7 r6 into r274; + ternary r273 r6 r7 into r275; + sub r275 r274 into r276; + gt r276 0u128 into r277; + ternary r277 r276 1u128 into r278; + ternary r277 r4 0u128 into r279; + and r279 18446744073709551615u128 into r280; + shr r279 64u8 into r281; + mul r280 9223372036854775808u128 into r282; + mul r281 9223372036854775808u128 into r283; + and r282 18446744073709551615u128 into r284; + shr r282 64u8 into r285; + and r283 18446744073709551615u128 into r286; + add r285 r286 into r287; + and r287 18446744073709551615u128 into r288; + shr r287 64u8 into r289; + shr r283 64u8 into r290; + add r290 r289 into r291; + and r291 18446744073709551615u128 into r292; + shr r291 64u8 into r293; + shl r288 64u8 into r294; + add r294 r284 into r295; + shl r293 64u8 into r296; + add r296 r292 into r297; + lt r297 r278 into r298; + assert.eq r298 true; + shr r295 96u8 into r299; + and r299 4294967295u128 into r300; + shl r297 32u8 into r301; + add r301 r300 into r302; + div r302 r278 into r303; + rem r302 r278 into r304; + shr r295 64u8 into r305; + and r305 4294967295u128 into r306; + shl r304 32u8 into r307; + add r307 r306 into r308; + shl r303 32u8 into r309; + div r308 r278 into r310; + add r309 r310 into r311; + rem r308 r278 into r312; + shr r295 32u8 into r313; + and r313 4294967295u128 into r314; + shl r312 32u8 into r315; + add r315 r314 into r316; + shl r311 32u8 into r317; + div r316 r278 into r318; + add r317 r318 into r319; + rem r316 r278 into r320; + shr r295 0u8 into r321; + and r321 4294967295u128 into r322; + shl r320 32u8 into r323; + add r323 r322 into r324; + shl r319 32u8 into r325; + div r324 r278 into r326; + add r325 r326 into r327; + rem r324 r278 into r328; + add r327 1u128 into r329; + ternary r111 r272 r327 into r330; + ternary r8 r108 r330 into r331; + output r331 as u128.public; + +function mint: + input r0 as field.private; + input r1 as dynamic.record; + input r2 as dynamic.record; + input r3 as address.private; + input r4 as MintPositionRequest.public; + input r5 as field.public; + input r6 as field.public; + assert.neq r3 shield_swap_v3.aleo; + cast r4 r3 r0 into r7 as TokenIDPreimage; + hash.bhp256 r7 into r8 as field; + cast aleo1t08epjqqv8h7jpuy2m2cxm80zy2pcy5c4f3m82hnac4sjmdrjyysvx3s2h r8 r5 r6 r4 self.caller r3 into r9 as MintComplianceRecord.record; + cast r3 r8 r5 r6 r4.pool r4.tick_lower r4.tick_upper into r10 as PositionNFT.record; + call.dynamic r5 'aleo' 'transfer_private_to_public' with r1 shield_swap_v3.aleo r4.amount0_desired (as dynamic.record address.public u128.public) into r11 r12 (as dynamic.record dynamic.future); + call.dynamic r6 'aleo' 'transfer_private_to_public' with r2 shield_swap_v3.aleo r4.amount1_desired (as dynamic.record address.public u128.public) into r13 r14 (as dynamic.record dynamic.future); + async mint r12 r14 r4 r8 r5 r6 into r15; + output r8 as field.public; + output r10 as PositionNFT.record; + output r11 as dynamic.record; + output r13 as dynamic.record; + output r9 as MintComplianceRecord.record; + output r15 as shield_swap_v3.aleo/mint.future; + +finalize mint: + input r0 as dynamic.future; + input r1 as dynamic.future; + input r2 as MintPositionRequest.public; + input r3 as field.public; + input r4 as field.public; + input r5 as field.public; + await r0; + await r1; + get.or_use global_paused[true] false into r6; + not r6 into r7; + assert.eq r7 true; + get pools[r2.pool] into r8; + assert.eq r8.enabled true; + get.or_use token_paused[r8.token0] false into r9; + not r9 into r10; + assert.eq r10 true; + get.or_use token_paused[r8.token1] false into r11; + not r11 into r12; + assert.eq r12 true; + cast r8.token0 r8.token1 into r13 as PairKey; + get.or_use pair_paused[r13] false into r14; + not r14 into r15; + assert.eq r15 true; + is.eq r8.token0 r4 into r16; + assert.eq r16 true; + is.eq r8.token1 r5 into r17; + assert.eq r17 true; + get slots[r2.pool] into r18; + cast r18.tick_spacing into r19 as i32; + rem r2.tick_lower r19 into r20; + is.eq r20 0i32 into r21; + assert.eq r21 true; + cast r18.tick_spacing into r22 as i32; + rem r2.tick_upper r22 into r23; + is.eq r23 0i32 into r24; + assert.eq r24 true; + lt r2.tick_lower r2.tick_upper into r25; + assert.eq r25 true; + gte r2.tick_lower -400000i32 into r26; + assert.eq r26 true; + lte r2.tick_upper 400000i32 into r27; + assert.eq r27 true; + call view_sqrt_price_at_tick r2.tick_lower into r28; + call view_sqrt_price_at_tick r2.tick_upper into r29; + rem r2.amount0_desired r8.scale0 into r30; + is.eq r30 0u128 into r31; + assert.eq r31 true; + rem r2.amount1_desired r8.scale1 into r32; + is.eq r32 0u128 into r33; + assert.eq r33 true; + div r2.amount0_desired r8.scale0 into r34; + div r2.amount1_desired r8.scale1 into r35; + call view_liquidity_for_amounts r18.sqrt_price r28 r29 r34 r35 into r36; + gt r36 0u128 into r37; + assert.eq r37 true; + call view_amounts_for_liquidity r18.sqrt_price r28 r29 r36 false into r38 r39; + lte r38 r34 into r40; + lte r39 r35 into r41; + and r40 r41 into r42; + assert.eq r42 true; + mul r38 r8.scale0 into r43; + gte r43 r2.amount0_min into r44; + mul r39 r8.scale1 into r45; + gte r45 r2.amount1_min into r46; + and r44 r46 into r47; + assert.eq r47 true; + lt r18.sqrt_price r29 into r48; + branch.eq r48 false to end_then_0_0; + gt r38 0u128 into r49; + assert.eq r49 true; + branch.eq true true to end_otherwise_0_1; + position end_then_0_0; + position end_otherwise_0_1; + gt r18.sqrt_price r28 into r50; + branch.eq r50 false to end_then_0_2; + gt r39 0u128 into r51; + assert.eq r51 true; + branch.eq true true to end_otherwise_0_3; + position end_then_0_2; + position end_otherwise_0_3; + cast r2.pool r2.tick_lower into r52 as TickKey; + hash.bhp256 r52 into r53 as field; + cast r2.pool r2.tick_upper into r54 as TickKey; + hash.bhp256 r54 into r55 as field; + cast r2.pool 0i128 0u128 r2.tick_lower 0u128 0u128 0i32 0i32 into r56 as Tick; + cast r2.pool 0i128 0u128 r2.tick_upper 0u128 0u128 0i32 0i32 into r57 as Tick; + get.or_use ticks[r53] r56 into r58; + get.or_use ticks[r55] r57 into r59; + gt r58.liquidity_gross 0u128 into r60; + gt r59.liquidity_gross 0u128 into r61; + not r60 into r62; + lte r2.tick_lower r18.tick into r63; + and r62 r63 into r64; + ternary r64 r18.fee_growth_global0_x_64 r58.fee_growth_outside0_64 into r65; + lte r2.tick_lower r18.tick into r66; + and r62 r66 into r67; + ternary r67 r18.fee_growth_global1_x_64 r58.fee_growth_outside1_64 into r68; + not r61 into r69; + lte r2.tick_upper r18.tick into r70; + and r69 r70 into r71; + ternary r71 r18.fee_growth_global0_x_64 r59.fee_growth_outside0_64 into r72; + lte r2.tick_upper r18.tick into r73; + and r69 r73 into r74; + ternary r74 r18.fee_growth_global1_x_64 r59.fee_growth_outside1_64 into r75; + add r58.liquidity_gross r36 into r76; + add r59.liquidity_gross r36 into r77; + lte r76 r18.max_liquidity_per_tick into r78; + assert.eq r78 true; + lte r77 r18.max_liquidity_per_tick into r79; + assert.eq r79 true; + ternary r60 -400001i32 r2.tick_lower_hint into r80; + cast r2.pool r80 into r81 as TickKey; + hash.bhp256 r81 into r82 as field; + get ticks[r82] into r83; + branch.eq r62 false to end_then_0_4; + is.eq r83.pool r2.pool into r84; + assert.eq r84 true; + is.eq r83.tick r2.tick_lower_hint into r85; + assert.eq r85 true; + is.eq r2.tick_lower_hint -400001i32 into r86; + gt r83.liquidity_gross 0u128 into r87; + or r86 r87 into r88; + assert.eq r88 true; + lt r83.tick r2.tick_lower into r89; + assert.eq r89 true; + gt r83.next r2.tick_lower into r90; + assert.eq r90 true; + branch.eq true true to end_otherwise_0_5; + position end_then_0_4; + position end_otherwise_0_5; + ternary r60 r58.prev r2.tick_lower_hint into r91; + ternary r60 r58.next r83.next into r92; + cast r36 into r93 as i128; + add r58.liquidity_net r93 into r94; + cast r2.pool r94 r76 r2.tick_lower r65 r68 r91 r92 into r95 as Tick; + set r95 into ticks[r53]; + branch.eq r62 false to end_then_0_6; + cast r83.pool r83.liquidity_net r83.liquidity_gross r83.tick r83.fee_growth_outside0_64 r83.fee_growth_outside1_64 r83.prev r2.tick_lower into r96 as Tick; + set r96 into ticks[r82]; + cast r2.pool r92 into r97 as TickKey; + hash.bhp256 r97 into r98 as field; + get ticks[r98] into r99; + cast r99.pool r99.liquidity_net r99.liquidity_gross r99.tick r99.fee_growth_outside0_64 r99.fee_growth_outside1_64 r2.tick_lower r99.next into r100 as Tick; + set r100 into ticks[r98]; + branch.eq true true to end_otherwise_0_7; + position end_then_0_6; + position end_otherwise_0_7; + get.or_use ticks[r55] r57 into r101; + ternary r61 -400001i32 r2.tick_upper_hint into r102; + cast r2.pool r102 into r103 as TickKey; + hash.bhp256 r103 into r104 as field; + get ticks[r104] into r105; + branch.eq r69 false to end_then_0_8; + is.eq r105.pool r2.pool into r106; + assert.eq r106 true; + is.eq r105.tick r2.tick_upper_hint into r107; + assert.eq r107 true; + is.eq r2.tick_upper_hint -400001i32 into r108; + gt r105.liquidity_gross 0u128 into r109; + or r108 r109 into r110; + assert.eq r110 true; + lt r105.tick r2.tick_upper into r111; + assert.eq r111 true; + gt r105.next r2.tick_upper into r112; + assert.eq r112 true; + branch.eq true true to end_otherwise_0_9; + position end_then_0_8; + position end_otherwise_0_9; + ternary r61 r101.prev r2.tick_upper_hint into r113; + ternary r61 r101.next r105.next into r114; + cast r36 into r115 as i128; + sub r101.liquidity_net r115 into r116; + cast r2.pool r116 r77 r2.tick_upper r72 r75 r113 r114 into r117 as Tick; + set r117 into ticks[r55]; + branch.eq r69 false to end_then_0_10; + get ticks[r104] into r118; + cast r118.pool r118.liquidity_net r118.liquidity_gross r118.tick r118.fee_growth_outside0_64 r118.fee_growth_outside1_64 r118.prev r2.tick_upper into r119 as Tick; + set r119 into ticks[r104]; + cast r2.pool r114 into r120 as TickKey; + hash.bhp256 r120 into r121 as field; + get ticks[r121] into r122; + cast r122.pool r122.liquidity_net r122.liquidity_gross r122.tick r122.fee_growth_outside0_64 r122.fee_growth_outside1_64 r2.tick_upper r122.next into r123 as Tick; + set r123 into ticks[r121]; + branch.eq true true to end_otherwise_0_11; + position end_then_0_10; + position end_otherwise_0_11; + get ticks[r53] into r124; + get ticks[r55] into r125; + gte r18.tick r124.tick into r126; + gte r18.fee_growth_global0_x_64 r124.fee_growth_outside0_64 into r127; + ternary r127 r18.fee_growth_global0_x_64 r124.fee_growth_outside0_64 into r128; + ternary r127 r124.fee_growth_outside0_64 r18.fee_growth_global0_x_64 into r129; + sub r128 r129 into r130; + gt r130 0u128 into r131; + ternary r131 r130 1u128 into r132; + sub 340282366920938463463374607431768211455u128 r132 into r133; + add r133 1u128 into r134; + ternary r127 r130 r134 into r135; + gte r18.fee_growth_global1_x_64 r124.fee_growth_outside1_64 into r136; + ternary r136 r18.fee_growth_global1_x_64 r124.fee_growth_outside1_64 into r137; + ternary r136 r124.fee_growth_outside1_64 r18.fee_growth_global1_x_64 into r138; + sub r137 r138 into r139; + gt r139 0u128 into r140; + ternary r140 r139 1u128 into r141; + sub 340282366920938463463374607431768211455u128 r141 into r142; + add r142 1u128 into r143; + ternary r136 r139 r143 into r144; + ternary r126 r124.fee_growth_outside0_64 r135 into r145; + ternary r126 r124.fee_growth_outside1_64 r144 into r146; + lt r18.tick r125.tick into r147; + gte r18.fee_growth_global0_x_64 r125.fee_growth_outside0_64 into r148; + ternary r148 r18.fee_growth_global0_x_64 r125.fee_growth_outside0_64 into r149; + ternary r148 r125.fee_growth_outside0_64 r18.fee_growth_global0_x_64 into r150; + sub r149 r150 into r151; + gt r151 0u128 into r152; + ternary r152 r151 1u128 into r153; + sub 340282366920938463463374607431768211455u128 r153 into r154; + add r154 1u128 into r155; + ternary r148 r151 r155 into r156; + gte r18.fee_growth_global1_x_64 r125.fee_growth_outside1_64 into r157; + ternary r157 r18.fee_growth_global1_x_64 r125.fee_growth_outside1_64 into r158; + ternary r157 r125.fee_growth_outside1_64 r18.fee_growth_global1_x_64 into r159; + sub r158 r159 into r160; + gt r160 0u128 into r161; + ternary r161 r160 1u128 into r162; + sub 340282366920938463463374607431768211455u128 r162 into r163; + add r163 1u128 into r164; + ternary r157 r160 r164 into r165; + ternary r147 r125.fee_growth_outside0_64 r156 into r166; + ternary r147 r125.fee_growth_outside1_64 r165 into r167; + gte r18.fee_growth_global0_x_64 r145 into r168; + ternary r168 r18.fee_growth_global0_x_64 r145 into r169; + ternary r168 r145 r18.fee_growth_global0_x_64 into r170; + sub r169 r170 into r171; + gt r171 0u128 into r172; + ternary r172 r171 1u128 into r173; + sub 340282366920938463463374607431768211455u128 r173 into r174; + add r174 1u128 into r175; + ternary r168 r171 r175 into r176; + gte r176 r166 into r177; + ternary r177 r176 r166 into r178; + ternary r177 r166 r176 into r179; + sub r178 r179 into r180; + gt r180 0u128 into r181; + ternary r181 r180 1u128 into r182; + sub 340282366920938463463374607431768211455u128 r182 into r183; + add r183 1u128 into r184; + ternary r177 r180 r184 into r185; + gte r18.fee_growth_global1_x_64 r146 into r186; + ternary r186 r18.fee_growth_global1_x_64 r146 into r187; + ternary r186 r146 r18.fee_growth_global1_x_64 into r188; + sub r187 r188 into r189; + gt r189 0u128 into r190; + ternary r190 r189 1u128 into r191; + sub 340282366920938463463374607431768211455u128 r191 into r192; + add r192 1u128 into r193; + ternary r186 r189 r193 into r194; + gte r194 r167 into r195; + ternary r195 r194 r167 into r196; + ternary r195 r167 r194 into r197; + sub r196 r197 into r198; + gt r198 0u128 into r199; + ternary r199 r198 1u128 into r200; + sub 340282366920938463463374607431768211455u128 r200 into r201; + add r201 1u128 into r202; + ternary r195 r198 r202 into r203; + contains positions[r3] into r204; + not r204 into r205; + assert.eq r205 true; + sub r34 r38 into r206; + sub r35 r39 into r207; + cast r3 r2.pool r2.tick_lower r2.tick_upper r36 r185 r203 r206 r207 into r208 as Position; + set r208 into positions[r3]; + lte r2.tick_lower r18.tick into r209; + and r62 r209 into r210; + gt r2.tick_lower r18.next_init_below into r211; + and r210 r211 into r212; + ternary r212 r2.tick_lower r18.next_init_below into r213; + gt r2.tick_lower r18.tick into r214; + and r62 r214 into r215; + lt r2.tick_lower r18.next_init_above into r216; + and r215 r216 into r217; + ternary r217 r2.tick_lower r18.next_init_above into r218; + lte r2.tick_upper r18.tick into r219; + and r69 r219 into r220; + gt r2.tick_upper r213 into r221; + and r220 r221 into r222; + ternary r222 r2.tick_upper r213 into r223; + gt r2.tick_upper r18.tick into r224; + and r69 r224 into r225; + lt r2.tick_upper r218 into r226; + and r225 r226 into r227; + ternary r227 r2.tick_upper r218 into r228; + gte r18.tick r2.tick_lower into r229; + lt r18.tick r2.tick_upper into r230; + and r229 r230 into r231; + add r18.liquidity r36 into r232; + ternary r231 r232 r18.liquidity into r233; + cast r18.tick r18.tick_spacing r18.sqrt_price r18.fee_protocol r233 r18.fee_growth_global0_x_64 r18.fee_growth_global1_x_64 r18.fee_residual0_x_64 r18.fee_residual1_x_64 r18.max_liquidity_per_tick r18.protocol_fees0 r18.protocol_fees1 r223 r228 into r234 as Slot; + set r234 into slots[r2.pool]; + +function decrease_liquidity: + input r0 as PositionNFT.record; + input r1 as u128.public; + input r2 as u128.public; + input r3 as u128.public; + cast r0.owner r0.token_id r0.token0_id r0.token1_id r0.pool r0.tick_lower r0.tick_upper into r4 as PositionNFT.record; + async decrease_liquidity r0.token_id r0.pool r0.tick_lower r0.tick_upper r1 r2 r3 into r5; + output r0.token_id as field.public; + output r4 as PositionNFT.record; + output r5 as shield_swap_v3.aleo/decrease_liquidity.future; + +finalize decrease_liquidity: + input r0 as field.public; + input r1 as field.public; + input r2 as i32.public; + input r3 as i32.public; + input r4 as u128.public; + input r5 as u128.public; + input r6 as u128.public; + get positions[r0] into r7; + contains frozen_position[r0] into r8; + not r8 into r9; + assert.eq r9 true; + is.eq r7.pool r1 into r10; + is.eq r7.tick_lower r2 into r11; + and r10 r11 into r12; + is.eq r7.tick_upper r3 into r13; + and r12 r13 into r14; + assert.eq r14 true; + lte r4 r7.liquidity into r15; + assert.eq r15 true; + get positions[r0] into r16; + get slots[r16.pool] into r17; + call view_sqrt_price_at_tick r16.tick_lower into r18; + call view_sqrt_price_at_tick r16.tick_upper into r19; + call view_amounts_for_liquidity r17.sqrt_price r18 r19 r4 false into r20 r21; + cast r16.pool r16.tick_lower into r22 as TickKey; + hash.bhp256 r22 into r23 as field; + cast r16.pool r16.tick_upper into r24 as TickKey; + hash.bhp256 r24 into r25 as field; + get ticks[r23] into r26; + get ticks[r25] into r27; + gt r26.liquidity_gross 0u128 into r28; + gt r27.liquidity_gross 0u128 into r29; + sub r26.liquidity_gross r4 into r30; + sub r27.liquidity_gross r4 into r31; + is.eq r30 0u128 into r32; + and r28 r32 into r33; + is.eq r31 0u128 into r34; + and r29 r34 into r35; + cast r4 into r36 as i128; + sub r26.liquidity_net r36 into r37; + cast r26.pool r37 r30 r26.tick r26.fee_growth_outside0_64 r26.fee_growth_outside1_64 r26.prev r26.next into r38 as Tick; + set r38 into ticks[r23]; + branch.eq r33 false to end_then_0_0; + cast r16.pool r26.prev into r39 as TickKey; + hash.bhp256 r39 into r40 as field; + get ticks[r40] into r41; + cast r41.pool r41.liquidity_net r41.liquidity_gross r41.tick r41.fee_growth_outside0_64 r41.fee_growth_outside1_64 r41.prev r26.next into r42 as Tick; + set r42 into ticks[r40]; + cast r16.pool r26.next into r43 as TickKey; + hash.bhp256 r43 into r44 as field; + get ticks[r44] into r45; + cast r45.pool r45.liquidity_net r45.liquidity_gross r45.tick r45.fee_growth_outside0_64 r45.fee_growth_outside1_64 r26.prev r45.next into r46 as Tick; + set r46 into ticks[r44]; + branch.eq true true to end_otherwise_0_1; + position end_then_0_0; + position end_otherwise_0_1; + get ticks[r25] into r47; + cast r4 into r48 as i128; + add r47.liquidity_net r48 into r49; + cast r47.pool r49 r31 r47.tick r47.fee_growth_outside0_64 r47.fee_growth_outside1_64 r47.prev r47.next into r50 as Tick; + set r50 into ticks[r25]; + branch.eq r35 false to end_then_0_2; + cast r16.pool r47.prev into r51 as TickKey; + hash.bhp256 r51 into r52 as field; + get ticks[r52] into r53; + cast r53.pool r53.liquidity_net r53.liquidity_gross r53.tick r53.fee_growth_outside0_64 r53.fee_growth_outside1_64 r53.prev r47.next into r54 as Tick; + set r54 into ticks[r52]; + cast r16.pool r47.next into r55 as TickKey; + hash.bhp256 r55 into r56 as field; + get ticks[r56] into r57; + cast r57.pool r57.liquidity_net r57.liquidity_gross r57.tick r57.fee_growth_outside0_64 r57.fee_growth_outside1_64 r47.prev r57.next into r58 as Tick; + set r58 into ticks[r56]; + branch.eq true true to end_otherwise_0_3; + position end_then_0_2; + position end_otherwise_0_3; + get ticks[r23] into r59; + get ticks[r25] into r60; + gte r17.tick r59.tick into r61; + gte r17.fee_growth_global0_x_64 r59.fee_growth_outside0_64 into r62; + ternary r62 r17.fee_growth_global0_x_64 r59.fee_growth_outside0_64 into r63; + ternary r62 r59.fee_growth_outside0_64 r17.fee_growth_global0_x_64 into r64; + sub r63 r64 into r65; + gt r65 0u128 into r66; + ternary r66 r65 1u128 into r67; + sub 340282366920938463463374607431768211455u128 r67 into r68; + add r68 1u128 into r69; + ternary r62 r65 r69 into r70; + gte r17.fee_growth_global1_x_64 r59.fee_growth_outside1_64 into r71; + ternary r71 r17.fee_growth_global1_x_64 r59.fee_growth_outside1_64 into r72; + ternary r71 r59.fee_growth_outside1_64 r17.fee_growth_global1_x_64 into r73; + sub r72 r73 into r74; + gt r74 0u128 into r75; + ternary r75 r74 1u128 into r76; + sub 340282366920938463463374607431768211455u128 r76 into r77; + add r77 1u128 into r78; + ternary r71 r74 r78 into r79; + ternary r61 r59.fee_growth_outside0_64 r70 into r80; + ternary r61 r59.fee_growth_outside1_64 r79 into r81; + lt r17.tick r60.tick into r82; + gte r17.fee_growth_global0_x_64 r60.fee_growth_outside0_64 into r83; + ternary r83 r17.fee_growth_global0_x_64 r60.fee_growth_outside0_64 into r84; + ternary r83 r60.fee_growth_outside0_64 r17.fee_growth_global0_x_64 into r85; + sub r84 r85 into r86; + gt r86 0u128 into r87; + ternary r87 r86 1u128 into r88; + sub 340282366920938463463374607431768211455u128 r88 into r89; + add r89 1u128 into r90; + ternary r83 r86 r90 into r91; + gte r17.fee_growth_global1_x_64 r60.fee_growth_outside1_64 into r92; + ternary r92 r17.fee_growth_global1_x_64 r60.fee_growth_outside1_64 into r93; + ternary r92 r60.fee_growth_outside1_64 r17.fee_growth_global1_x_64 into r94; + sub r93 r94 into r95; + gt r95 0u128 into r96; + ternary r96 r95 1u128 into r97; + sub 340282366920938463463374607431768211455u128 r97 into r98; + add r98 1u128 into r99; + ternary r92 r95 r99 into r100; + ternary r82 r60.fee_growth_outside0_64 r91 into r101; + ternary r82 r60.fee_growth_outside1_64 r100 into r102; + gte r17.fee_growth_global0_x_64 r80 into r103; + ternary r103 r17.fee_growth_global0_x_64 r80 into r104; + ternary r103 r80 r17.fee_growth_global0_x_64 into r105; + sub r104 r105 into r106; + gt r106 0u128 into r107; + ternary r107 r106 1u128 into r108; + sub 340282366920938463463374607431768211455u128 r108 into r109; + add r109 1u128 into r110; + ternary r103 r106 r110 into r111; + gte r111 r101 into r112; + ternary r112 r111 r101 into r113; + ternary r112 r101 r111 into r114; + sub r113 r114 into r115; + gt r115 0u128 into r116; + ternary r116 r115 1u128 into r117; + sub 340282366920938463463374607431768211455u128 r117 into r118; + add r118 1u128 into r119; + ternary r112 r115 r119 into r120; + gte r17.fee_growth_global1_x_64 r81 into r121; + ternary r121 r17.fee_growth_global1_x_64 r81 into r122; + ternary r121 r81 r17.fee_growth_global1_x_64 into r123; + sub r122 r123 into r124; + gt r124 0u128 into r125; + ternary r125 r124 1u128 into r126; + sub 340282366920938463463374607431768211455u128 r126 into r127; + add r127 1u128 into r128; + ternary r121 r124 r128 into r129; + gte r129 r102 into r130; + ternary r130 r129 r102 into r131; + ternary r130 r102 r129 into r132; + sub r131 r132 into r133; + gt r133 0u128 into r134; + ternary r134 r133 1u128 into r135; + sub 340282366920938463463374607431768211455u128 r135 into r136; + add r136 1u128 into r137; + ternary r130 r133 r137 into r138; + gte r120 r16.fee_growth_inside0_last_64 into r139; + ternary r139 r120 r16.fee_growth_inside0_last_64 into r140; + ternary r139 r16.fee_growth_inside0_last_64 r120 into r141; + sub r140 r141 into r142; + gt r142 0u128 into r143; + ternary r143 r142 1u128 into r144; + sub 340282366920938463463374607431768211455u128 r144 into r145; + add r145 1u128 into r146; + ternary r139 r142 r146 into r147; + and r147 18446744073709551615u128 into r148; + shr r147 64u8 into r149; + and r16.liquidity 18446744073709551615u128 into r150; + shr r16.liquidity 64u8 into r151; + mul r148 r150 into r152; + mul r148 r151 into r153; + mul r149 r150 into r154; + mul r149 r151 into r155; + and r152 18446744073709551615u128 into r156; + shr r152 64u8 into r157; + and r153 18446744073709551615u128 into r158; + add r157 r158 into r159; + and r154 18446744073709551615u128 into r160; + add r159 r160 into r161; + and r161 18446744073709551615u128 into r162; + shr r161 64u8 into r163; + shr r153 64u8 into r164; + shr r154 64u8 into r165; + add r164 r165 into r166; + and r155 18446744073709551615u128 into r167; + add r166 r167 into r168; + add r168 r163 into r169; + and r169 18446744073709551615u128 into r170; + shr r169 64u8 into r171; + shr r155 64u8 into r172; + add r172 r171 into r173; + shl r162 64u8 into r174; + add r174 r156 into r175; + shl r173 64u8 into r176; + add r176 r170 into r177; + shl r177 65u8 into r178; + shr r175 63u8 into r179; + add r178 r179 into r180; + add r16.tokens_owed0 r180 into r181; + add r181 r20 into r182; + gte r138 r16.fee_growth_inside1_last_64 into r183; + ternary r183 r138 r16.fee_growth_inside1_last_64 into r184; + ternary r183 r16.fee_growth_inside1_last_64 r138 into r185; + sub r184 r185 into r186; + gt r186 0u128 into r187; + ternary r187 r186 1u128 into r188; + sub 340282366920938463463374607431768211455u128 r188 into r189; + add r189 1u128 into r190; + ternary r183 r186 r190 into r191; + and r191 18446744073709551615u128 into r192; + shr r191 64u8 into r193; + and r16.liquidity 18446744073709551615u128 into r194; + shr r16.liquidity 64u8 into r195; + mul r192 r194 into r196; + mul r192 r195 into r197; + mul r193 r194 into r198; + mul r193 r195 into r199; + and r196 18446744073709551615u128 into r200; + shr r196 64u8 into r201; + and r197 18446744073709551615u128 into r202; + add r201 r202 into r203; + and r198 18446744073709551615u128 into r204; + add r203 r204 into r205; + and r205 18446744073709551615u128 into r206; + shr r205 64u8 into r207; + shr r197 64u8 into r208; + shr r198 64u8 into r209; + add r208 r209 into r210; + and r199 18446744073709551615u128 into r211; + add r210 r211 into r212; + add r212 r207 into r213; + and r213 18446744073709551615u128 into r214; + shr r213 64u8 into r215; + shr r199 64u8 into r216; + add r216 r215 into r217; + shl r206 64u8 into r218; + add r218 r200 into r219; + shl r217 64u8 into r220; + add r220 r214 into r221; + shl r221 65u8 into r222; + shr r219 63u8 into r223; + add r222 r223 into r224; + add r16.tokens_owed1 r224 into r225; + add r225 r21 into r226; + sub r16.liquidity r4 into r227; + cast r0 r16.pool r16.tick_lower r16.tick_upper r227 r120 r138 r182 r226 into r228 as Position; + set r228 into positions[r0]; + is.eq r17.next_init_below r16.tick_lower into r229; + and r33 r229 into r230; + ternary r230 r26.prev r17.next_init_below into r231; + is.eq r17.next_init_above r16.tick_lower into r232; + and r33 r232 into r233; + ternary r233 r26.next r17.next_init_above into r234; + is.eq r231 r16.tick_upper into r235; + and r35 r235 into r236; + ternary r236 r47.prev r231 into r237; + is.eq r234 r16.tick_upper into r238; + and r35 r238 into r239; + ternary r239 r47.next r234 into r240; + gte r17.tick r16.tick_lower into r241; + lt r17.tick r16.tick_upper into r242; + and r241 r242 into r243; + ternary r243 r4 0u128 into r244; + sub r17.liquidity r244 into r245; + cast r17.tick r17.tick_spacing r17.sqrt_price r17.fee_protocol r245 r17.fee_growth_global0_x_64 r17.fee_growth_global1_x_64 r17.fee_residual0_x_64 r17.fee_residual1_x_64 r17.max_liquidity_per_tick r17.protocol_fees0 r17.protocol_fees1 r237 r240 into r246 as Slot; + set r246 into slots[r16.pool]; + branch.eq r33 false to end_then_0_4; + remove ticks[r23]; + branch.eq true true to end_otherwise_0_5; + position end_then_0_4; + position end_otherwise_0_5; + branch.eq r35 false to end_then_0_6; + remove ticks[r25]; + branch.eq true true to end_otherwise_0_7; + position end_then_0_6; + position end_otherwise_0_7; + get pools[r1] into r247; + mul r20 r247.scale0 into r248; + gte r248 r5 into r249; + mul r21 r247.scale1 into r250; + gte r250 r6 into r251; + and r249 r251 into r252; + assert.eq r252 true; + +function increase_liquidity: + input r0 as PositionNFT.record; + input r1 as dynamic.record; + input r2 as dynamic.record; + input r3 as u128.public; + input r4 as u128.public; + input r5 as u128.public; + input r6 as u128.public; + input r7 as field.public; + input r8 as field.public; + input r9 as i32.public; + input r10 as i32.public; + cast r0.owner r0.token_id r0.token0_id r0.token1_id r0.pool r0.tick_lower r0.tick_upper into r11 as PositionNFT.record; + call.dynamic r7 'aleo' 'transfer_private_to_public' with r1 shield_swap_v3.aleo r3 (as dynamic.record address.public u128.public) into r12 r13 (as dynamic.record dynamic.future); + call.dynamic r8 'aleo' 'transfer_private_to_public' with r2 shield_swap_v3.aleo r4 (as dynamic.record address.public u128.public) into r14 r15 (as dynamic.record dynamic.future); + async increase_liquidity r13 r15 r0.token_id r0.pool r0.tick_lower r0.tick_upper r3 r4 r5 r6 r7 r8 r9 r10 into r16; + output r0.token_id as field.public; + output r11 as PositionNFT.record; + output r12 as dynamic.record; + output r14 as dynamic.record; + output r16 as shield_swap_v3.aleo/increase_liquidity.future; + +finalize increase_liquidity: + input r0 as dynamic.future; + input r1 as dynamic.future; + input r2 as field.public; + input r3 as field.public; + input r4 as i32.public; + input r5 as i32.public; + input r6 as u128.public; + input r7 as u128.public; + input r8 as u128.public; + input r9 as u128.public; + input r10 as field.public; + input r11 as field.public; + input r12 as i32.public; + input r13 as i32.public; + await r0; + await r1; + get.or_use global_paused[true] false into r14; + not r14 into r15; + assert.eq r15 true; + get pools[r3] into r16; + assert.eq r16.enabled true; + get.or_use token_paused[r16.token0] false into r17; + not r17 into r18; + assert.eq r18 true; + get.or_use token_paused[r16.token1] false into r19; + not r19 into r20; + assert.eq r20 true; + cast r16.token0 r16.token1 into r21 as PairKey; + get.or_use pair_paused[r21] false into r22; + not r22 into r23; + assert.eq r23 true; + is.eq r16.token0 r10 into r24; + assert.eq r24 true; + is.eq r16.token1 r11 into r25; + assert.eq r25 true; + get slots[r3] into r26; + get positions[r2] into r27; + contains frozen_position[r2] into r28; + not r28 into r29; + assert.eq r29 true; + is.eq r27.pool r3 into r30; + is.eq r27.tick_lower r4 into r31; + and r30 r31 into r32; + is.eq r27.tick_upper r5 into r33; + and r32 r33 into r34; + assert.eq r34 true; + call view_sqrt_price_at_tick r4 into r35; + call view_sqrt_price_at_tick r5 into r36; + rem r6 r16.scale0 into r37; + is.eq r37 0u128 into r38; + assert.eq r38 true; + rem r7 r16.scale1 into r39; + is.eq r39 0u128 into r40; + assert.eq r40 true; + div r6 r16.scale0 into r41; + div r7 r16.scale1 into r42; + call view_liquidity_for_amounts r26.sqrt_price r35 r36 r41 r42 into r43; + gt r43 0u128 into r44; + assert.eq r44 true; + call view_amounts_for_liquidity r26.sqrt_price r35 r36 r43 false into r45 r46; + lte r45 r41 into r47; + lte r46 r42 into r48; + and r47 r48 into r49; + assert.eq r49 true; + mul r45 r16.scale0 into r50; + gte r50 r8 into r51; + mul r46 r16.scale1 into r52; + gte r52 r9 into r53; + and r51 r53 into r54; + assert.eq r54 true; + lt r26.sqrt_price r36 into r55; + branch.eq r55 false to end_then_0_0; + gt r45 0u128 into r56; + assert.eq r56 true; + branch.eq true true to end_otherwise_0_1; + position end_then_0_0; + position end_otherwise_0_1; + gt r26.sqrt_price r35 into r57; + branch.eq r57 false to end_then_0_2; + gt r46 0u128 into r58; + assert.eq r58 true; + branch.eq true true to end_otherwise_0_3; + position end_then_0_2; + position end_otherwise_0_3; + cast r3 r4 into r59 as TickKey; + hash.bhp256 r59 into r60 as field; + cast r3 r5 into r61 as TickKey; + hash.bhp256 r61 into r62 as field; + cast r3 0i128 0u128 r4 0u128 0u128 0i32 0i32 into r63 as Tick; + cast r3 0i128 0u128 r5 0u128 0u128 0i32 0i32 into r64 as Tick; + get.or_use ticks[r60] r63 into r65; + get.or_use ticks[r62] r64 into r66; + gt r65.liquidity_gross 0u128 into r67; + gt r66.liquidity_gross 0u128 into r68; + add r65.liquidity_gross r43 into r69; + add r66.liquidity_gross r43 into r70; + lte r69 r26.max_liquidity_per_tick into r71; + assert.eq r71 true; + lte r70 r26.max_liquidity_per_tick into r72; + assert.eq r72 true; + not r67 into r73; + lte r4 r26.tick into r74; + and r73 r74 into r75; + ternary r75 r26.fee_growth_global0_x_64 r65.fee_growth_outside0_64 into r76; + lte r4 r26.tick into r77; + and r73 r77 into r78; + ternary r78 r26.fee_growth_global1_x_64 r65.fee_growth_outside1_64 into r79; + not r68 into r80; + lte r5 r26.tick into r81; + and r80 r81 into r82; + ternary r82 r26.fee_growth_global0_x_64 r66.fee_growth_outside0_64 into r83; + lte r5 r26.tick into r84; + and r80 r84 into r85; + ternary r85 r26.fee_growth_global1_x_64 r66.fee_growth_outside1_64 into r86; + ternary r67 -400001i32 r12 into r87; + cast r3 r87 into r88 as TickKey; + hash.bhp256 r88 into r89 as field; + get ticks[r89] into r90; + branch.eq r73 false to end_then_0_4; + is.eq r90.pool r3 into r91; + assert.eq r91 true; + is.eq r90.tick r12 into r92; + assert.eq r92 true; + is.eq r12 -400001i32 into r93; + gt r90.liquidity_gross 0u128 into r94; + or r93 r94 into r95; + assert.eq r95 true; + lt r90.tick r4 into r96; + assert.eq r96 true; + gt r90.next r4 into r97; + assert.eq r97 true; + branch.eq true true to end_otherwise_0_5; + position end_then_0_4; + position end_otherwise_0_5; + ternary r67 r65.prev r12 into r98; + ternary r67 r65.next r90.next into r99; + cast r43 into r100 as i128; + add r65.liquidity_net r100 into r101; + cast r3 r101 r69 r4 r76 r79 r98 r99 into r102 as Tick; + set r102 into ticks[r60]; + branch.eq r73 false to end_then_0_6; + cast r90.pool r90.liquidity_net r90.liquidity_gross r90.tick r90.fee_growth_outside0_64 r90.fee_growth_outside1_64 r90.prev r4 into r103 as Tick; + set r103 into ticks[r89]; + cast r3 r99 into r104 as TickKey; + hash.bhp256 r104 into r105 as field; + get ticks[r105] into r106; + cast r106.pool r106.liquidity_net r106.liquidity_gross r106.tick r106.fee_growth_outside0_64 r106.fee_growth_outside1_64 r4 r106.next into r107 as Tick; + set r107 into ticks[r105]; + branch.eq true true to end_otherwise_0_7; + position end_then_0_6; + position end_otherwise_0_7; + get.or_use ticks[r62] r64 into r108; + ternary r68 -400001i32 r13 into r109; + cast r3 r109 into r110 as TickKey; + hash.bhp256 r110 into r111 as field; + get ticks[r111] into r112; + branch.eq r80 false to end_then_0_8; + is.eq r112.pool r3 into r113; + assert.eq r113 true; + is.eq r112.tick r13 into r114; + assert.eq r114 true; + is.eq r13 -400001i32 into r115; + gt r112.liquidity_gross 0u128 into r116; + or r115 r116 into r117; + assert.eq r117 true; + lt r112.tick r5 into r118; + assert.eq r118 true; + gt r112.next r5 into r119; + assert.eq r119 true; + branch.eq true true to end_otherwise_0_9; + position end_then_0_8; + position end_otherwise_0_9; + ternary r68 r108.prev r13 into r120; + ternary r68 r108.next r112.next into r121; + cast r43 into r122 as i128; + sub r108.liquidity_net r122 into r123; + cast r3 r123 r70 r5 r83 r86 r120 r121 into r124 as Tick; + set r124 into ticks[r62]; + branch.eq r80 false to end_then_0_10; + get ticks[r111] into r125; + cast r125.pool r125.liquidity_net r125.liquidity_gross r125.tick r125.fee_growth_outside0_64 r125.fee_growth_outside1_64 r125.prev r5 into r126 as Tick; + set r126 into ticks[r111]; + cast r3 r121 into r127 as TickKey; + hash.bhp256 r127 into r128 as field; + get ticks[r128] into r129; + cast r129.pool r129.liquidity_net r129.liquidity_gross r129.tick r129.fee_growth_outside0_64 r129.fee_growth_outside1_64 r5 r129.next into r130 as Tick; + set r130 into ticks[r128]; + branch.eq true true to end_otherwise_0_11; + position end_then_0_10; + position end_otherwise_0_11; + get ticks[r60] into r131; + get ticks[r62] into r132; + gte r26.tick r131.tick into r133; + gte r26.fee_growth_global0_x_64 r131.fee_growth_outside0_64 into r134; + ternary r134 r26.fee_growth_global0_x_64 r131.fee_growth_outside0_64 into r135; + ternary r134 r131.fee_growth_outside0_64 r26.fee_growth_global0_x_64 into r136; + sub r135 r136 into r137; + gt r137 0u128 into r138; + ternary r138 r137 1u128 into r139; + sub 340282366920938463463374607431768211455u128 r139 into r140; + add r140 1u128 into r141; + ternary r134 r137 r141 into r142; + gte r26.fee_growth_global1_x_64 r131.fee_growth_outside1_64 into r143; + ternary r143 r26.fee_growth_global1_x_64 r131.fee_growth_outside1_64 into r144; + ternary r143 r131.fee_growth_outside1_64 r26.fee_growth_global1_x_64 into r145; + sub r144 r145 into r146; + gt r146 0u128 into r147; + ternary r147 r146 1u128 into r148; + sub 340282366920938463463374607431768211455u128 r148 into r149; + add r149 1u128 into r150; + ternary r143 r146 r150 into r151; + ternary r133 r131.fee_growth_outside0_64 r142 into r152; + ternary r133 r131.fee_growth_outside1_64 r151 into r153; + lt r26.tick r132.tick into r154; + gte r26.fee_growth_global0_x_64 r132.fee_growth_outside0_64 into r155; + ternary r155 r26.fee_growth_global0_x_64 r132.fee_growth_outside0_64 into r156; + ternary r155 r132.fee_growth_outside0_64 r26.fee_growth_global0_x_64 into r157; + sub r156 r157 into r158; + gt r158 0u128 into r159; + ternary r159 r158 1u128 into r160; + sub 340282366920938463463374607431768211455u128 r160 into r161; + add r161 1u128 into r162; + ternary r155 r158 r162 into r163; + gte r26.fee_growth_global1_x_64 r132.fee_growth_outside1_64 into r164; + ternary r164 r26.fee_growth_global1_x_64 r132.fee_growth_outside1_64 into r165; + ternary r164 r132.fee_growth_outside1_64 r26.fee_growth_global1_x_64 into r166; + sub r165 r166 into r167; + gt r167 0u128 into r168; + ternary r168 r167 1u128 into r169; + sub 340282366920938463463374607431768211455u128 r169 into r170; + add r170 1u128 into r171; + ternary r164 r167 r171 into r172; + ternary r154 r132.fee_growth_outside0_64 r163 into r173; + ternary r154 r132.fee_growth_outside1_64 r172 into r174; + gte r26.fee_growth_global0_x_64 r152 into r175; + ternary r175 r26.fee_growth_global0_x_64 r152 into r176; + ternary r175 r152 r26.fee_growth_global0_x_64 into r177; + sub r176 r177 into r178; + gt r178 0u128 into r179; + ternary r179 r178 1u128 into r180; + sub 340282366920938463463374607431768211455u128 r180 into r181; + add r181 1u128 into r182; + ternary r175 r178 r182 into r183; + gte r183 r173 into r184; + ternary r184 r183 r173 into r185; + ternary r184 r173 r183 into r186; + sub r185 r186 into r187; + gt r187 0u128 into r188; + ternary r188 r187 1u128 into r189; + sub 340282366920938463463374607431768211455u128 r189 into r190; + add r190 1u128 into r191; + ternary r184 r187 r191 into r192; + gte r26.fee_growth_global1_x_64 r153 into r193; + ternary r193 r26.fee_growth_global1_x_64 r153 into r194; + ternary r193 r153 r26.fee_growth_global1_x_64 into r195; + sub r194 r195 into r196; + gt r196 0u128 into r197; + ternary r197 r196 1u128 into r198; + sub 340282366920938463463374607431768211455u128 r198 into r199; + add r199 1u128 into r200; + ternary r193 r196 r200 into r201; + gte r201 r174 into r202; + ternary r202 r201 r174 into r203; + ternary r202 r174 r201 into r204; + sub r203 r204 into r205; + gt r205 0u128 into r206; + ternary r206 r205 1u128 into r207; + sub 340282366920938463463374607431768211455u128 r207 into r208; + add r208 1u128 into r209; + ternary r202 r205 r209 into r210; + gte r192 r27.fee_growth_inside0_last_64 into r211; + ternary r211 r192 r27.fee_growth_inside0_last_64 into r212; + ternary r211 r27.fee_growth_inside0_last_64 r192 into r213; + sub r212 r213 into r214; + gt r214 0u128 into r215; + ternary r215 r214 1u128 into r216; + sub 340282366920938463463374607431768211455u128 r216 into r217; + add r217 1u128 into r218; + ternary r211 r214 r218 into r219; + and r219 18446744073709551615u128 into r220; + shr r219 64u8 into r221; + and r27.liquidity 18446744073709551615u128 into r222; + shr r27.liquidity 64u8 into r223; + mul r220 r222 into r224; + mul r220 r223 into r225; + mul r221 r222 into r226; + mul r221 r223 into r227; + and r224 18446744073709551615u128 into r228; + shr r224 64u8 into r229; + and r225 18446744073709551615u128 into r230; + add r229 r230 into r231; + and r226 18446744073709551615u128 into r232; + add r231 r232 into r233; + and r233 18446744073709551615u128 into r234; + shr r233 64u8 into r235; + shr r225 64u8 into r236; + shr r226 64u8 into r237; + add r236 r237 into r238; + and r227 18446744073709551615u128 into r239; + add r238 r239 into r240; + add r240 r235 into r241; + and r241 18446744073709551615u128 into r242; + shr r241 64u8 into r243; + shr r227 64u8 into r244; + add r244 r243 into r245; + shl r234 64u8 into r246; + add r246 r228 into r247; + shl r245 64u8 into r248; + add r248 r242 into r249; + shl r249 65u8 into r250; + shr r247 63u8 into r251; + add r250 r251 into r252; + gte r210 r27.fee_growth_inside1_last_64 into r253; + ternary r253 r210 r27.fee_growth_inside1_last_64 into r254; + ternary r253 r27.fee_growth_inside1_last_64 r210 into r255; + sub r254 r255 into r256; + gt r256 0u128 into r257; + ternary r257 r256 1u128 into r258; + sub 340282366920938463463374607431768211455u128 r258 into r259; + add r259 1u128 into r260; + ternary r253 r256 r260 into r261; + and r261 18446744073709551615u128 into r262; + shr r261 64u8 into r263; + and r27.liquidity 18446744073709551615u128 into r264; + shr r27.liquidity 64u8 into r265; + mul r262 r264 into r266; + mul r262 r265 into r267; + mul r263 r264 into r268; + mul r263 r265 into r269; + and r266 18446744073709551615u128 into r270; + shr r266 64u8 into r271; + and r267 18446744073709551615u128 into r272; + add r271 r272 into r273; + and r268 18446744073709551615u128 into r274; + add r273 r274 into r275; + and r275 18446744073709551615u128 into r276; + shr r275 64u8 into r277; + shr r267 64u8 into r278; + shr r268 64u8 into r279; + add r278 r279 into r280; + and r269 18446744073709551615u128 into r281; + add r280 r281 into r282; + add r282 r277 into r283; + and r283 18446744073709551615u128 into r284; + shr r283 64u8 into r285; + shr r269 64u8 into r286; + add r286 r285 into r287; + shl r276 64u8 into r288; + add r288 r270 into r289; + shl r287 64u8 into r290; + add r290 r284 into r291; + shl r291 65u8 into r292; + shr r289 63u8 into r293; + add r292 r293 into r294; + sub r41 r45 into r295; + sub r42 r46 into r296; + add r27.liquidity r43 into r297; + add r27.tokens_owed0 r252 into r298; + add r298 r295 into r299; + add r27.tokens_owed1 r294 into r300; + add r300 r296 into r301; + cast r2 r3 r4 r5 r297 r192 r210 r299 r301 into r302 as Position; + set r302 into positions[r2]; + lte r4 r26.tick into r303; + and r73 r303 into r304; + gt r4 r26.next_init_below into r305; + and r304 r305 into r306; + ternary r306 r4 r26.next_init_below into r307; + gt r4 r26.tick into r308; + and r73 r308 into r309; + lt r4 r26.next_init_above into r310; + and r309 r310 into r311; + ternary r311 r4 r26.next_init_above into r312; + lte r5 r26.tick into r313; + and r80 r313 into r314; + gt r5 r307 into r315; + and r314 r315 into r316; + ternary r316 r5 r307 into r317; + gt r5 r26.tick into r318; + and r80 r318 into r319; + lt r5 r312 into r320; + and r319 r320 into r321; + ternary r321 r5 r312 into r322; + gte r26.tick r4 into r323; + lt r26.tick r5 into r324; + and r323 r324 into r325; + add r26.liquidity r43 into r326; + ternary r325 r326 r26.liquidity into r327; + cast r26.tick r26.tick_spacing r26.sqrt_price r26.fee_protocol r327 r26.fee_growth_global0_x_64 r26.fee_growth_global1_x_64 r26.fee_residual0_x_64 r26.fee_residual1_x_64 r26.max_liquidity_per_tick r26.protocol_fees0 r26.protocol_fees1 r317 r322 into r328 as Slot; + set r328 into slots[r3]; + +function collect: + input r0 as PositionNFT.record; + input r1 as u128.public; + input r2 as u128.public; + input r3 as field.public; + input r4 as field.public; + input r5 as address.private; + assert.neq r5 shield_swap_v3.aleo; + cast r0.owner r0.token_id r0.token0_id r0.token1_id r0.pool r0.tick_lower r0.tick_upper into r6 as PositionNFT.record; + call.dynamic r3 'aleo' 'transfer_public_to_private' with r5 r1 (as address.private u128.public) into r7 r8 (as dynamic.record dynamic.future); + call.dynamic r4 'aleo' 'transfer_public_to_private' with r5 r2 (as address.private u128.public) into r9 r10 (as dynamic.record dynamic.future); + async collect r8 r10 r0.token_id r0.pool r0.tick_lower r0.tick_upper r1 r2 r3 r4 into r11; + output r6 as PositionNFT.record; + output r7 as dynamic.record; + output r9 as dynamic.record; + output r11 as shield_swap_v3.aleo/collect.future; + +finalize collect: + input r0 as dynamic.future; + input r1 as dynamic.future; + input r2 as field.public; + input r3 as field.public; + input r4 as i32.public; + input r5 as i32.public; + input r6 as u128.public; + input r7 as u128.public; + input r8 as field.public; + input r9 as field.public; + await r0; + await r1; + get pools[r3] into r10; + is.eq r10.token0 r8 into r11; + is.eq r10.token1 r9 into r12; + and r11 r12 into r13; + assert.eq r13 true; + get slots[r3] into r14; + get positions[r2] into r15; + contains frozen_position[r2] into r16; + not r16 into r17; + assert.eq r17 true; + is.eq r15.pool r3 into r18; + is.eq r15.tick_lower r4 into r19; + and r18 r19 into r20; + is.eq r15.tick_upper r5 into r21; + and r20 r21 into r22; + assert.eq r22 true; + cast r3 0i128 0u128 r4 0u128 0u128 0i32 0i32 into r23 as Tick; + cast r3 0i128 0u128 r5 0u128 0u128 0i32 0i32 into r24 as Tick; + cast r3 r4 into r25 as TickKey; + hash.bhp256 r25 into r26 as field; + get.or_use ticks[r26] r23 into r27; + cast r3 r5 into r28 as TickKey; + hash.bhp256 r28 into r29 as field; + get.or_use ticks[r29] r24 into r30; + gte r14.tick r27.tick into r31; + gte r14.fee_growth_global0_x_64 r27.fee_growth_outside0_64 into r32; + ternary r32 r14.fee_growth_global0_x_64 r27.fee_growth_outside0_64 into r33; + ternary r32 r27.fee_growth_outside0_64 r14.fee_growth_global0_x_64 into r34; + sub r33 r34 into r35; + gt r35 0u128 into r36; + ternary r36 r35 1u128 into r37; + sub 340282366920938463463374607431768211455u128 r37 into r38; + add r38 1u128 into r39; + ternary r32 r35 r39 into r40; + gte r14.fee_growth_global1_x_64 r27.fee_growth_outside1_64 into r41; + ternary r41 r14.fee_growth_global1_x_64 r27.fee_growth_outside1_64 into r42; + ternary r41 r27.fee_growth_outside1_64 r14.fee_growth_global1_x_64 into r43; + sub r42 r43 into r44; + gt r44 0u128 into r45; + ternary r45 r44 1u128 into r46; + sub 340282366920938463463374607431768211455u128 r46 into r47; + add r47 1u128 into r48; + ternary r41 r44 r48 into r49; + ternary r31 r27.fee_growth_outside0_64 r40 into r50; + ternary r31 r27.fee_growth_outside1_64 r49 into r51; + lt r14.tick r30.tick into r52; + gte r14.fee_growth_global0_x_64 r30.fee_growth_outside0_64 into r53; + ternary r53 r14.fee_growth_global0_x_64 r30.fee_growth_outside0_64 into r54; + ternary r53 r30.fee_growth_outside0_64 r14.fee_growth_global0_x_64 into r55; + sub r54 r55 into r56; + gt r56 0u128 into r57; + ternary r57 r56 1u128 into r58; + sub 340282366920938463463374607431768211455u128 r58 into r59; + add r59 1u128 into r60; + ternary r53 r56 r60 into r61; + gte r14.fee_growth_global1_x_64 r30.fee_growth_outside1_64 into r62; + ternary r62 r14.fee_growth_global1_x_64 r30.fee_growth_outside1_64 into r63; + ternary r62 r30.fee_growth_outside1_64 r14.fee_growth_global1_x_64 into r64; + sub r63 r64 into r65; + gt r65 0u128 into r66; + ternary r66 r65 1u128 into r67; + sub 340282366920938463463374607431768211455u128 r67 into r68; + add r68 1u128 into r69; + ternary r62 r65 r69 into r70; + ternary r52 r30.fee_growth_outside0_64 r61 into r71; + ternary r52 r30.fee_growth_outside1_64 r70 into r72; + gte r14.fee_growth_global0_x_64 r50 into r73; + ternary r73 r14.fee_growth_global0_x_64 r50 into r74; + ternary r73 r50 r14.fee_growth_global0_x_64 into r75; + sub r74 r75 into r76; + gt r76 0u128 into r77; + ternary r77 r76 1u128 into r78; + sub 340282366920938463463374607431768211455u128 r78 into r79; + add r79 1u128 into r80; + ternary r73 r76 r80 into r81; + gte r81 r71 into r82; + ternary r82 r81 r71 into r83; + ternary r82 r71 r81 into r84; + sub r83 r84 into r85; + gt r85 0u128 into r86; + ternary r86 r85 1u128 into r87; + sub 340282366920938463463374607431768211455u128 r87 into r88; + add r88 1u128 into r89; + ternary r82 r85 r89 into r90; + gte r14.fee_growth_global1_x_64 r51 into r91; + ternary r91 r14.fee_growth_global1_x_64 r51 into r92; + ternary r91 r51 r14.fee_growth_global1_x_64 into r93; + sub r92 r93 into r94; + gt r94 0u128 into r95; + ternary r95 r94 1u128 into r96; + sub 340282366920938463463374607431768211455u128 r96 into r97; + add r97 1u128 into r98; + ternary r91 r94 r98 into r99; + gte r99 r72 into r100; + ternary r100 r99 r72 into r101; + ternary r100 r72 r99 into r102; + sub r101 r102 into r103; + gt r103 0u128 into r104; + ternary r104 r103 1u128 into r105; + sub 340282366920938463463374607431768211455u128 r105 into r106; + add r106 1u128 into r107; + ternary r100 r103 r107 into r108; + rem r6 r10.scale0 into r109; + is.eq r109 0u128 into r110; + rem r7 r10.scale1 into r111; + is.eq r111 0u128 into r112; + and r110 r112 into r113; + assert.eq r113 true; + div r6 r10.scale0 into r114; + div r7 r10.scale1 into r115; + gte r90 r15.fee_growth_inside0_last_64 into r116; + ternary r116 r90 r15.fee_growth_inside0_last_64 into r117; + ternary r116 r15.fee_growth_inside0_last_64 r90 into r118; + sub r117 r118 into r119; + gt r119 0u128 into r120; + ternary r120 r119 1u128 into r121; + sub 340282366920938463463374607431768211455u128 r121 into r122; + add r122 1u128 into r123; + ternary r116 r119 r123 into r124; + and r124 18446744073709551615u128 into r125; + shr r124 64u8 into r126; + and r15.liquidity 18446744073709551615u128 into r127; + shr r15.liquidity 64u8 into r128; + mul r125 r127 into r129; + mul r125 r128 into r130; + mul r126 r127 into r131; + mul r126 r128 into r132; + and r129 18446744073709551615u128 into r133; + shr r129 64u8 into r134; + and r130 18446744073709551615u128 into r135; + add r134 r135 into r136; + and r131 18446744073709551615u128 into r137; + add r136 r137 into r138; + and r138 18446744073709551615u128 into r139; + shr r138 64u8 into r140; + shr r130 64u8 into r141; + shr r131 64u8 into r142; + add r141 r142 into r143; + and r132 18446744073709551615u128 into r144; + add r143 r144 into r145; + add r145 r140 into r146; + and r146 18446744073709551615u128 into r147; + shr r146 64u8 into r148; + shr r132 64u8 into r149; + add r149 r148 into r150; + shl r139 64u8 into r151; + add r151 r133 into r152; + shl r150 64u8 into r153; + add r153 r147 into r154; + shl r154 65u8 into r155; + shr r152 63u8 into r156; + add r155 r156 into r157; + add r15.tokens_owed0 r157 into r158; + gte r108 r15.fee_growth_inside1_last_64 into r159; + ternary r159 r108 r15.fee_growth_inside1_last_64 into r160; + ternary r159 r15.fee_growth_inside1_last_64 r108 into r161; + sub r160 r161 into r162; + gt r162 0u128 into r163; + ternary r163 r162 1u128 into r164; + sub 340282366920938463463374607431768211455u128 r164 into r165; + add r165 1u128 into r166; + ternary r159 r162 r166 into r167; + and r167 18446744073709551615u128 into r168; + shr r167 64u8 into r169; + and r15.liquidity 18446744073709551615u128 into r170; + shr r15.liquidity 64u8 into r171; + mul r168 r170 into r172; + mul r168 r171 into r173; + mul r169 r170 into r174; + mul r169 r171 into r175; + and r172 18446744073709551615u128 into r176; + shr r172 64u8 into r177; + and r173 18446744073709551615u128 into r178; + add r177 r178 into r179; + and r174 18446744073709551615u128 into r180; + add r179 r180 into r181; + and r181 18446744073709551615u128 into r182; + shr r181 64u8 into r183; + shr r173 64u8 into r184; + shr r174 64u8 into r185; + add r184 r185 into r186; + and r175 18446744073709551615u128 into r187; + add r186 r187 into r188; + add r188 r183 into r189; + and r189 18446744073709551615u128 into r190; + shr r189 64u8 into r191; + shr r175 64u8 into r192; + add r192 r191 into r193; + shl r182 64u8 into r194; + add r194 r176 into r195; + shl r193 64u8 into r196; + add r196 r190 into r197; + shl r197 65u8 into r198; + shr r195 63u8 into r199; + add r198 r199 into r200; + add r15.tokens_owed1 r200 into r201; + lte r114 r158 into r202; + lte r115 r201 into r203; + and r202 r203 into r204; + assert.eq r204 true; + sub r158 r114 into r205; + sub r201 r115 into r206; + cast r2 r3 r4 r5 r15.liquidity r90 r108 r205 r206 into r207 as Position; + set r207 into positions[r2]; + +function burn: + input r0 as PositionNFT.record; + async burn r0.token_id into r1; + output r0.token_id as field.public; + output self.signer as address.public; + output r1 as shield_swap_v3.aleo/burn.future; + +finalize burn: + input r0 as field.public; + contains frozen_position[r0] into r1; + not r1 into r2; + assert.eq r2 true; + get positions[r0] into r3; + is.eq r3.liquidity 0u128 into r4; + assert.eq r4 true; + is.eq r3.tokens_owed0 0u128 into r5; + assert.eq r5 true; + is.eq r3.tokens_owed1 0u128 into r6; + assert.eq r6 true; + remove positions[r0]; + +closure verify_blinded_address: + input r0 as address; + input r1 as address; + input r2 as field; + input r3 as address; + cast r0 into r4 as field; + cast r1 into r5 as field; + cast r4 11835072102227764468342786961086432175093421716844963782363567713633field r5 r2 into r6 as [field; 4u32]; + hash.psd8.raw r6 into r7 as address; + assert.eq r7 r3; + +view view_swap_iteration: + input r0 as SwapIterCfg.public; + input r1 as i32.public; + input r2 as Tick.public; + input r3 as SwapIterState.public; + gte r1 -873409i32 into r4; + lte r1 873409i32 into r5; + and r4 r5 into r6; + assert.eq r6 true; + lt r1 0i32 into r7; + sub 0i32 r1 into r8; + ternary r7 r8 r1 into r9; + gte r9 0i32 into r10; + assert.eq r10 true; + cast r9 into r11 as u32; + and r11 3u32 into r12; + is.eq r12 0u32 into r13; + is.eq r12 1u32 into r14; + is.eq r12 2u32 into r15; + ternary r15 9222449791875588096u128 9221988703967300608u128 into r16; + ternary r14 9222910902837697536u128 r16 into r17; + ternary r13 9223372036854775808u128 r17 into r18; + and r11 4u32 into r19; + is.neq r19 0u32 into r20; + mul r18 9221527639111677952u128 into r21; + shr r21 63u8 into r22; + ternary r20 r22 r18 into r23; + and r11 8u32 into r24; + is.neq r24 0u32 into r25; + mul r23 9219683610192801792u128 into r26; + shr r26 63u8 into r27; + ternary r25 r27 r23 into r28; + and r11 16u32 into r29; + is.neq r29 0u32 into r30; + mul r28 9215996658532725760u128 into r31; + shr r31 63u8 into r32; + ternary r30 r32 r28 into r33; + and r11 32u32 into r34; + is.neq r34 0u32 into r35; + mul r33 9208627177859081216u128 into r36; + shr r36 63u8 into r37; + ternary r35 r37 r33 into r38; + and r11 64u32 into r39; + is.neq r39 0u32 into r40; + mul r38 9193905890596798464u128 into r41; + shr r41 63u8 into r42; + ternary r40 r42 r38 into r43; + and r11 128u32 into r44; + is.neq r44 0u32 into r45; + mul r43 9164533880601766912u128 into r46; + shr r46 63u8 into r47; + ternary r45 r47 r43 into r48; + and r11 256u32 into r49; + is.neq r49 0u32 into r50; + mul r48 9106071067403056128u128 into r51; + shr r51 63u8 into r52; + ternary r50 r52 r48 into r53; + and r11 512u32 into r54; + is.neq r54 0u32 into r55; + mul r53 8990261907820801024u128 into r56; + shr r56 63u8 into r57; + ternary r55 r57 r53 into r58; + and r11 1024u32 into r59; + is.neq r59 0u32 into r60; + mul r58 8763043369415622656u128 into r61; + shr r61 63u8 into r62; + ternary r60 r62 r58 into r63; + and r11 2048u32 into r64; + is.neq r64 0u32 into r65; + mul r63 8325689215117605888u128 into r66; + shr r66 63u8 into r67; + ternary r65 r67 r63 into r68; + and r11 4096u32 into r69; + is.neq r69 0u32 into r70; + mul r68 7515375139346884608u128 into r71; + shr r71 63u8 into r72; + ternary r70 r72 r68 into r73; + and r11 8192u32 into r74; + is.neq r74 0u32 into r75; + mul r73 6123667489441693696u128 into r76; + shr r76 63u8 into r77; + ternary r75 r77 r73 into r78; + and r11 16384u32 into r79; + is.neq r79 0u32 into r80; + mul r78 4065682634442729984u128 into r81; + shr r81 63u8 into r82; + ternary r80 r82 r78 into r83; + and r11 32768u32 into r84; + is.neq r84 0u32 into r85; + mul r83 1792161827361994496u128 into r86; + shr r86 63u8 into r87; + ternary r85 r87 r83 into r88; + and r11 65536u32 into r89; + is.neq r89 0u32 into r90; + mul r88 348228825923923264u128 into r91; + shr r91 63u8 into r92; + ternary r90 r92 r88 into r93; + and r11 131072u32 into r94; + is.neq r94 0u32 into r95; + mul r93 13147394978735516u128 into r96; + shr r96 63u8 into r97; + ternary r95 r97 r93 into r98; + and r11 262144u32 into r99; + is.neq r99 0u32 into r100; + mul r98 18740867660568u128 into r101; + shr r101 63u8 into r102; + ternary r100 r102 r98 into r103; + and r11 524288u32 into r104; + is.neq r104 0u32 into r105; + mul r103 38079361u128 into r106; + shr r106 63u8 into r107; + ternary r105 r107 r103 into r108; + gt r1 0i32 into r109; + div 85070591730234615865843651857942052864u128 r108 into r110; + ternary r109 r110 r108 into r111; + lt r111 r0.lim into r112; + ternary r112 r0.lim r111 into r113; + gt r111 r0.lim into r114; + ternary r114 r0.lim r111 into r115; + ternary r0.z r113 r115 into r116; + gt r3.rem 0u128 into r117; + and r3.crossed r117 into r118; + is.eq r3.liq 0u128 into r119; + and r118 r119 into r120; + gt r3.liq 0u128 into r121; + and r117 r121 into r122; + and r122 r3.crossed into r123; + gt r116 r3.sp into r124; + ternary r124 r3.sp r116 into r125; + ternary r124 r116 r3.sp into r126; + gt r125 0u128 into r127; + gt r126 0u128 into r128; + and r127 r128 into r129; + ternary r128 r126 1u128 into r130; + ternary r127 r125 1u128 into r131; + and r3.liq 18446744073709551615u128 into r132; + shr r3.liq 64u8 into r133; + mul r132 9223372036854775808u128 into r134; + mul r133 9223372036854775808u128 into r135; + and r134 18446744073709551615u128 into r136; + shr r134 64u8 into r137; + and r135 18446744073709551615u128 into r138; + add r137 r138 into r139; + and r139 18446744073709551615u128 into r140; + shr r139 64u8 into r141; + shr r135 64u8 into r142; + add r142 r141 into r143; + and r143 18446744073709551615u128 into r144; + shr r143 64u8 into r145; + shl r140 64u8 into r146; + add r146 r136 into r147; + shl r145 64u8 into r148; + add r148 r144 into r149; + lt r149 r131 into r150; + assert.eq r150 true; + shr r147 96u8 into r151; + and r151 4294967295u128 into r152; + shl r149 32u8 into r153; + add r153 r152 into r154; + div r154 r131 into r155; + rem r154 r131 into r156; + shr r147 64u8 into r157; + and r157 4294967295u128 into r158; + shl r156 32u8 into r159; + add r159 r158 into r160; + shl r155 32u8 into r161; + div r160 r131 into r162; + add r161 r162 into r163; + rem r160 r131 into r164; + shr r147 32u8 into r165; + and r165 4294967295u128 into r166; + shl r164 32u8 into r167; + add r167 r166 into r168; + shl r163 32u8 into r169; + div r168 r131 into r170; + add r169 r170 into r171; + rem r168 r131 into r172; + shr r147 0u8 into r173; + and r173 4294967295u128 into r174; + shl r172 32u8 into r175; + add r175 r174 into r176; + shl r171 32u8 into r177; + div r176 r131 into r178; + add r177 r178 into r179; + rem r176 r131 into r180; + gt r180 0u128 into r181; + add r179 1u128 into r182; + ternary r181 r182 r179 into r183; + add r137 r138 into r184; + and r184 18446744073709551615u128 into r185; + shr r184 64u8 into r186; + add r142 r186 into r187; + and r187 18446744073709551615u128 into r188; + shr r187 64u8 into r189; + shl r185 64u8 into r190; + add r190 r136 into r191; + shl r189 64u8 into r192; + add r192 r188 into r193; + lt r193 r130 into r194; + assert.eq r194 true; + shr r191 96u8 into r195; + and r195 4294967295u128 into r196; + shl r193 32u8 into r197; + add r197 r196 into r198; + div r198 r130 into r199; + rem r198 r130 into r200; + shr r191 64u8 into r201; + and r201 4294967295u128 into r202; + shl r200 32u8 into r203; + add r203 r202 into r204; + shl r199 32u8 into r205; + div r204 r130 into r206; + add r205 r206 into r207; + rem r204 r130 into r208; + shr r191 32u8 into r209; + and r209 4294967295u128 into r210; + shl r208 32u8 into r211; + add r211 r210 into r212; + shl r207 32u8 into r213; + div r212 r130 into r214; + add r213 r214 into r215; + rem r212 r130 into r216; + shr r191 0u8 into r217; + and r217 4294967295u128 into r218; + shl r216 32u8 into r219; + add r219 r218 into r220; + shl r215 32u8 into r221; + div r220 r130 into r222; + add r221 r222 into r223; + rem r220 r130 into r224; + add r223 1u128 into r225; + gte r183 r223 into r226; + ternary r226 r183 r223 into r227; + ternary r226 r223 r183 into r228; + sub r227 r228 into r229; + ternary r226 r229 0u128 into r230; + lt r125 r126 into r231; + and r129 r231 into r232; + ternary r232 r230 0u128 into r233; + gt r3.sp r116 into r234; + ternary r234 r116 r3.sp into r235; + ternary r234 r3.sp r116 into r236; + sub r236 r235 into r237; + and r237 18446744073709551615u128 into r238; + shr r237 64u8 into r239; + mul r132 r238 into r240; + mul r132 r239 into r241; + mul r133 r238 into r242; + mul r133 r239 into r243; + and r240 18446744073709551615u128 into r244; + shr r240 64u8 into r245; + and r241 18446744073709551615u128 into r246; + add r245 r246 into r247; + and r242 18446744073709551615u128 into r248; + add r247 r248 into r249; + and r249 18446744073709551615u128 into r250; + shr r249 64u8 into r251; + shr r241 64u8 into r252; + shr r242 64u8 into r253; + add r252 r253 into r254; + and r243 18446744073709551615u128 into r255; + add r254 r255 into r256; + add r256 r251 into r257; + and r257 18446744073709551615u128 into r258; + shr r257 64u8 into r259; + shr r243 64u8 into r260; + add r260 r259 into r261; + shl r250 64u8 into r262; + add r262 r244 into r263; + shl r261 64u8 into r264; + add r264 r258 into r265; + lt r265 9223372036854775808u128 into r266; + assert.eq r266 true; + shr r263 96u8 into r267; + and r267 4294967295u128 into r268; + shl r265 32u8 into r269; + add r269 r268 into r270; + div r270 9223372036854775808u128 into r271; + rem r270 9223372036854775808u128 into r272; + shr r263 64u8 into r273; + and r273 4294967295u128 into r274; + shl r272 32u8 into r275; + add r275 r274 into r276; + shl r271 32u8 into r277; + div r276 9223372036854775808u128 into r278; + add r277 r278 into r279; + rem r276 9223372036854775808u128 into r280; + shr r263 32u8 into r281; + and r281 4294967295u128 into r282; + shl r280 32u8 into r283; + add r283 r282 into r284; + shl r279 32u8 into r285; + div r284 9223372036854775808u128 into r286; + add r285 r286 into r287; + rem r284 9223372036854775808u128 into r288; + shr r263 0u8 into r289; + and r289 4294967295u128 into r290; + shl r288 32u8 into r291; + add r291 r290 into r292; + shl r287 32u8 into r293; + div r292 9223372036854775808u128 into r294; + add r293 r294 into r295; + rem r292 9223372036854775808u128 into r296; + gt r296 0u128 into r297; + add r295 1u128 into r298; + ternary r297 r298 r295 into r299; + ternary r0.z r233 r299 into r300; + cast r0.fee_pips into r301 as u128; + sub 1000000u128 r301 into r302; + and r3.rem 18446744073709551615u128 into r303; + shr r3.rem 64u8 into r304; + and r302 18446744073709551615u128 into r305; + shr r302 64u8 into r306; + mul r303 r305 into r307; + mul r303 r306 into r308; + mul r304 r305 into r309; + mul r304 r306 into r310; + and r307 18446744073709551615u128 into r311; + shr r307 64u8 into r312; + and r308 18446744073709551615u128 into r313; + add r312 r313 into r314; + and r309 18446744073709551615u128 into r315; + add r314 r315 into r316; + and r316 18446744073709551615u128 into r317; + shr r316 64u8 into r318; + shr r308 64u8 into r319; + shr r309 64u8 into r320; + add r319 r320 into r321; + and r310 18446744073709551615u128 into r322; + add r321 r322 into r323; + add r323 r318 into r324; + and r324 18446744073709551615u128 into r325; + shr r324 64u8 into r326; + shr r310 64u8 into r327; + add r327 r326 into r328; + shl r317 64u8 into r329; + add r329 r311 into r330; + shl r328 64u8 into r331; + add r331 r325 into r332; + lt r332 1000000u128 into r333; + assert.eq r333 true; + shr r330 96u8 into r334; + and r334 4294967295u128 into r335; + shl r332 32u8 into r336; + add r336 r335 into r337; + div r337 1000000u128 into r338; + rem r337 1000000u128 into r339; + shr r330 64u8 into r340; + and r340 4294967295u128 into r341; + shl r339 32u8 into r342; + add r342 r341 into r343; + shl r338 32u8 into r344; + div r343 1000000u128 into r345; + add r344 r345 into r346; + rem r343 1000000u128 into r347; + shr r330 32u8 into r348; + and r348 4294967295u128 into r349; + shl r347 32u8 into r350; + add r350 r349 into r351; + shl r346 32u8 into r352; + div r351 1000000u128 into r353; + add r352 r353 into r354; + rem r351 1000000u128 into r355; + shr r330 0u8 into r356; + and r356 4294967295u128 into r357; + shl r355 32u8 into r358; + add r358 r357 into r359; + shl r354 32u8 into r360; + div r359 1000000u128 into r361; + add r360 r361 into r362; + rem r359 1000000u128 into r363; + add r362 1u128 into r364; + gte r362 r300 into r365; + is.eq r362 0u128 into r366; + shl r189 64u8 into r367; + add r367 r188 into r368; + lt r368 r3.sp into r369; + assert.eq r369 true; + shl r368 32u8 into r370; + add r370 r196 into r371; + div r371 r3.sp into r372; + rem r371 r3.sp into r373; + shl r373 32u8 into r374; + add r374 r202 into r375; + shl r372 32u8 into r376; + div r375 r3.sp into r377; + add r376 r377 into r378; + rem r375 r3.sp into r379; + shl r379 32u8 into r380; + add r380 r210 into r381; + shl r378 32u8 into r382; + div r381 r3.sp into r383; + add r382 r383 into r384; + rem r381 r3.sp into r385; + shl r385 32u8 into r386; + add r386 r218 into r387; + shl r384 32u8 into r388; + div r387 r3.sp into r389; + add r388 r389 into r390; + rem r387 r3.sp into r391; + add r390 1u128 into r392; + add r390 r362 into r393; + gt r362 r390 into r394; + ternary r394 r390 r362 into r395; + sub r390 r395 into r396; + lt r368 r393 into r397; + assert.eq r397 true; + gte r368 170141183460469231731687303715884105728u128 into r398; + add.w r368 r368 into r399; + shr r191 127u8 into r400; + and r400 1u128 into r401; + add r399 r401 into r402; + gte r402 r393 into r403; + or r398 r403 into r404; + sub.w r402 r393 into r405; + ternary r404 r405 r402 into r406; + ternary r404 170141183460469231731687303715884105728u128 0u128 into r407; + gte r406 170141183460469231731687303715884105728u128 into r408; + add.w r406 r406 into r409; + shr r191 126u8 into r410; + and r410 1u128 into r411; + add r409 r411 into r412; + gte r412 r393 into r413; + or r408 r413 into r414; + sub.w r412 r393 into r415; + ternary r414 r415 r412 into r416; + add r407 85070591730234615865843651857942052864u128 into r417; + ternary r414 r417 r407 into r418; + gte r416 170141183460469231731687303715884105728u128 into r419; + add.w r416 r416 into r420; + shr r191 125u8 into r421; + and r421 1u128 into r422; + add r420 r422 into r423; + gte r423 r393 into r424; + or r419 r424 into r425; + sub.w r423 r393 into r426; + ternary r425 r426 r423 into r427; + add r418 42535295865117307932921825928971026432u128 into r428; + ternary r425 r428 r418 into r429; + gte r427 170141183460469231731687303715884105728u128 into r430; + add.w r427 r427 into r431; + shr r191 124u8 into r432; + and r432 1u128 into r433; + add r431 r433 into r434; + gte r434 r393 into r435; + or r430 r435 into r436; + sub.w r434 r393 into r437; + ternary r436 r437 r434 into r438; + add r429 21267647932558653966460912964485513216u128 into r439; + ternary r436 r439 r429 into r440; + gte r438 170141183460469231731687303715884105728u128 into r441; + add.w r438 r438 into r442; + shr r191 123u8 into r443; + and r443 1u128 into r444; + add r442 r444 into r445; + gte r445 r393 into r446; + or r441 r446 into r447; + sub.w r445 r393 into r448; + ternary r447 r448 r445 into r449; + add r440 10633823966279326983230456482242756608u128 into r450; + ternary r447 r450 r440 into r451; + gte r449 170141183460469231731687303715884105728u128 into r452; + add.w r449 r449 into r453; + shr r191 122u8 into r454; + and r454 1u128 into r455; + add r453 r455 into r456; + gte r456 r393 into r457; + or r452 r457 into r458; + sub.w r456 r393 into r459; + ternary r458 r459 r456 into r460; + add r451 5316911983139663491615228241121378304u128 into r461; + ternary r458 r461 r451 into r462; + gte r460 170141183460469231731687303715884105728u128 into r463; + add.w r460 r460 into r464; + shr r191 121u8 into r465; + and r465 1u128 into r466; + add r464 r466 into r467; + gte r467 r393 into r468; + or r463 r468 into r469; + sub.w r467 r393 into r470; + ternary r469 r470 r467 into r471; + add r462 2658455991569831745807614120560689152u128 into r472; + ternary r469 r472 r462 into r473; + gte r471 170141183460469231731687303715884105728u128 into r474; + add.w r471 r471 into r475; + shr r191 120u8 into r476; + and r476 1u128 into r477; + add r475 r477 into r478; + gte r478 r393 into r479; + or r474 r479 into r480; + sub.w r478 r393 into r481; + ternary r480 r481 r478 into r482; + add r473 1329227995784915872903807060280344576u128 into r483; + ternary r480 r483 r473 into r484; + gte r482 170141183460469231731687303715884105728u128 into r485; + add.w r482 r482 into r486; + shr r191 119u8 into r487; + and r487 1u128 into r488; + add r486 r488 into r489; + gte r489 r393 into r490; + or r485 r490 into r491; + sub.w r489 r393 into r492; + ternary r491 r492 r489 into r493; + add r484 664613997892457936451903530140172288u128 into r494; + ternary r491 r494 r484 into r495; + gte r493 170141183460469231731687303715884105728u128 into r496; + add.w r493 r493 into r497; + shr r191 118u8 into r498; + and r498 1u128 into r499; + add r497 r499 into r500; + gte r500 r393 into r501; + or r496 r501 into r502; + sub.w r500 r393 into r503; + ternary r502 r503 r500 into r504; + add r495 332306998946228968225951765070086144u128 into r505; + ternary r502 r505 r495 into r506; + gte r504 170141183460469231731687303715884105728u128 into r507; + add.w r504 r504 into r508; + shr r191 117u8 into r509; + and r509 1u128 into r510; + add r508 r510 into r511; + gte r511 r393 into r512; + or r507 r512 into r513; + sub.w r511 r393 into r514; + ternary r513 r514 r511 into r515; + add r506 166153499473114484112975882535043072u128 into r516; + ternary r513 r516 r506 into r517; + gte r515 170141183460469231731687303715884105728u128 into r518; + add.w r515 r515 into r519; + shr r191 116u8 into r520; + and r520 1u128 into r521; + add r519 r521 into r522; + gte r522 r393 into r523; + or r518 r523 into r524; + sub.w r522 r393 into r525; + ternary r524 r525 r522 into r526; + add r517 83076749736557242056487941267521536u128 into r527; + ternary r524 r527 r517 into r528; + gte r526 170141183460469231731687303715884105728u128 into r529; + add.w r526 r526 into r530; + shr r191 115u8 into r531; + and r531 1u128 into r532; + add r530 r532 into r533; + gte r533 r393 into r534; + or r529 r534 into r535; + sub.w r533 r393 into r536; + ternary r535 r536 r533 into r537; + add r528 41538374868278621028243970633760768u128 into r538; + ternary r535 r538 r528 into r539; + gte r537 170141183460469231731687303715884105728u128 into r540; + add.w r537 r537 into r541; + shr r191 114u8 into r542; + and r542 1u128 into r543; + add r541 r543 into r544; + gte r544 r393 into r545; + or r540 r545 into r546; + sub.w r544 r393 into r547; + ternary r546 r547 r544 into r548; + add r539 20769187434139310514121985316880384u128 into r549; + ternary r546 r549 r539 into r550; + gte r548 170141183460469231731687303715884105728u128 into r551; + add.w r548 r548 into r552; + shr r191 113u8 into r553; + and r553 1u128 into r554; + add r552 r554 into r555; + gte r555 r393 into r556; + or r551 r556 into r557; + sub.w r555 r393 into r558; + ternary r557 r558 r555 into r559; + add r550 10384593717069655257060992658440192u128 into r560; + ternary r557 r560 r550 into r561; + gte r559 170141183460469231731687303715884105728u128 into r562; + add.w r559 r559 into r563; + shr r191 112u8 into r564; + and r564 1u128 into r565; + add r563 r565 into r566; + gte r566 r393 into r567; + or r562 r567 into r568; + sub.w r566 r393 into r569; + ternary r568 r569 r566 into r570; + add r561 5192296858534827628530496329220096u128 into r571; + ternary r568 r571 r561 into r572; + gte r570 170141183460469231731687303715884105728u128 into r573; + add.w r570 r570 into r574; + shr r191 111u8 into r575; + and r575 1u128 into r576; + add r574 r576 into r577; + gte r577 r393 into r578; + or r573 r578 into r579; + sub.w r577 r393 into r580; + ternary r579 r580 r577 into r581; + add r572 2596148429267413814265248164610048u128 into r582; + ternary r579 r582 r572 into r583; + gte r581 170141183460469231731687303715884105728u128 into r584; + add.w r581 r581 into r585; + shr r191 110u8 into r586; + and r586 1u128 into r587; + add r585 r587 into r588; + gte r588 r393 into r589; + or r584 r589 into r590; + sub.w r588 r393 into r591; + ternary r590 r591 r588 into r592; + add r583 1298074214633706907132624082305024u128 into r593; + ternary r590 r593 r583 into r594; + gte r592 170141183460469231731687303715884105728u128 into r595; + add.w r592 r592 into r596; + shr r191 109u8 into r597; + and r597 1u128 into r598; + add r596 r598 into r599; + gte r599 r393 into r600; + or r595 r600 into r601; + sub.w r599 r393 into r602; + ternary r601 r602 r599 into r603; + add r594 649037107316853453566312041152512u128 into r604; + ternary r601 r604 r594 into r605; + gte r603 170141183460469231731687303715884105728u128 into r606; + add.w r603 r603 into r607; + shr r191 108u8 into r608; + and r608 1u128 into r609; + add r607 r609 into r610; + gte r610 r393 into r611; + or r606 r611 into r612; + sub.w r610 r393 into r613; + ternary r612 r613 r610 into r614; + add r605 324518553658426726783156020576256u128 into r615; + ternary r612 r615 r605 into r616; + gte r614 170141183460469231731687303715884105728u128 into r617; + add.w r614 r614 into r618; + shr r191 107u8 into r619; + and r619 1u128 into r620; + add r618 r620 into r621; + gte r621 r393 into r622; + or r617 r622 into r623; + sub.w r621 r393 into r624; + ternary r623 r624 r621 into r625; + add r616 162259276829213363391578010288128u128 into r626; + ternary r623 r626 r616 into r627; + gte r625 170141183460469231731687303715884105728u128 into r628; + add.w r625 r625 into r629; + shr r191 106u8 into r630; + and r630 1u128 into r631; + add r629 r631 into r632; + gte r632 r393 into r633; + or r628 r633 into r634; + sub.w r632 r393 into r635; + ternary r634 r635 r632 into r636; + add r627 81129638414606681695789005144064u128 into r637; + ternary r634 r637 r627 into r638; + gte r636 170141183460469231731687303715884105728u128 into r639; + add.w r636 r636 into r640; + shr r191 105u8 into r641; + and r641 1u128 into r642; + add r640 r642 into r643; + gte r643 r393 into r644; + or r639 r644 into r645; + sub.w r643 r393 into r646; + ternary r645 r646 r643 into r647; + add r638 40564819207303340847894502572032u128 into r648; + ternary r645 r648 r638 into r649; + gte r647 170141183460469231731687303715884105728u128 into r650; + add.w r647 r647 into r651; + shr r191 104u8 into r652; + and r652 1u128 into r653; + add r651 r653 into r654; + gte r654 r393 into r655; + or r650 r655 into r656; + sub.w r654 r393 into r657; + ternary r656 r657 r654 into r658; + add r649 20282409603651670423947251286016u128 into r659; + ternary r656 r659 r649 into r660; + gte r658 170141183460469231731687303715884105728u128 into r661; + add.w r658 r658 into r662; + shr r191 103u8 into r663; + and r663 1u128 into r664; + add r662 r664 into r665; + gte r665 r393 into r666; + or r661 r666 into r667; + sub.w r665 r393 into r668; + ternary r667 r668 r665 into r669; + add r660 10141204801825835211973625643008u128 into r670; + ternary r667 r670 r660 into r671; + gte r669 170141183460469231731687303715884105728u128 into r672; + add.w r669 r669 into r673; + shr r191 102u8 into r674; + and r674 1u128 into r675; + add r673 r675 into r676; + gte r676 r393 into r677; + or r672 r677 into r678; + sub.w r676 r393 into r679; + ternary r678 r679 r676 into r680; + add r671 5070602400912917605986812821504u128 into r681; + ternary r678 r681 r671 into r682; + gte r680 170141183460469231731687303715884105728u128 into r683; + add.w r680 r680 into r684; + shr r191 101u8 into r685; + and r685 1u128 into r686; + add r684 r686 into r687; + gte r687 r393 into r688; + or r683 r688 into r689; + sub.w r687 r393 into r690; + ternary r689 r690 r687 into r691; + add r682 2535301200456458802993406410752u128 into r692; + ternary r689 r692 r682 into r693; + gte r691 170141183460469231731687303715884105728u128 into r694; + add.w r691 r691 into r695; + shr r191 100u8 into r696; + and r696 1u128 into r697; + add r695 r697 into r698; + gte r698 r393 into r699; + or r694 r699 into r700; + sub.w r698 r393 into r701; + ternary r700 r701 r698 into r702; + add r693 1267650600228229401496703205376u128 into r703; + ternary r700 r703 r693 into r704; + gte r702 170141183460469231731687303715884105728u128 into r705; + add.w r702 r702 into r706; + shr r191 99u8 into r707; + and r707 1u128 into r708; + add r706 r708 into r709; + gte r709 r393 into r710; + or r705 r710 into r711; + sub.w r709 r393 into r712; + ternary r711 r712 r709 into r713; + add r704 633825300114114700748351602688u128 into r714; + ternary r711 r714 r704 into r715; + gte r713 170141183460469231731687303715884105728u128 into r716; + add.w r713 r713 into r717; + shr r191 98u8 into r718; + and r718 1u128 into r719; + add r717 r719 into r720; + gte r720 r393 into r721; + or r716 r721 into r722; + sub.w r720 r393 into r723; + ternary r722 r723 r720 into r724; + add r715 316912650057057350374175801344u128 into r725; + ternary r722 r725 r715 into r726; + gte r724 170141183460469231731687303715884105728u128 into r727; + add.w r724 r724 into r728; + shr r191 97u8 into r729; + and r729 1u128 into r730; + add r728 r730 into r731; + gte r731 r393 into r732; + or r727 r732 into r733; + sub.w r731 r393 into r734; + ternary r733 r734 r731 into r735; + add r726 158456325028528675187087900672u128 into r736; + ternary r733 r736 r726 into r737; + gte r735 170141183460469231731687303715884105728u128 into r738; + add.w r735 r735 into r739; + and r195 1u128 into r740; + add r739 r740 into r741; + gte r741 r393 into r742; + or r738 r742 into r743; + sub.w r741 r393 into r744; + ternary r743 r744 r741 into r745; + add r737 79228162514264337593543950336u128 into r746; + ternary r743 r746 r737 into r747; + gte r745 170141183460469231731687303715884105728u128 into r748; + add.w r745 r745 into r749; + shr r191 95u8 into r750; + and r750 1u128 into r751; + add r749 r751 into r752; + gte r752 r393 into r753; + or r748 r753 into r754; + sub.w r752 r393 into r755; + ternary r754 r755 r752 into r756; + add r747 39614081257132168796771975168u128 into r757; + ternary r754 r757 r747 into r758; + gte r756 170141183460469231731687303715884105728u128 into r759; + add.w r756 r756 into r760; + shr r191 94u8 into r761; + and r761 1u128 into r762; + add r760 r762 into r763; + gte r763 r393 into r764; + or r759 r764 into r765; + sub.w r763 r393 into r766; + ternary r765 r766 r763 into r767; + add r758 19807040628566084398385987584u128 into r768; + ternary r765 r768 r758 into r769; + gte r767 170141183460469231731687303715884105728u128 into r770; + add.w r767 r767 into r771; + shr r191 93u8 into r772; + and r772 1u128 into r773; + add r771 r773 into r774; + gte r774 r393 into r775; + or r770 r775 into r776; + sub.w r774 r393 into r777; + ternary r776 r777 r774 into r778; + add r769 9903520314283042199192993792u128 into r779; + ternary r776 r779 r769 into r780; + gte r778 170141183460469231731687303715884105728u128 into r781; + add.w r778 r778 into r782; + shr r191 92u8 into r783; + and r783 1u128 into r784; + add r782 r784 into r785; + gte r785 r393 into r786; + or r781 r786 into r787; + sub.w r785 r393 into r788; + ternary r787 r788 r785 into r789; + add r780 4951760157141521099596496896u128 into r790; + ternary r787 r790 r780 into r791; + gte r789 170141183460469231731687303715884105728u128 into r792; + add.w r789 r789 into r793; + shr r191 91u8 into r794; + and r794 1u128 into r795; + add r793 r795 into r796; + gte r796 r393 into r797; + or r792 r797 into r798; + sub.w r796 r393 into r799; + ternary r798 r799 r796 into r800; + add r791 2475880078570760549798248448u128 into r801; + ternary r798 r801 r791 into r802; + gte r800 170141183460469231731687303715884105728u128 into r803; + add.w r800 r800 into r804; + shr r191 90u8 into r805; + and r805 1u128 into r806; + add r804 r806 into r807; + gte r807 r393 into r808; + or r803 r808 into r809; + sub.w r807 r393 into r810; + ternary r809 r810 r807 into r811; + add r802 1237940039285380274899124224u128 into r812; + ternary r809 r812 r802 into r813; + gte r811 170141183460469231731687303715884105728u128 into r814; + add.w r811 r811 into r815; + shr r191 89u8 into r816; + and r816 1u128 into r817; + add r815 r817 into r818; + gte r818 r393 into r819; + or r814 r819 into r820; + sub.w r818 r393 into r821; + ternary r820 r821 r818 into r822; + add r813 618970019642690137449562112u128 into r823; + ternary r820 r823 r813 into r824; + gte r822 170141183460469231731687303715884105728u128 into r825; + add.w r822 r822 into r826; + shr r191 88u8 into r827; + and r827 1u128 into r828; + add r826 r828 into r829; + gte r829 r393 into r830; + or r825 r830 into r831; + sub.w r829 r393 into r832; + ternary r831 r832 r829 into r833; + add r824 309485009821345068724781056u128 into r834; + ternary r831 r834 r824 into r835; + gte r833 170141183460469231731687303715884105728u128 into r836; + add.w r833 r833 into r837; + shr r191 87u8 into r838; + and r838 1u128 into r839; + add r837 r839 into r840; + gte r840 r393 into r841; + or r836 r841 into r842; + sub.w r840 r393 into r843; + ternary r842 r843 r840 into r844; + add r835 154742504910672534362390528u128 into r845; + ternary r842 r845 r835 into r846; + gte r844 170141183460469231731687303715884105728u128 into r847; + add.w r844 r844 into r848; + shr r191 86u8 into r849; + and r849 1u128 into r850; + add r848 r850 into r851; + gte r851 r393 into r852; + or r847 r852 into r853; + sub.w r851 r393 into r854; + ternary r853 r854 r851 into r855; + add r846 77371252455336267181195264u128 into r856; + ternary r853 r856 r846 into r857; + gte r855 170141183460469231731687303715884105728u128 into r858; + add.w r855 r855 into r859; + shr r191 85u8 into r860; + and r860 1u128 into r861; + add r859 r861 into r862; + gte r862 r393 into r863; + or r858 r863 into r864; + sub.w r862 r393 into r865; + ternary r864 r865 r862 into r866; + add r857 38685626227668133590597632u128 into r867; + ternary r864 r867 r857 into r868; + gte r866 170141183460469231731687303715884105728u128 into r869; + add.w r866 r866 into r870; + shr r191 84u8 into r871; + and r871 1u128 into r872; + add r870 r872 into r873; + gte r873 r393 into r874; + or r869 r874 into r875; + sub.w r873 r393 into r876; + ternary r875 r876 r873 into r877; + add r868 19342813113834066795298816u128 into r878; + ternary r875 r878 r868 into r879; + gte r877 170141183460469231731687303715884105728u128 into r880; + add.w r877 r877 into r881; + shr r191 83u8 into r882; + and r882 1u128 into r883; + add r881 r883 into r884; + gte r884 r393 into r885; + or r880 r885 into r886; + sub.w r884 r393 into r887; + ternary r886 r887 r884 into r888; + add r879 9671406556917033397649408u128 into r889; + ternary r886 r889 r879 into r890; + gte r888 170141183460469231731687303715884105728u128 into r891; + add.w r888 r888 into r892; + shr r191 82u8 into r893; + and r893 1u128 into r894; + add r892 r894 into r895; + gte r895 r393 into r896; + or r891 r896 into r897; + sub.w r895 r393 into r898; + ternary r897 r898 r895 into r899; + add r890 4835703278458516698824704u128 into r900; + ternary r897 r900 r890 into r901; + gte r899 170141183460469231731687303715884105728u128 into r902; + add.w r899 r899 into r903; + shr r191 81u8 into r904; + and r904 1u128 into r905; + add r903 r905 into r906; + gte r906 r393 into r907; + or r902 r907 into r908; + sub.w r906 r393 into r909; + ternary r908 r909 r906 into r910; + add r901 2417851639229258349412352u128 into r911; + ternary r908 r911 r901 into r912; + gte r910 170141183460469231731687303715884105728u128 into r913; + add.w r910 r910 into r914; + shr r191 80u8 into r915; + and r915 1u128 into r916; + add r914 r916 into r917; + gte r917 r393 into r918; + or r913 r918 into r919; + sub.w r917 r393 into r920; + ternary r919 r920 r917 into r921; + add r912 1208925819614629174706176u128 into r922; + ternary r919 r922 r912 into r923; + gte r921 170141183460469231731687303715884105728u128 into r924; + add.w r921 r921 into r925; + shr r191 79u8 into r926; + and r926 1u128 into r927; + add r925 r927 into r928; + gte r928 r393 into r929; + or r924 r929 into r930; + sub.w r928 r393 into r931; + ternary r930 r931 r928 into r932; + add r923 604462909807314587353088u128 into r933; + ternary r930 r933 r923 into r934; + gte r932 170141183460469231731687303715884105728u128 into r935; + add.w r932 r932 into r936; + shr r191 78u8 into r937; + and r937 1u128 into r938; + add r936 r938 into r939; + gte r939 r393 into r940; + or r935 r940 into r941; + sub.w r939 r393 into r942; + ternary r941 r942 r939 into r943; + add r934 302231454903657293676544u128 into r944; + ternary r941 r944 r934 into r945; + gte r943 170141183460469231731687303715884105728u128 into r946; + add.w r943 r943 into r947; + shr r191 77u8 into r948; + and r948 1u128 into r949; + add r947 r949 into r950; + gte r950 r393 into r951; + or r946 r951 into r952; + sub.w r950 r393 into r953; + ternary r952 r953 r950 into r954; + add r945 151115727451828646838272u128 into r955; + ternary r952 r955 r945 into r956; + gte r954 170141183460469231731687303715884105728u128 into r957; + add.w r954 r954 into r958; + shr r191 76u8 into r959; + and r959 1u128 into r960; + add r958 r960 into r961; + gte r961 r393 into r962; + or r957 r962 into r963; + sub.w r961 r393 into r964; + ternary r963 r964 r961 into r965; + add r956 75557863725914323419136u128 into r966; + ternary r963 r966 r956 into r967; + gte r965 170141183460469231731687303715884105728u128 into r968; + add.w r965 r965 into r969; + shr r191 75u8 into r970; + and r970 1u128 into r971; + add r969 r971 into r972; + gte r972 r393 into r973; + or r968 r973 into r974; + sub.w r972 r393 into r975; + ternary r974 r975 r972 into r976; + add r967 37778931862957161709568u128 into r977; + ternary r974 r977 r967 into r978; + gte r976 170141183460469231731687303715884105728u128 into r979; + add.w r976 r976 into r980; + shr r191 74u8 into r981; + and r981 1u128 into r982; + add r980 r982 into r983; + gte r983 r393 into r984; + or r979 r984 into r985; + sub.w r983 r393 into r986; + ternary r985 r986 r983 into r987; + add r978 18889465931478580854784u128 into r988; + ternary r985 r988 r978 into r989; + gte r987 170141183460469231731687303715884105728u128 into r990; + add.w r987 r987 into r991; + shr r191 73u8 into r992; + and r992 1u128 into r993; + add r991 r993 into r994; + gte r994 r393 into r995; + or r990 r995 into r996; + sub.w r994 r393 into r997; + ternary r996 r997 r994 into r998; + add r989 9444732965739290427392u128 into r999; + ternary r996 r999 r989 into r1000; + gte r998 170141183460469231731687303715884105728u128 into r1001; + add.w r998 r998 into r1002; + shr r191 72u8 into r1003; + and r1003 1u128 into r1004; + add r1002 r1004 into r1005; + gte r1005 r393 into r1006; + or r1001 r1006 into r1007; + sub.w r1005 r393 into r1008; + ternary r1007 r1008 r1005 into r1009; + add r1000 4722366482869645213696u128 into r1010; + ternary r1007 r1010 r1000 into r1011; + gte r1009 170141183460469231731687303715884105728u128 into r1012; + add.w r1009 r1009 into r1013; + shr r191 71u8 into r1014; + and r1014 1u128 into r1015; + add r1013 r1015 into r1016; + gte r1016 r393 into r1017; + or r1012 r1017 into r1018; + sub.w r1016 r393 into r1019; + ternary r1018 r1019 r1016 into r1020; + add r1011 2361183241434822606848u128 into r1021; + ternary r1018 r1021 r1011 into r1022; + gte r1020 170141183460469231731687303715884105728u128 into r1023; + add.w r1020 r1020 into r1024; + shr r191 70u8 into r1025; + and r1025 1u128 into r1026; + add r1024 r1026 into r1027; + gte r1027 r393 into r1028; + or r1023 r1028 into r1029; + sub.w r1027 r393 into r1030; + ternary r1029 r1030 r1027 into r1031; + add r1022 1180591620717411303424u128 into r1032; + ternary r1029 r1032 r1022 into r1033; + gte r1031 170141183460469231731687303715884105728u128 into r1034; + add.w r1031 r1031 into r1035; + shr r191 69u8 into r1036; + and r1036 1u128 into r1037; + add r1035 r1037 into r1038; + gte r1038 r393 into r1039; + or r1034 r1039 into r1040; + sub.w r1038 r393 into r1041; + ternary r1040 r1041 r1038 into r1042; + add r1033 590295810358705651712u128 into r1043; + ternary r1040 r1043 r1033 into r1044; + gte r1042 170141183460469231731687303715884105728u128 into r1045; + add.w r1042 r1042 into r1046; + shr r191 68u8 into r1047; + and r1047 1u128 into r1048; + add r1046 r1048 into r1049; + gte r1049 r393 into r1050; + or r1045 r1050 into r1051; + sub.w r1049 r393 into r1052; + ternary r1051 r1052 r1049 into r1053; + add r1044 295147905179352825856u128 into r1054; + ternary r1051 r1054 r1044 into r1055; + gte r1053 170141183460469231731687303715884105728u128 into r1056; + add.w r1053 r1053 into r1057; + shr r191 67u8 into r1058; + and r1058 1u128 into r1059; + add r1057 r1059 into r1060; + gte r1060 r393 into r1061; + or r1056 r1061 into r1062; + sub.w r1060 r393 into r1063; + ternary r1062 r1063 r1060 into r1064; + add r1055 147573952589676412928u128 into r1065; + ternary r1062 r1065 r1055 into r1066; + gte r1064 170141183460469231731687303715884105728u128 into r1067; + add.w r1064 r1064 into r1068; + shr r191 66u8 into r1069; + and r1069 1u128 into r1070; + add r1068 r1070 into r1071; + gte r1071 r393 into r1072; + or r1067 r1072 into r1073; + sub.w r1071 r393 into r1074; + ternary r1073 r1074 r1071 into r1075; + add r1066 73786976294838206464u128 into r1076; + ternary r1073 r1076 r1066 into r1077; + gte r1075 170141183460469231731687303715884105728u128 into r1078; + add.w r1075 r1075 into r1079; + shr r191 65u8 into r1080; + and r1080 1u128 into r1081; + add r1079 r1081 into r1082; + gte r1082 r393 into r1083; + or r1078 r1083 into r1084; + sub.w r1082 r393 into r1085; + ternary r1084 r1085 r1082 into r1086; + add r1077 36893488147419103232u128 into r1087; + ternary r1084 r1087 r1077 into r1088; + gte r1086 170141183460469231731687303715884105728u128 into r1089; + add.w r1086 r1086 into r1090; + and r201 1u128 into r1091; + add r1090 r1091 into r1092; + gte r1092 r393 into r1093; + or r1089 r1093 into r1094; + sub.w r1092 r393 into r1095; + ternary r1094 r1095 r1092 into r1096; + add r1088 18446744073709551616u128 into r1097; + ternary r1094 r1097 r1088 into r1098; + gte r1096 170141183460469231731687303715884105728u128 into r1099; + add.w r1096 r1096 into r1100; + shr r191 63u8 into r1101; + and r1101 1u128 into r1102; + add r1100 r1102 into r1103; + gte r1103 r393 into r1104; + or r1099 r1104 into r1105; + sub.w r1103 r393 into r1106; + ternary r1105 r1106 r1103 into r1107; + add r1098 9223372036854775808u128 into r1108; + ternary r1105 r1108 r1098 into r1109; + gte r1107 170141183460469231731687303715884105728u128 into r1110; + add.w r1107 r1107 into r1111; + shr r191 62u8 into r1112; + and r1112 1u128 into r1113; + add r1111 r1113 into r1114; + gte r1114 r393 into r1115; + or r1110 r1115 into r1116; + sub.w r1114 r393 into r1117; + ternary r1116 r1117 r1114 into r1118; + add r1109 4611686018427387904u128 into r1119; + ternary r1116 r1119 r1109 into r1120; + gte r1118 170141183460469231731687303715884105728u128 into r1121; + add.w r1118 r1118 into r1122; + shr r191 61u8 into r1123; + and r1123 1u128 into r1124; + add r1122 r1124 into r1125; + gte r1125 r393 into r1126; + or r1121 r1126 into r1127; + sub.w r1125 r393 into r1128; + ternary r1127 r1128 r1125 into r1129; + add r1120 2305843009213693952u128 into r1130; + ternary r1127 r1130 r1120 into r1131; + gte r1129 170141183460469231731687303715884105728u128 into r1132; + add.w r1129 r1129 into r1133; + shr r191 60u8 into r1134; + and r1134 1u128 into r1135; + add r1133 r1135 into r1136; + gte r1136 r393 into r1137; + or r1132 r1137 into r1138; + sub.w r1136 r393 into r1139; + ternary r1138 r1139 r1136 into r1140; + add r1131 1152921504606846976u128 into r1141; + ternary r1138 r1141 r1131 into r1142; + gte r1140 170141183460469231731687303715884105728u128 into r1143; + add.w r1140 r1140 into r1144; + shr r191 59u8 into r1145; + and r1145 1u128 into r1146; + add r1144 r1146 into r1147; + gte r1147 r393 into r1148; + or r1143 r1148 into r1149; + sub.w r1147 r393 into r1150; + ternary r1149 r1150 r1147 into r1151; + add r1142 576460752303423488u128 into r1152; + ternary r1149 r1152 r1142 into r1153; + gte r1151 170141183460469231731687303715884105728u128 into r1154; + add.w r1151 r1151 into r1155; + shr r191 58u8 into r1156; + and r1156 1u128 into r1157; + add r1155 r1157 into r1158; + gte r1158 r393 into r1159; + or r1154 r1159 into r1160; + sub.w r1158 r393 into r1161; + ternary r1160 r1161 r1158 into r1162; + add r1153 288230376151711744u128 into r1163; + ternary r1160 r1163 r1153 into r1164; + gte r1162 170141183460469231731687303715884105728u128 into r1165; + add.w r1162 r1162 into r1166; + shr r191 57u8 into r1167; + and r1167 1u128 into r1168; + add r1166 r1168 into r1169; + gte r1169 r393 into r1170; + or r1165 r1170 into r1171; + sub.w r1169 r393 into r1172; + ternary r1171 r1172 r1169 into r1173; + add r1164 144115188075855872u128 into r1174; + ternary r1171 r1174 r1164 into r1175; + gte r1173 170141183460469231731687303715884105728u128 into r1176; + add.w r1173 r1173 into r1177; + shr r191 56u8 into r1178; + and r1178 1u128 into r1179; + add r1177 r1179 into r1180; + gte r1180 r393 into r1181; + or r1176 r1181 into r1182; + sub.w r1180 r393 into r1183; + ternary r1182 r1183 r1180 into r1184; + add r1175 72057594037927936u128 into r1185; + ternary r1182 r1185 r1175 into r1186; + gte r1184 170141183460469231731687303715884105728u128 into r1187; + add.w r1184 r1184 into r1188; + shr r191 55u8 into r1189; + and r1189 1u128 into r1190; + add r1188 r1190 into r1191; + gte r1191 r393 into r1192; + or r1187 r1192 into r1193; + sub.w r1191 r393 into r1194; + ternary r1193 r1194 r1191 into r1195; + add r1186 36028797018963968u128 into r1196; + ternary r1193 r1196 r1186 into r1197; + gte r1195 170141183460469231731687303715884105728u128 into r1198; + add.w r1195 r1195 into r1199; + shr r191 54u8 into r1200; + and r1200 1u128 into r1201; + add r1199 r1201 into r1202; + gte r1202 r393 into r1203; + or r1198 r1203 into r1204; + sub.w r1202 r393 into r1205; + ternary r1204 r1205 r1202 into r1206; + add r1197 18014398509481984u128 into r1207; + ternary r1204 r1207 r1197 into r1208; + gte r1206 170141183460469231731687303715884105728u128 into r1209; + add.w r1206 r1206 into r1210; + shr r191 53u8 into r1211; + and r1211 1u128 into r1212; + add r1210 r1212 into r1213; + gte r1213 r393 into r1214; + or r1209 r1214 into r1215; + sub.w r1213 r393 into r1216; + ternary r1215 r1216 r1213 into r1217; + add r1208 9007199254740992u128 into r1218; + ternary r1215 r1218 r1208 into r1219; + gte r1217 170141183460469231731687303715884105728u128 into r1220; + add.w r1217 r1217 into r1221; + shr r191 52u8 into r1222; + and r1222 1u128 into r1223; + add r1221 r1223 into r1224; + gte r1224 r393 into r1225; + or r1220 r1225 into r1226; + sub.w r1224 r393 into r1227; + ternary r1226 r1227 r1224 into r1228; + add r1219 4503599627370496u128 into r1229; + ternary r1226 r1229 r1219 into r1230; + gte r1228 170141183460469231731687303715884105728u128 into r1231; + add.w r1228 r1228 into r1232; + shr r191 51u8 into r1233; + and r1233 1u128 into r1234; + add r1232 r1234 into r1235; + gte r1235 r393 into r1236; + or r1231 r1236 into r1237; + sub.w r1235 r393 into r1238; + ternary r1237 r1238 r1235 into r1239; + add r1230 2251799813685248u128 into r1240; + ternary r1237 r1240 r1230 into r1241; + gte r1239 170141183460469231731687303715884105728u128 into r1242; + add.w r1239 r1239 into r1243; + shr r191 50u8 into r1244; + and r1244 1u128 into r1245; + add r1243 r1245 into r1246; + gte r1246 r393 into r1247; + or r1242 r1247 into r1248; + sub.w r1246 r393 into r1249; + ternary r1248 r1249 r1246 into r1250; + add r1241 1125899906842624u128 into r1251; + ternary r1248 r1251 r1241 into r1252; + gte r1250 170141183460469231731687303715884105728u128 into r1253; + add.w r1250 r1250 into r1254; + shr r191 49u8 into r1255; + and r1255 1u128 into r1256; + add r1254 r1256 into r1257; + gte r1257 r393 into r1258; + or r1253 r1258 into r1259; + sub.w r1257 r393 into r1260; + ternary r1259 r1260 r1257 into r1261; + add r1252 562949953421312u128 into r1262; + ternary r1259 r1262 r1252 into r1263; + gte r1261 170141183460469231731687303715884105728u128 into r1264; + add.w r1261 r1261 into r1265; + shr r191 48u8 into r1266; + and r1266 1u128 into r1267; + add r1265 r1267 into r1268; + gte r1268 r393 into r1269; + or r1264 r1269 into r1270; + sub.w r1268 r393 into r1271; + ternary r1270 r1271 r1268 into r1272; + add r1263 281474976710656u128 into r1273; + ternary r1270 r1273 r1263 into r1274; + gte r1272 170141183460469231731687303715884105728u128 into r1275; + add.w r1272 r1272 into r1276; + shr r191 47u8 into r1277; + and r1277 1u128 into r1278; + add r1276 r1278 into r1279; + gte r1279 r393 into r1280; + or r1275 r1280 into r1281; + sub.w r1279 r393 into r1282; + ternary r1281 r1282 r1279 into r1283; + add r1274 140737488355328u128 into r1284; + ternary r1281 r1284 r1274 into r1285; + gte r1283 170141183460469231731687303715884105728u128 into r1286; + add.w r1283 r1283 into r1287; + shr r191 46u8 into r1288; + and r1288 1u128 into r1289; + add r1287 r1289 into r1290; + gte r1290 r393 into r1291; + or r1286 r1291 into r1292; + sub.w r1290 r393 into r1293; + ternary r1292 r1293 r1290 into r1294; + add r1285 70368744177664u128 into r1295; + ternary r1292 r1295 r1285 into r1296; + gte r1294 170141183460469231731687303715884105728u128 into r1297; + add.w r1294 r1294 into r1298; + shr r191 45u8 into r1299; + and r1299 1u128 into r1300; + add r1298 r1300 into r1301; + gte r1301 r393 into r1302; + or r1297 r1302 into r1303; + sub.w r1301 r393 into r1304; + ternary r1303 r1304 r1301 into r1305; + add r1296 35184372088832u128 into r1306; + ternary r1303 r1306 r1296 into r1307; + gte r1305 170141183460469231731687303715884105728u128 into r1308; + add.w r1305 r1305 into r1309; + shr r191 44u8 into r1310; + and r1310 1u128 into r1311; + add r1309 r1311 into r1312; + gte r1312 r393 into r1313; + or r1308 r1313 into r1314; + sub.w r1312 r393 into r1315; + ternary r1314 r1315 r1312 into r1316; + add r1307 17592186044416u128 into r1317; + ternary r1314 r1317 r1307 into r1318; + gte r1316 170141183460469231731687303715884105728u128 into r1319; + add.w r1316 r1316 into r1320; + shr r191 43u8 into r1321; + and r1321 1u128 into r1322; + add r1320 r1322 into r1323; + gte r1323 r393 into r1324; + or r1319 r1324 into r1325; + sub.w r1323 r393 into r1326; + ternary r1325 r1326 r1323 into r1327; + add r1318 8796093022208u128 into r1328; + ternary r1325 r1328 r1318 into r1329; + gte r1327 170141183460469231731687303715884105728u128 into r1330; + add.w r1327 r1327 into r1331; + shr r191 42u8 into r1332; + and r1332 1u128 into r1333; + add r1331 r1333 into r1334; + gte r1334 r393 into r1335; + or r1330 r1335 into r1336; + sub.w r1334 r393 into r1337; + ternary r1336 r1337 r1334 into r1338; + add r1329 4398046511104u128 into r1339; + ternary r1336 r1339 r1329 into r1340; + gte r1338 170141183460469231731687303715884105728u128 into r1341; + add.w r1338 r1338 into r1342; + shr r191 41u8 into r1343; + and r1343 1u128 into r1344; + add r1342 r1344 into r1345; + gte r1345 r393 into r1346; + or r1341 r1346 into r1347; + sub.w r1345 r393 into r1348; + ternary r1347 r1348 r1345 into r1349; + add r1340 2199023255552u128 into r1350; + ternary r1347 r1350 r1340 into r1351; + gte r1349 170141183460469231731687303715884105728u128 into r1352; + add.w r1349 r1349 into r1353; + shr r191 40u8 into r1354; + and r1354 1u128 into r1355; + add r1353 r1355 into r1356; + gte r1356 r393 into r1357; + or r1352 r1357 into r1358; + sub.w r1356 r393 into r1359; + ternary r1358 r1359 r1356 into r1360; + add r1351 1099511627776u128 into r1361; + ternary r1358 r1361 r1351 into r1362; + gte r1360 170141183460469231731687303715884105728u128 into r1363; + add.w r1360 r1360 into r1364; + shr r191 39u8 into r1365; + and r1365 1u128 into r1366; + add r1364 r1366 into r1367; + gte r1367 r393 into r1368; + or r1363 r1368 into r1369; + sub.w r1367 r393 into r1370; + ternary r1369 r1370 r1367 into r1371; + add r1362 549755813888u128 into r1372; + ternary r1369 r1372 r1362 into r1373; + gte r1371 170141183460469231731687303715884105728u128 into r1374; + add.w r1371 r1371 into r1375; + shr r191 38u8 into r1376; + and r1376 1u128 into r1377; + add r1375 r1377 into r1378; + gte r1378 r393 into r1379; + or r1374 r1379 into r1380; + sub.w r1378 r393 into r1381; + ternary r1380 r1381 r1378 into r1382; + add r1373 274877906944u128 into r1383; + ternary r1380 r1383 r1373 into r1384; + gte r1382 170141183460469231731687303715884105728u128 into r1385; + add.w r1382 r1382 into r1386; + shr r191 37u8 into r1387; + and r1387 1u128 into r1388; + add r1386 r1388 into r1389; + gte r1389 r393 into r1390; + or r1385 r1390 into r1391; + sub.w r1389 r393 into r1392; + ternary r1391 r1392 r1389 into r1393; + add r1384 137438953472u128 into r1394; + ternary r1391 r1394 r1384 into r1395; + gte r1393 170141183460469231731687303715884105728u128 into r1396; + add.w r1393 r1393 into r1397; + shr r191 36u8 into r1398; + and r1398 1u128 into r1399; + add r1397 r1399 into r1400; + gte r1400 r393 into r1401; + or r1396 r1401 into r1402; + sub.w r1400 r393 into r1403; + ternary r1402 r1403 r1400 into r1404; + add r1395 68719476736u128 into r1405; + ternary r1402 r1405 r1395 into r1406; + gte r1404 170141183460469231731687303715884105728u128 into r1407; + add.w r1404 r1404 into r1408; + shr r191 35u8 into r1409; + and r1409 1u128 into r1410; + add r1408 r1410 into r1411; + gte r1411 r393 into r1412; + or r1407 r1412 into r1413; + sub.w r1411 r393 into r1414; + ternary r1413 r1414 r1411 into r1415; + add r1406 34359738368u128 into r1416; + ternary r1413 r1416 r1406 into r1417; + gte r1415 170141183460469231731687303715884105728u128 into r1418; + add.w r1415 r1415 into r1419; + shr r191 34u8 into r1420; + and r1420 1u128 into r1421; + add r1419 r1421 into r1422; + gte r1422 r393 into r1423; + or r1418 r1423 into r1424; + sub.w r1422 r393 into r1425; + ternary r1424 r1425 r1422 into r1426; + add r1417 17179869184u128 into r1427; + ternary r1424 r1427 r1417 into r1428; + gte r1426 170141183460469231731687303715884105728u128 into r1429; + add.w r1426 r1426 into r1430; + shr r191 33u8 into r1431; + and r1431 1u128 into r1432; + add r1430 r1432 into r1433; + gte r1433 r393 into r1434; + or r1429 r1434 into r1435; + sub.w r1433 r393 into r1436; + ternary r1435 r1436 r1433 into r1437; + add r1428 8589934592u128 into r1438; + ternary r1435 r1438 r1428 into r1439; + gte r1437 170141183460469231731687303715884105728u128 into r1440; + add.w r1437 r1437 into r1441; + and r209 1u128 into r1442; + add r1441 r1442 into r1443; + gte r1443 r393 into r1444; + or r1440 r1444 into r1445; + sub.w r1443 r393 into r1446; + ternary r1445 r1446 r1443 into r1447; + add r1439 4294967296u128 into r1448; + ternary r1445 r1448 r1439 into r1449; + gte r1447 170141183460469231731687303715884105728u128 into r1450; + add.w r1447 r1447 into r1451; + shr r191 31u8 into r1452; + and r1452 1u128 into r1453; + add r1451 r1453 into r1454; + gte r1454 r393 into r1455; + or r1450 r1455 into r1456; + sub.w r1454 r393 into r1457; + ternary r1456 r1457 r1454 into r1458; + add r1449 2147483648u128 into r1459; + ternary r1456 r1459 r1449 into r1460; + gte r1458 170141183460469231731687303715884105728u128 into r1461; + add.w r1458 r1458 into r1462; + shr r191 30u8 into r1463; + and r1463 1u128 into r1464; + add r1462 r1464 into r1465; + gte r1465 r393 into r1466; + or r1461 r1466 into r1467; + sub.w r1465 r393 into r1468; + ternary r1467 r1468 r1465 into r1469; + add r1460 1073741824u128 into r1470; + ternary r1467 r1470 r1460 into r1471; + gte r1469 170141183460469231731687303715884105728u128 into r1472; + add.w r1469 r1469 into r1473; + shr r191 29u8 into r1474; + and r1474 1u128 into r1475; + add r1473 r1475 into r1476; + gte r1476 r393 into r1477; + or r1472 r1477 into r1478; + sub.w r1476 r393 into r1479; + ternary r1478 r1479 r1476 into r1480; + add r1471 536870912u128 into r1481; + ternary r1478 r1481 r1471 into r1482; + gte r1480 170141183460469231731687303715884105728u128 into r1483; + add.w r1480 r1480 into r1484; + shr r191 28u8 into r1485; + and r1485 1u128 into r1486; + add r1484 r1486 into r1487; + gte r1487 r393 into r1488; + or r1483 r1488 into r1489; + sub.w r1487 r393 into r1490; + ternary r1489 r1490 r1487 into r1491; + add r1482 268435456u128 into r1492; + ternary r1489 r1492 r1482 into r1493; + gte r1491 170141183460469231731687303715884105728u128 into r1494; + add.w r1491 r1491 into r1495; + shr r191 27u8 into r1496; + and r1496 1u128 into r1497; + add r1495 r1497 into r1498; + gte r1498 r393 into r1499; + or r1494 r1499 into r1500; + sub.w r1498 r393 into r1501; + ternary r1500 r1501 r1498 into r1502; + add r1493 134217728u128 into r1503; + ternary r1500 r1503 r1493 into r1504; + gte r1502 170141183460469231731687303715884105728u128 into r1505; + add.w r1502 r1502 into r1506; + shr r191 26u8 into r1507; + and r1507 1u128 into r1508; + add r1506 r1508 into r1509; + gte r1509 r393 into r1510; + or r1505 r1510 into r1511; + sub.w r1509 r393 into r1512; + ternary r1511 r1512 r1509 into r1513; + add r1504 67108864u128 into r1514; + ternary r1511 r1514 r1504 into r1515; + gte r1513 170141183460469231731687303715884105728u128 into r1516; + add.w r1513 r1513 into r1517; + shr r191 25u8 into r1518; + and r1518 1u128 into r1519; + add r1517 r1519 into r1520; + gte r1520 r393 into r1521; + or r1516 r1521 into r1522; + sub.w r1520 r393 into r1523; + ternary r1522 r1523 r1520 into r1524; + add r1515 33554432u128 into r1525; + ternary r1522 r1525 r1515 into r1526; + gte r1524 170141183460469231731687303715884105728u128 into r1527; + add.w r1524 r1524 into r1528; + shr r191 24u8 into r1529; + and r1529 1u128 into r1530; + add r1528 r1530 into r1531; + gte r1531 r393 into r1532; + or r1527 r1532 into r1533; + sub.w r1531 r393 into r1534; + ternary r1533 r1534 r1531 into r1535; + add r1526 16777216u128 into r1536; + ternary r1533 r1536 r1526 into r1537; + gte r1535 170141183460469231731687303715884105728u128 into r1538; + add.w r1535 r1535 into r1539; + shr r191 23u8 into r1540; + and r1540 1u128 into r1541; + add r1539 r1541 into r1542; + gte r1542 r393 into r1543; + or r1538 r1543 into r1544; + sub.w r1542 r393 into r1545; + ternary r1544 r1545 r1542 into r1546; + add r1537 8388608u128 into r1547; + ternary r1544 r1547 r1537 into r1548; + gte r1546 170141183460469231731687303715884105728u128 into r1549; + add.w r1546 r1546 into r1550; + shr r191 22u8 into r1551; + and r1551 1u128 into r1552; + add r1550 r1552 into r1553; + gte r1553 r393 into r1554; + or r1549 r1554 into r1555; + sub.w r1553 r393 into r1556; + ternary r1555 r1556 r1553 into r1557; + add r1548 4194304u128 into r1558; + ternary r1555 r1558 r1548 into r1559; + gte r1557 170141183460469231731687303715884105728u128 into r1560; + add.w r1557 r1557 into r1561; + shr r191 21u8 into r1562; + and r1562 1u128 into r1563; + add r1561 r1563 into r1564; + gte r1564 r393 into r1565; + or r1560 r1565 into r1566; + sub.w r1564 r393 into r1567; + ternary r1566 r1567 r1564 into r1568; + add r1559 2097152u128 into r1569; + ternary r1566 r1569 r1559 into r1570; + gte r1568 170141183460469231731687303715884105728u128 into r1571; + add.w r1568 r1568 into r1572; + shr r191 20u8 into r1573; + and r1573 1u128 into r1574; + add r1572 r1574 into r1575; + gte r1575 r393 into r1576; + or r1571 r1576 into r1577; + sub.w r1575 r393 into r1578; + ternary r1577 r1578 r1575 into r1579; + add r1570 1048576u128 into r1580; + ternary r1577 r1580 r1570 into r1581; + gte r1579 170141183460469231731687303715884105728u128 into r1582; + add.w r1579 r1579 into r1583; + shr r191 19u8 into r1584; + and r1584 1u128 into r1585; + add r1583 r1585 into r1586; + gte r1586 r393 into r1587; + or r1582 r1587 into r1588; + sub.w r1586 r393 into r1589; + ternary r1588 r1589 r1586 into r1590; + add r1581 524288u128 into r1591; + ternary r1588 r1591 r1581 into r1592; + gte r1590 170141183460469231731687303715884105728u128 into r1593; + add.w r1590 r1590 into r1594; + shr r191 18u8 into r1595; + and r1595 1u128 into r1596; + add r1594 r1596 into r1597; + gte r1597 r393 into r1598; + or r1593 r1598 into r1599; + sub.w r1597 r393 into r1600; + ternary r1599 r1600 r1597 into r1601; + add r1592 262144u128 into r1602; + ternary r1599 r1602 r1592 into r1603; + gte r1601 170141183460469231731687303715884105728u128 into r1604; + add.w r1601 r1601 into r1605; + shr r191 17u8 into r1606; + and r1606 1u128 into r1607; + add r1605 r1607 into r1608; + gte r1608 r393 into r1609; + or r1604 r1609 into r1610; + sub.w r1608 r393 into r1611; + ternary r1610 r1611 r1608 into r1612; + add r1603 131072u128 into r1613; + ternary r1610 r1613 r1603 into r1614; + gte r1612 170141183460469231731687303715884105728u128 into r1615; + add.w r1612 r1612 into r1616; + shr r191 16u8 into r1617; + and r1617 1u128 into r1618; + add r1616 r1618 into r1619; + gte r1619 r393 into r1620; + or r1615 r1620 into r1621; + sub.w r1619 r393 into r1622; + ternary r1621 r1622 r1619 into r1623; + add r1614 65536u128 into r1624; + ternary r1621 r1624 r1614 into r1625; + gte r1623 170141183460469231731687303715884105728u128 into r1626; + add.w r1623 r1623 into r1627; + shr r191 15u8 into r1628; + and r1628 1u128 into r1629; + add r1627 r1629 into r1630; + gte r1630 r393 into r1631; + or r1626 r1631 into r1632; + sub.w r1630 r393 into r1633; + ternary r1632 r1633 r1630 into r1634; + add r1625 32768u128 into r1635; + ternary r1632 r1635 r1625 into r1636; + gte r1634 170141183460469231731687303715884105728u128 into r1637; + add.w r1634 r1634 into r1638; + shr r191 14u8 into r1639; + and r1639 1u128 into r1640; + add r1638 r1640 into r1641; + gte r1641 r393 into r1642; + or r1637 r1642 into r1643; + sub.w r1641 r393 into r1644; + ternary r1643 r1644 r1641 into r1645; + add r1636 16384u128 into r1646; + ternary r1643 r1646 r1636 into r1647; + gte r1645 170141183460469231731687303715884105728u128 into r1648; + add.w r1645 r1645 into r1649; + shr r191 13u8 into r1650; + and r1650 1u128 into r1651; + add r1649 r1651 into r1652; + gte r1652 r393 into r1653; + or r1648 r1653 into r1654; + sub.w r1652 r393 into r1655; + ternary r1654 r1655 r1652 into r1656; + add r1647 8192u128 into r1657; + ternary r1654 r1657 r1647 into r1658; + gte r1656 170141183460469231731687303715884105728u128 into r1659; + add.w r1656 r1656 into r1660; + shr r191 12u8 into r1661; + and r1661 1u128 into r1662; + add r1660 r1662 into r1663; + gte r1663 r393 into r1664; + or r1659 r1664 into r1665; + sub.w r1663 r393 into r1666; + ternary r1665 r1666 r1663 into r1667; + add r1658 4096u128 into r1668; + ternary r1665 r1668 r1658 into r1669; + gte r1667 170141183460469231731687303715884105728u128 into r1670; + add.w r1667 r1667 into r1671; + shr r191 11u8 into r1672; + and r1672 1u128 into r1673; + add r1671 r1673 into r1674; + gte r1674 r393 into r1675; + or r1670 r1675 into r1676; + sub.w r1674 r393 into r1677; + ternary r1676 r1677 r1674 into r1678; + add r1669 2048u128 into r1679; + ternary r1676 r1679 r1669 into r1680; + gte r1678 170141183460469231731687303715884105728u128 into r1681; + add.w r1678 r1678 into r1682; + shr r191 10u8 into r1683; + and r1683 1u128 into r1684; + add r1682 r1684 into r1685; + gte r1685 r393 into r1686; + or r1681 r1686 into r1687; + sub.w r1685 r393 into r1688; + ternary r1687 r1688 r1685 into r1689; + add r1680 1024u128 into r1690; + ternary r1687 r1690 r1680 into r1691; + gte r1689 170141183460469231731687303715884105728u128 into r1692; + add.w r1689 r1689 into r1693; + shr r191 9u8 into r1694; + and r1694 1u128 into r1695; + add r1693 r1695 into r1696; + gte r1696 r393 into r1697; + or r1692 r1697 into r1698; + sub.w r1696 r393 into r1699; + ternary r1698 r1699 r1696 into r1700; + add r1691 512u128 into r1701; + ternary r1698 r1701 r1691 into r1702; + gte r1700 170141183460469231731687303715884105728u128 into r1703; + add.w r1700 r1700 into r1704; + shr r191 8u8 into r1705; + and r1705 1u128 into r1706; + add r1704 r1706 into r1707; + gte r1707 r393 into r1708; + or r1703 r1708 into r1709; + sub.w r1707 r393 into r1710; + ternary r1709 r1710 r1707 into r1711; + add r1702 256u128 into r1712; + ternary r1709 r1712 r1702 into r1713; + gte r1711 170141183460469231731687303715884105728u128 into r1714; + add.w r1711 r1711 into r1715; + shr r191 7u8 into r1716; + and r1716 1u128 into r1717; + add r1715 r1717 into r1718; + gte r1718 r393 into r1719; + or r1714 r1719 into r1720; + sub.w r1718 r393 into r1721; + ternary r1720 r1721 r1718 into r1722; + add r1713 128u128 into r1723; + ternary r1720 r1723 r1713 into r1724; + gte r1722 170141183460469231731687303715884105728u128 into r1725; + add.w r1722 r1722 into r1726; + shr r191 6u8 into r1727; + and r1727 1u128 into r1728; + add r1726 r1728 into r1729; + gte r1729 r393 into r1730; + or r1725 r1730 into r1731; + sub.w r1729 r393 into r1732; + ternary r1731 r1732 r1729 into r1733; + add r1724 64u128 into r1734; + ternary r1731 r1734 r1724 into r1735; + gte r1733 170141183460469231731687303715884105728u128 into r1736; + add.w r1733 r1733 into r1737; + shr r191 5u8 into r1738; + and r1738 1u128 into r1739; + add r1737 r1739 into r1740; + gte r1740 r393 into r1741; + or r1736 r1741 into r1742; + sub.w r1740 r393 into r1743; + ternary r1742 r1743 r1740 into r1744; + add r1735 32u128 into r1745; + ternary r1742 r1745 r1735 into r1746; + gte r1744 170141183460469231731687303715884105728u128 into r1747; + add.w r1744 r1744 into r1748; + shr r191 4u8 into r1749; + and r1749 1u128 into r1750; + add r1748 r1750 into r1751; + gte r1751 r393 into r1752; + or r1747 r1752 into r1753; + sub.w r1751 r393 into r1754; + ternary r1753 r1754 r1751 into r1755; + add r1746 16u128 into r1756; + ternary r1753 r1756 r1746 into r1757; + gte r1755 170141183460469231731687303715884105728u128 into r1758; + add.w r1755 r1755 into r1759; + shr r191 3u8 into r1760; + and r1760 1u128 into r1761; + add r1759 r1761 into r1762; + gte r1762 r393 into r1763; + or r1758 r1763 into r1764; + sub.w r1762 r393 into r1765; + ternary r1764 r1765 r1762 into r1766; + add r1757 8u128 into r1767; + ternary r1764 r1767 r1757 into r1768; + gte r1766 170141183460469231731687303715884105728u128 into r1769; + add.w r1766 r1766 into r1770; + shr r191 2u8 into r1771; + and r1771 1u128 into r1772; + add r1770 r1772 into r1773; + gte r1773 r393 into r1774; + or r1769 r1774 into r1775; + sub.w r1773 r393 into r1776; + ternary r1775 r1776 r1773 into r1777; + add r1768 4u128 into r1778; + ternary r1775 r1778 r1768 into r1779; + gte r1777 170141183460469231731687303715884105728u128 into r1780; + add.w r1777 r1777 into r1781; + shr r191 1u8 into r1782; + and r1782 1u128 into r1783; + add r1781 r1783 into r1784; + gte r1784 r393 into r1785; + or r1780 r1785 into r1786; + sub.w r1784 r393 into r1787; + ternary r1786 r1787 r1784 into r1788; + add r1779 2u128 into r1789; + ternary r1786 r1789 r1779 into r1790; + gte r1788 170141183460469231731687303715884105728u128 into r1791; + add.w r1788 r1788 into r1792; + and r217 1u128 into r1793; + add r1792 r1793 into r1794; + gte r1794 r393 into r1795; + or r1791 r1795 into r1796; + sub.w r1794 r393 into r1797; + ternary r1796 r1797 r1794 into r1798; + add r1790 1u128 into r1799; + ternary r1796 r1799 r1790 into r1800; + gt r1798 0u128 into r1801; + add r1800 1u128 into r1802; + ternary r1801 r1802 r1800 into r1803; + ternary r366 r3.sp r1803 into r1804; + ternary r121 r3.liq 1u128 into r1805; + and r362 18446744073709551615u128 into r1806; + shr r362 64u8 into r1807; + mul r1806 9223372036854775808u128 into r1808; + mul r1807 9223372036854775808u128 into r1809; + and r1808 18446744073709551615u128 into r1810; + shr r1808 64u8 into r1811; + and r1809 18446744073709551615u128 into r1812; + add r1811 r1812 into r1813; + and r1813 18446744073709551615u128 into r1814; + shr r1813 64u8 into r1815; + shr r1809 64u8 into r1816; + add r1816 r1815 into r1817; + and r1817 18446744073709551615u128 into r1818; + shr r1817 64u8 into r1819; + shl r1814 64u8 into r1820; + add r1820 r1810 into r1821; + shl r1819 64u8 into r1822; + add r1822 r1818 into r1823; + lt r1823 r1805 into r1824; + assert.eq r1824 true; + shr r1821 96u8 into r1825; + and r1825 4294967295u128 into r1826; + shl r1823 32u8 into r1827; + add r1827 r1826 into r1828; + div r1828 r1805 into r1829; + rem r1828 r1805 into r1830; + shr r1821 64u8 into r1831; + and r1831 4294967295u128 into r1832; + shl r1830 32u8 into r1833; + add r1833 r1832 into r1834; + shl r1829 32u8 into r1835; + div r1834 r1805 into r1836; + add r1835 r1836 into r1837; + rem r1834 r1805 into r1838; + shr r1821 32u8 into r1839; + and r1839 4294967295u128 into r1840; + shl r1838 32u8 into r1841; + add r1841 r1840 into r1842; + shl r1837 32u8 into r1843; + div r1842 r1805 into r1844; + add r1843 r1844 into r1845; + rem r1842 r1805 into r1846; + shr r1821 0u8 into r1847; + and r1847 4294967295u128 into r1848; + shl r1846 32u8 into r1849; + add r1849 r1848 into r1850; + shl r1845 32u8 into r1851; + div r1850 r1805 into r1852; + add r1851 r1852 into r1853; + rem r1850 r1805 into r1854; + add r1853 1u128 into r1855; + ternary r121 r1853 0u128 into r1856; + add r3.sp r1856 into r1857; + gt r1856 r3.sp into r1858; + ternary r1858 r3.sp r1856 into r1859; + sub r3.sp r1859 into r1860; + ternary r0.z r1804 r1857 into r1861; + ternary r365 r116 r1861 into r1862; + gt r1862 r3.sp into r1863; + ternary r1863 r3.sp r1862 into r1864; + ternary r1863 r1862 r3.sp into r1865; + gt r1864 0u128 into r1866; + gt r1865 0u128 into r1867; + and r1866 r1867 into r1868; + ternary r1867 r1865 1u128 into r1869; + ternary r1866 r1864 1u128 into r1870; + lt r368 r1870 into r1871; + assert.eq r1871 true; + shl r368 32u8 into r1872; + add r1872 r196 into r1873; + div r1873 r1870 into r1874; + rem r1873 r1870 into r1875; + shl r1875 32u8 into r1876; + add r1876 r202 into r1877; + shl r1874 32u8 into r1878; + div r1877 r1870 into r1879; + add r1878 r1879 into r1880; + rem r1877 r1870 into r1881; + shl r1881 32u8 into r1882; + add r1882 r210 into r1883; + shl r1880 32u8 into r1884; + div r1883 r1870 into r1885; + add r1884 r1885 into r1886; + rem r1883 r1870 into r1887; + shl r1887 32u8 into r1888; + add r1888 r218 into r1889; + shl r1886 32u8 into r1890; + div r1889 r1870 into r1891; + add r1890 r1891 into r1892; + rem r1889 r1870 into r1893; + gt r1893 0u128 into r1894; + add r1892 1u128 into r1895; + ternary r1894 r1895 r1892 into r1896; + lt r368 r1869 into r1897; + assert.eq r1897 true; + div r1873 r1869 into r1898; + rem r1873 r1869 into r1899; + shl r1899 32u8 into r1900; + add r1900 r202 into r1901; + shl r1898 32u8 into r1902; + div r1901 r1869 into r1903; + add r1902 r1903 into r1904; + rem r1901 r1869 into r1905; + shl r1905 32u8 into r1906; + add r1906 r210 into r1907; + shl r1904 32u8 into r1908; + div r1907 r1869 into r1909; + add r1908 r1909 into r1910; + rem r1907 r1869 into r1911; + shl r1911 32u8 into r1912; + add r1912 r218 into r1913; + shl r1910 32u8 into r1914; + div r1913 r1869 into r1915; + add r1914 r1915 into r1916; + rem r1913 r1869 into r1917; + add r1916 1u128 into r1918; + gte r1896 r1916 into r1919; + ternary r1919 r1896 r1916 into r1920; + ternary r1919 r1916 r1896 into r1921; + sub r1920 r1921 into r1922; + ternary r1919 r1922 0u128 into r1923; + lt r1864 r1865 into r1924; + and r1868 r1924 into r1925; + ternary r1925 r1923 0u128 into r1926; + gt r3.sp r1862 into r1927; + ternary r1927 r1862 r3.sp into r1928; + ternary r1927 r3.sp r1862 into r1929; + sub r1929 r1928 into r1930; + and r1930 18446744073709551615u128 into r1931; + shr r1930 64u8 into r1932; + mul r132 r1931 into r1933; + mul r132 r1932 into r1934; + mul r133 r1931 into r1935; + mul r133 r1932 into r1936; + and r1933 18446744073709551615u128 into r1937; + shr r1933 64u8 into r1938; + and r1934 18446744073709551615u128 into r1939; + add r1938 r1939 into r1940; + and r1935 18446744073709551615u128 into r1941; + add r1940 r1941 into r1942; + and r1942 18446744073709551615u128 into r1943; + shr r1942 64u8 into r1944; + shr r1934 64u8 into r1945; + shr r1935 64u8 into r1946; + add r1945 r1946 into r1947; + and r1936 18446744073709551615u128 into r1948; + add r1947 r1948 into r1949; + add r1949 r1944 into r1950; + and r1950 18446744073709551615u128 into r1951; + shr r1950 64u8 into r1952; + shr r1936 64u8 into r1953; + add r1953 r1952 into r1954; + shl r1943 64u8 into r1955; + add r1955 r1937 into r1956; + shl r1954 64u8 into r1957; + add r1957 r1951 into r1958; + lt r1958 9223372036854775808u128 into r1959; + assert.eq r1959 true; + shr r1956 96u8 into r1960; + and r1960 4294967295u128 into r1961; + shl r1958 32u8 into r1962; + add r1962 r1961 into r1963; + div r1963 9223372036854775808u128 into r1964; + rem r1963 9223372036854775808u128 into r1965; + shr r1956 64u8 into r1966; + and r1966 4294967295u128 into r1967; + shl r1965 32u8 into r1968; + add r1968 r1967 into r1969; + shl r1964 32u8 into r1970; + div r1969 9223372036854775808u128 into r1971; + add r1970 r1971 into r1972; + rem r1969 9223372036854775808u128 into r1973; + shr r1956 32u8 into r1974; + and r1974 4294967295u128 into r1975; + shl r1973 32u8 into r1976; + add r1976 r1975 into r1977; + shl r1972 32u8 into r1978; + div r1977 9223372036854775808u128 into r1979; + add r1978 r1979 into r1980; + rem r1977 9223372036854775808u128 into r1981; + shr r1956 0u8 into r1982; + and r1982 4294967295u128 into r1983; + shl r1981 32u8 into r1984; + add r1984 r1983 into r1985; + shl r1980 32u8 into r1986; + div r1985 9223372036854775808u128 into r1987; + add r1986 r1987 into r1988; + rem r1985 9223372036854775808u128 into r1989; + gt r1989 0u128 into r1990; + add r1988 1u128 into r1991; + ternary r1990 r1991 r1988 into r1992; + ternary r0.z r1926 r1992 into r1993; + ternary r365 r300 r1993 into r1994; + gt r1862 r3.sp into r1995; + ternary r1995 r3.sp r1862 into r1996; + ternary r1995 r1862 r3.sp into r1997; + sub r1997 r1996 into r1998; + and r1998 18446744073709551615u128 into r1999; + shr r1998 64u8 into r2000; + mul r132 r1999 into r2001; + mul r132 r2000 into r2002; + mul r133 r1999 into r2003; + mul r133 r2000 into r2004; + and r2001 18446744073709551615u128 into r2005; + shr r2001 64u8 into r2006; + and r2002 18446744073709551615u128 into r2007; + add r2006 r2007 into r2008; + and r2003 18446744073709551615u128 into r2009; + add r2008 r2009 into r2010; + and r2010 18446744073709551615u128 into r2011; + shr r2010 64u8 into r2012; + shr r2002 64u8 into r2013; + shr r2003 64u8 into r2014; + add r2013 r2014 into r2015; + and r2004 18446744073709551615u128 into r2016; + add r2015 r2016 into r2017; + add r2017 r2012 into r2018; + and r2018 18446744073709551615u128 into r2019; + shr r2018 64u8 into r2020; + shr r2004 64u8 into r2021; + add r2021 r2020 into r2022; + shl r2011 64u8 into r2023; + add r2023 r2005 into r2024; + shl r2022 64u8 into r2025; + add r2025 r2019 into r2026; + lt r2026 9223372036854775808u128 into r2027; + assert.eq r2027 true; + shr r2024 96u8 into r2028; + and r2028 4294967295u128 into r2029; + shl r2026 32u8 into r2030; + add r2030 r2029 into r2031; + div r2031 9223372036854775808u128 into r2032; + rem r2031 9223372036854775808u128 into r2033; + shr r2024 64u8 into r2034; + and r2034 4294967295u128 into r2035; + shl r2033 32u8 into r2036; + add r2036 r2035 into r2037; + shl r2032 32u8 into r2038; + div r2037 9223372036854775808u128 into r2039; + add r2038 r2039 into r2040; + rem r2037 9223372036854775808u128 into r2041; + shr r2024 32u8 into r2042; + and r2042 4294967295u128 into r2043; + shl r2041 32u8 into r2044; + add r2044 r2043 into r2045; + shl r2040 32u8 into r2046; + div r2045 9223372036854775808u128 into r2047; + add r2046 r2047 into r2048; + rem r2045 9223372036854775808u128 into r2049; + shr r2024 0u8 into r2050; + and r2050 4294967295u128 into r2051; + shl r2049 32u8 into r2052; + add r2052 r2051 into r2053; + shl r2048 32u8 into r2054; + div r2053 9223372036854775808u128 into r2055; + add r2054 r2055 into r2056; + rem r2053 9223372036854775808u128 into r2057; + add r2056 1u128 into r2058; + gt r1928 0u128 into r2059; + gt r1929 0u128 into r2060; + and r2059 r2060 into r2061; + ternary r2060 r1929 1u128 into r2062; + ternary r2059 r1928 1u128 into r2063; + lt r368 r2063 into r2064; + assert.eq r2064 true; + div r1873 r2063 into r2065; + rem r1873 r2063 into r2066; + shl r2066 32u8 into r2067; + add r2067 r202 into r2068; + shl r2065 32u8 into r2069; + div r2068 r2063 into r2070; + add r2069 r2070 into r2071; + rem r2068 r2063 into r2072; + shl r2072 32u8 into r2073; + add r2073 r210 into r2074; + shl r2071 32u8 into r2075; + div r2074 r2063 into r2076; + add r2075 r2076 into r2077; + rem r2074 r2063 into r2078; + shl r2078 32u8 into r2079; + add r2079 r218 into r2080; + shl r2077 32u8 into r2081; + div r2080 r2063 into r2082; + add r2081 r2082 into r2083; + rem r2080 r2063 into r2084; + add r2083 1u128 into r2085; + lt r368 r2062 into r2086; + assert.eq r2086 true; + div r1873 r2062 into r2087; + rem r1873 r2062 into r2088; + shl r2088 32u8 into r2089; + add r2089 r202 into r2090; + shl r2087 32u8 into r2091; + div r2090 r2062 into r2092; + add r2091 r2092 into r2093; + rem r2090 r2062 into r2094; + shl r2094 32u8 into r2095; + add r2095 r210 into r2096; + shl r2093 32u8 into r2097; + div r2096 r2062 into r2098; + add r2097 r2098 into r2099; + rem r2096 r2062 into r2100; + shl r2100 32u8 into r2101; + add r2101 r218 into r2102; + shl r2099 32u8 into r2103; + div r2102 r2062 into r2104; + add r2103 r2104 into r2105; + rem r2102 r2062 into r2106; + gt r2106 0u128 into r2107; + add r2105 1u128 into r2108; + ternary r2107 r2108 r2105 into r2109; + gte r2083 r2109 into r2110; + ternary r2110 r2083 r2109 into r2111; + ternary r2110 r2109 r2083 into r2112; + sub r2111 r2112 into r2113; + ternary r2110 r2113 0u128 into r2114; + lt r1928 r1929 into r2115; + and r2061 r2115 into r2116; + ternary r2116 r2114 0u128 into r2117; + ternary r0.z r2056 r2117 into r2118; + cast r0.fee_pips into r2119 as u128; + cast r0.fee_pips into r2120 as u128; + sub 1000000u128 r2120 into r2121; + and r1994 18446744073709551615u128 into r2122; + shr r1994 64u8 into r2123; + and r2119 18446744073709551615u128 into r2124; + shr r2119 64u8 into r2125; + mul r2122 r2124 into r2126; + mul r2122 r2125 into r2127; + mul r2123 r2124 into r2128; + mul r2123 r2125 into r2129; + and r2126 18446744073709551615u128 into r2130; + shr r2126 64u8 into r2131; + and r2127 18446744073709551615u128 into r2132; + add r2131 r2132 into r2133; + and r2128 18446744073709551615u128 into r2134; + add r2133 r2134 into r2135; + and r2135 18446744073709551615u128 into r2136; + shr r2135 64u8 into r2137; + shr r2127 64u8 into r2138; + shr r2128 64u8 into r2139; + add r2138 r2139 into r2140; + and r2129 18446744073709551615u128 into r2141; + add r2140 r2141 into r2142; + add r2142 r2137 into r2143; + and r2143 18446744073709551615u128 into r2144; + shr r2143 64u8 into r2145; + shr r2129 64u8 into r2146; + add r2146 r2145 into r2147; + shl r2136 64u8 into r2148; + add r2148 r2130 into r2149; + shl r2147 64u8 into r2150; + add r2150 r2144 into r2151; + lt r2151 r2121 into r2152; + assert.eq r2152 true; + shr r2149 96u8 into r2153; + and r2153 4294967295u128 into r2154; + shl r2151 32u8 into r2155; + add r2155 r2154 into r2156; + div r2156 r2121 into r2157; + rem r2156 r2121 into r2158; + shr r2149 64u8 into r2159; + and r2159 4294967295u128 into r2160; + shl r2158 32u8 into r2161; + add r2161 r2160 into r2162; + shl r2157 32u8 into r2163; + div r2162 r2121 into r2164; + add r2163 r2164 into r2165; + rem r2162 r2121 into r2166; + shr r2149 32u8 into r2167; + and r2167 4294967295u128 into r2168; + shl r2166 32u8 into r2169; + add r2169 r2168 into r2170; + shl r2165 32u8 into r2171; + div r2170 r2121 into r2172; + add r2171 r2172 into r2173; + rem r2170 r2121 into r2174; + shr r2149 0u8 into r2175; + and r2175 4294967295u128 into r2176; + shl r2174 32u8 into r2177; + add r2177 r2176 into r2178; + shl r2173 32u8 into r2179; + div r2178 r2121 into r2180; + add r2179 r2180 into r2181; + rem r2178 r2121 into r2182; + gt r2182 0u128 into r2183; + add r2181 1u128 into r2184; + ternary r2183 r2184 r2181 into r2185; + gt r1994 r3.rem into r2186; + ternary r2186 r3.rem r1994 into r2187; + sub r3.rem r2187 into r2188; + ternary r365 r2185 r2188 into r2189; + ternary r120 r116 r3.sp into r2190; + ternary r123 r1862 r2190 into r2191; + ternary r123 r1994 0u128 into r2192; + ternary r123 r2118 0u128 into r2193; + ternary r123 r2189 0u128 into r2194; + cast r0.fee_protocol into r2195 as u128; + mul r2194 r2195 into r2196; + div r2196 16u128 into r2197; + sub r2194 r2197 into r2198; + add r3.pf r2197 into r2199; + add r2192 r2194 into r2200; + gt r2200 r3.rem into r2201; + ternary r2201 r3.rem r2200 into r2202; + sub r3.rem r2202 into r2203; + add r3.out r2193 into r2204; + and r2198 18446744073709551615u128 into r2205; + shr r2198 64u8 into r2206; + mul r2205 9223372036854775808u128 into r2207; + mul r2206 9223372036854775808u128 into r2208; + and r2207 18446744073709551615u128 into r2209; + shr r2207 64u8 into r2210; + and r2208 18446744073709551615u128 into r2211; + add r2210 r2211 into r2212; + and r2212 18446744073709551615u128 into r2213; + shr r2212 64u8 into r2214; + shr r2208 64u8 into r2215; + add r2215 r2214 into r2216; + and r2216 18446744073709551615u128 into r2217; + shr r2216 64u8 into r2218; + shl r2213 64u8 into r2219; + add r2219 r2209 into r2220; + shl r2218 64u8 into r2221; + add r2221 r2217 into r2222; + lt r2222 r1805 into r2223; + assert.eq r2223 true; + shr r2220 96u8 into r2224; + and r2224 4294967295u128 into r2225; + shl r2222 32u8 into r2226; + add r2226 r2225 into r2227; + div r2227 r1805 into r2228; + rem r2227 r1805 into r2229; + shr r2220 64u8 into r2230; + and r2230 4294967295u128 into r2231; + shl r2229 32u8 into r2232; + add r2232 r2231 into r2233; + shl r2228 32u8 into r2234; + div r2233 r1805 into r2235; + add r2234 r2235 into r2236; + rem r2233 r1805 into r2237; + shr r2220 32u8 into r2238; + and r2238 4294967295u128 into r2239; + shl r2237 32u8 into r2240; + add r2240 r2239 into r2241; + shl r2236 32u8 into r2242; + div r2241 r1805 into r2243; + add r2242 r2243 into r2244; + rem r2241 r1805 into r2245; + shr r2220 0u8 into r2246; + and r2246 4294967295u128 into r2247; + shl r2245 32u8 into r2248; + add r2248 r2247 into r2249; + shl r2244 32u8 into r2250; + div r2249 r1805 into r2251; + add r2250 r2251 into r2252; + rem r2249 r1805 into r2253; + add r2252 1u128 into r2254; + mul.w r2198 9223372036854775808u128 into r2255; + mul.w r2252 r1805 into r2256; + sub.w r2255 r2256 into r2257; + sub r1805 r2257 into r2258; + gte r3.resid r2258 into r2259; + and r121 r2259 into r2260; + sub.w r3.resid r2258 into r2261; + add.w r2257 r3.resid into r2262; + ternary r2260 r2261 r2262 into r2263; + ternary r2260 1u128 0u128 into r2264; + add r2252 r2264 into r2265; + sub 340282366920938463463374607431768211455u128 r3.fg into r2266; + gt r2265 r2266 into r2267; + ternary r2267 0u128 r2265 into r2268; + add r3.fg r2268 into r2269; + gte r2265 r2266 into r2270; + ternary r2270 r2265 r2266 into r2271; + sub r2271 r2266 into r2272; + gte r2272 1u128 into r2273; + ternary r2273 r2272 1u128 into r2274; + sub r2274 1u128 into r2275; + ternary r2267 r2275 r2269 into r2276; + is.eq r2191 r111 into r2277; + and r3.crossed r2277 into r2278; + is.neq r111 r0.lim into r2279; + and r2278 r2279 into r2280; + ternary r0.z r2276 r0.slot_fg0 into r2281; + ternary r0.z r0.slot_fg1 r2276 into r2282; + gte r2281 r2.fee_growth_outside0_64 into r2283; + ternary r2283 r2281 r2.fee_growth_outside0_64 into r2284; + ternary r2283 r2.fee_growth_outside0_64 r2281 into r2285; + sub r2284 r2285 into r2286; + gt r2286 0u128 into r2287; + ternary r2287 r2286 1u128 into r2288; + sub 340282366920938463463374607431768211455u128 r2288 into r2289; + add r2289 1u128 into r2290; + ternary r2283 r2286 r2290 into r2291; + gte r2282 r2.fee_growth_outside1_64 into r2292; + ternary r2292 r2282 r2.fee_growth_outside1_64 into r2293; + ternary r2292 r2.fee_growth_outside1_64 r2282 into r2294; + sub r2293 r2294 into r2295; + gt r2295 0u128 into r2296; + ternary r2296 r2295 1u128 into r2297; + sub 340282366920938463463374607431768211455u128 r2297 into r2298; + add r2298 1u128 into r2299; + ternary r2292 r2295 r2299 into r2300; + ternary r2280 r2.pool r2.pool into r2301; + ternary r2280 r2.liquidity_net r2.liquidity_net into r2302; + ternary r2280 r2.liquidity_gross r2.liquidity_gross into r2303; + ternary r2280 r2.tick r2.tick into r2304; + ternary r2280 r2291 r2.fee_growth_outside0_64 into r2305; + ternary r2280 r2300 r2.fee_growth_outside1_64 into r2306; + ternary r2280 r2.prev r2.prev into r2307; + ternary r2280 r2.next r2.next into r2308; + cast r2301 r2302 r2303 r2304 r2305 r2306 r2307 r2308 into r2309 as Tick; + sub 0i128 r2.liquidity_net into r2310; + ternary r0.z r2310 r2.liquidity_net into r2311; + ternary r2280 r2311 0i128 into r2312; + sub 0i128 r2312 into r2313; + gt r2312 0i128 into r2314; + ternary r2314 r2312 0i128 into r2315; + gt r2313 0i128 into r2316; + ternary r2316 r2313 0i128 into r2317; + cast r2315 into r2318 as u128; + cast r2317 into r2319 as u128; + gte r3.liq r2319 into r2320; + assert.eq r2320 true; + sub r3.liq r2319 into r2321; + add r3.liq r2318 into r2322; + lt r2312 0i128 into r2323; + ternary r2323 r2321 r2322 into r2324; + ternary r2280 r2324 r3.liq into r2325; + sub r1 1i32 into r2326; + ternary r0.z r2326 r1 into r2327; + is.eq r2191 r3.sp into r2328; + gte r2191 18446744073709551616u128 into r2329; + shr r2191 64u8 into r2330; + ternary r2329 r2330 r2191 into r2331; + ternary r2329 64u32 0u32 into r2332; + gte r2331 4294967296u128 into r2333; + shr r2331 32u8 into r2334; + add r2332 32u32 into r2335; + ternary r2333 r2334 r2331 into r2336; + ternary r2333 r2335 r2332 into r2337; + gte r2336 65536u128 into r2338; + shr r2336 16u8 into r2339; + add r2337 16u32 into r2340; + ternary r2338 r2339 r2336 into r2341; + ternary r2338 r2340 r2337 into r2342; + gte r2341 256u128 into r2343; + shr r2341 8u8 into r2344; + add r2342 8u32 into r2345; + ternary r2343 r2344 r2341 into r2346; + ternary r2343 r2345 r2342 into r2347; + gte r2346 16u128 into r2348; + shr r2346 4u8 into r2349; + add r2347 4u32 into r2350; + ternary r2348 r2349 r2346 into r2351; + ternary r2348 r2350 r2347 into r2352; + gte r2351 4u128 into r2353; + shr r2351 2u8 into r2354; + add r2352 2u32 into r2355; + ternary r2353 r2354 r2351 into r2356; + ternary r2353 r2355 r2352 into r2357; + gte r2356 2u128 into r2358; + add r2357 1u32 into r2359; + ternary r2358 r2359 r2357 into r2360; + gte r2360 63u32 into r2361; + ternary r2361 r2360 63u32 into r2362; + ternary r2361 63u32 r2360 into r2363; + sub r2362 r2363 into r2364; + cast r2364 into r2365 as u8; + shr r2191 r2365 into r2366; + shl r2191 r2365 into r2367; + ternary r2361 r2366 r2367 into r2368; + mul r2368 r2368 into r2369; + shr r2369 63u8 into r2370; + shr r2370 64u8 into r2371; + shl r2371 63u8 into r2372; + cast r2371 into r2373 as u8; + shr r2370 r2373 into r2374; + mul r2374 r2374 into r2375; + shr r2375 63u8 into r2376; + shr r2376 64u8 into r2377; + shl r2377 62u8 into r2378; + or r2372 r2378 into r2379; + cast r2377 into r2380 as u8; + shr r2376 r2380 into r2381; + mul r2381 r2381 into r2382; + shr r2382 63u8 into r2383; + shr r2383 64u8 into r2384; + shl r2384 61u8 into r2385; + or r2379 r2385 into r2386; + cast r2384 into r2387 as u8; + shr r2383 r2387 into r2388; + mul r2388 r2388 into r2389; + shr r2389 63u8 into r2390; + shr r2390 64u8 into r2391; + shl r2391 60u8 into r2392; + or r2386 r2392 into r2393; + cast r2391 into r2394 as u8; + shr r2390 r2394 into r2395; + mul r2395 r2395 into r2396; + shr r2396 63u8 into r2397; + shr r2397 64u8 into r2398; + shl r2398 59u8 into r2399; + or r2393 r2399 into r2400; + cast r2398 into r2401 as u8; + shr r2397 r2401 into r2402; + mul r2402 r2402 into r2403; + shr r2403 63u8 into r2404; + shr r2404 64u8 into r2405; + shl r2405 58u8 into r2406; + or r2400 r2406 into r2407; + cast r2405 into r2408 as u8; + shr r2404 r2408 into r2409; + mul r2409 r2409 into r2410; + shr r2410 63u8 into r2411; + shr r2411 64u8 into r2412; + shl r2412 57u8 into r2413; + or r2407 r2413 into r2414; + cast r2412 into r2415 as u8; + shr r2411 r2415 into r2416; + mul r2416 r2416 into r2417; + shr r2417 63u8 into r2418; + shr r2418 64u8 into r2419; + shl r2419 56u8 into r2420; + or r2414 r2420 into r2421; + cast r2419 into r2422 as u8; + shr r2418 r2422 into r2423; + mul r2423 r2423 into r2424; + shr r2424 63u8 into r2425; + shr r2425 64u8 into r2426; + shl r2426 55u8 into r2427; + or r2421 r2427 into r2428; + cast r2426 into r2429 as u8; + shr r2425 r2429 into r2430; + mul r2430 r2430 into r2431; + shr r2431 63u8 into r2432; + shr r2432 64u8 into r2433; + shl r2433 54u8 into r2434; + or r2428 r2434 into r2435; + cast r2433 into r2436 as u8; + shr r2432 r2436 into r2437; + mul r2437 r2437 into r2438; + shr r2438 63u8 into r2439; + shr r2439 64u8 into r2440; + shl r2440 53u8 into r2441; + or r2435 r2441 into r2442; + cast r2440 into r2443 as u8; + shr r2439 r2443 into r2444; + mul r2444 r2444 into r2445; + shr r2445 63u8 into r2446; + shr r2446 64u8 into r2447; + shl r2447 52u8 into r2448; + or r2442 r2448 into r2449; + cast r2447 into r2450 as u8; + shr r2446 r2450 into r2451; + mul r2451 r2451 into r2452; + shr r2452 63u8 into r2453; + shr r2453 64u8 into r2454; + shl r2454 51u8 into r2455; + or r2449 r2455 into r2456; + cast r2454 into r2457 as u8; + shr r2453 r2457 into r2458; + mul r2458 r2458 into r2459; + shr r2459 63u8 into r2460; + shr r2460 64u8 into r2461; + shl r2461 50u8 into r2462; + or r2456 r2462 into r2463; + cast r2360 into r2464 as i128; + sub r2464 63i128 into r2465; + shl r2465 64u8 into r2466; + cast r2463 into r2467 as i128; + add r2466 r2467 into r2468; + div r2468 1330584781654114i128 into r2469; + cast r2469 into r2470 as i32; + add r2470 1i32 into r2471; + gte r2471 -873409i32 into r2472; + lte r2471 873409i32 into r2473; + and r2472 r2473 into r2474; + assert.eq r2474 true; + lt r2471 0i32 into r2475; + sub 0i32 r2471 into r2476; + ternary r2475 r2476 r2471 into r2477; + gte r2477 0i32 into r2478; + assert.eq r2478 true; + cast r2477 into r2479 as u32; + and r2479 3u32 into r2480; + is.eq r2480 0u32 into r2481; + is.eq r2480 1u32 into r2482; + is.eq r2480 2u32 into r2483; + ternary r2483 9222449791875588096u128 9221988703967300608u128 into r2484; + ternary r2482 9222910902837697536u128 r2484 into r2485; + ternary r2481 9223372036854775808u128 r2485 into r2486; + and r2479 4u32 into r2487; + is.neq r2487 0u32 into r2488; + mul r2486 9221527639111677952u128 into r2489; + shr r2489 63u8 into r2490; + ternary r2488 r2490 r2486 into r2491; + and r2479 8u32 into r2492; + is.neq r2492 0u32 into r2493; + mul r2491 9219683610192801792u128 into r2494; + shr r2494 63u8 into r2495; + ternary r2493 r2495 r2491 into r2496; + and r2479 16u32 into r2497; + is.neq r2497 0u32 into r2498; + mul r2496 9215996658532725760u128 into r2499; + shr r2499 63u8 into r2500; + ternary r2498 r2500 r2496 into r2501; + and r2479 32u32 into r2502; + is.neq r2502 0u32 into r2503; + mul r2501 9208627177859081216u128 into r2504; + shr r2504 63u8 into r2505; + ternary r2503 r2505 r2501 into r2506; + and r2479 64u32 into r2507; + is.neq r2507 0u32 into r2508; + mul r2506 9193905890596798464u128 into r2509; + shr r2509 63u8 into r2510; + ternary r2508 r2510 r2506 into r2511; + and r2479 128u32 into r2512; + is.neq r2512 0u32 into r2513; + mul r2511 9164533880601766912u128 into r2514; + shr r2514 63u8 into r2515; + ternary r2513 r2515 r2511 into r2516; + and r2479 256u32 into r2517; + is.neq r2517 0u32 into r2518; + mul r2516 9106071067403056128u128 into r2519; + shr r2519 63u8 into r2520; + ternary r2518 r2520 r2516 into r2521; + and r2479 512u32 into r2522; + is.neq r2522 0u32 into r2523; + mul r2521 8990261907820801024u128 into r2524; + shr r2524 63u8 into r2525; + ternary r2523 r2525 r2521 into r2526; + and r2479 1024u32 into r2527; + is.neq r2527 0u32 into r2528; + mul r2526 8763043369415622656u128 into r2529; + shr r2529 63u8 into r2530; + ternary r2528 r2530 r2526 into r2531; + and r2479 2048u32 into r2532; + is.neq r2532 0u32 into r2533; + mul r2531 8325689215117605888u128 into r2534; + shr r2534 63u8 into r2535; + ternary r2533 r2535 r2531 into r2536; + and r2479 4096u32 into r2537; + is.neq r2537 0u32 into r2538; + mul r2536 7515375139346884608u128 into r2539; + shr r2539 63u8 into r2540; + ternary r2538 r2540 r2536 into r2541; + and r2479 8192u32 into r2542; + is.neq r2542 0u32 into r2543; + mul r2541 6123667489441693696u128 into r2544; + shr r2544 63u8 into r2545; + ternary r2543 r2545 r2541 into r2546; + and r2479 16384u32 into r2547; + is.neq r2547 0u32 into r2548; + mul r2546 4065682634442729984u128 into r2549; + shr r2549 63u8 into r2550; + ternary r2548 r2550 r2546 into r2551; + and r2479 32768u32 into r2552; + is.neq r2552 0u32 into r2553; + mul r2551 1792161827361994496u128 into r2554; + shr r2554 63u8 into r2555; + ternary r2553 r2555 r2551 into r2556; + and r2479 65536u32 into r2557; + is.neq r2557 0u32 into r2558; + mul r2556 348228825923923264u128 into r2559; + shr r2559 63u8 into r2560; + ternary r2558 r2560 r2556 into r2561; + and r2479 131072u32 into r2562; + is.neq r2562 0u32 into r2563; + mul r2561 13147394978735516u128 into r2564; + shr r2564 63u8 into r2565; + ternary r2563 r2565 r2561 into r2566; + and r2479 262144u32 into r2567; + is.neq r2567 0u32 into r2568; + mul r2566 18740867660568u128 into r2569; + shr r2569 63u8 into r2570; + ternary r2568 r2570 r2566 into r2571; + and r2479 524288u32 into r2572; + is.neq r2572 0u32 into r2573; + mul r2571 38079361u128 into r2574; + shr r2574 63u8 into r2575; + ternary r2573 r2575 r2571 into r2576; + gt r2471 0i32 into r2577; + div 85070591730234615865843651857942052864u128 r2576 into r2578; + ternary r2577 r2578 r2576 into r2579; + gte r2191 r2579 into r2580; + ternary r2580 r2471 r2470 into r2581; + gte r2581 -873409i32 into r2582; + lte r2581 873409i32 into r2583; + and r2582 r2583 into r2584; + assert.eq r2584 true; + lt r2581 0i32 into r2585; + sub 0i32 r2581 into r2586; + ternary r2585 r2586 r2581 into r2587; + gte r2587 0i32 into r2588; + assert.eq r2588 true; + cast r2587 into r2589 as u32; + and r2589 3u32 into r2590; + is.eq r2590 0u32 into r2591; + is.eq r2590 1u32 into r2592; + is.eq r2590 2u32 into r2593; + ternary r2593 9222449791875588096u128 9221988703967300608u128 into r2594; + ternary r2592 9222910902837697536u128 r2594 into r2595; + ternary r2591 9223372036854775808u128 r2595 into r2596; + and r2589 4u32 into r2597; + is.neq r2597 0u32 into r2598; + mul r2596 9221527639111677952u128 into r2599; + shr r2599 63u8 into r2600; + ternary r2598 r2600 r2596 into r2601; + and r2589 8u32 into r2602; + is.neq r2602 0u32 into r2603; + mul r2601 9219683610192801792u128 into r2604; + shr r2604 63u8 into r2605; + ternary r2603 r2605 r2601 into r2606; + and r2589 16u32 into r2607; + is.neq r2607 0u32 into r2608; + mul r2606 9215996658532725760u128 into r2609; + shr r2609 63u8 into r2610; + ternary r2608 r2610 r2606 into r2611; + and r2589 32u32 into r2612; + is.neq r2612 0u32 into r2613; + mul r2611 9208627177859081216u128 into r2614; + shr r2614 63u8 into r2615; + ternary r2613 r2615 r2611 into r2616; + and r2589 64u32 into r2617; + is.neq r2617 0u32 into r2618; + mul r2616 9193905890596798464u128 into r2619; + shr r2619 63u8 into r2620; + ternary r2618 r2620 r2616 into r2621; + and r2589 128u32 into r2622; + is.neq r2622 0u32 into r2623; + mul r2621 9164533880601766912u128 into r2624; + shr r2624 63u8 into r2625; + ternary r2623 r2625 r2621 into r2626; + and r2589 256u32 into r2627; + is.neq r2627 0u32 into r2628; + mul r2626 9106071067403056128u128 into r2629; + shr r2629 63u8 into r2630; + ternary r2628 r2630 r2626 into r2631; + and r2589 512u32 into r2632; + is.neq r2632 0u32 into r2633; + mul r2631 8990261907820801024u128 into r2634; + shr r2634 63u8 into r2635; + ternary r2633 r2635 r2631 into r2636; + and r2589 1024u32 into r2637; + is.neq r2637 0u32 into r2638; + mul r2636 8763043369415622656u128 into r2639; + shr r2639 63u8 into r2640; + ternary r2638 r2640 r2636 into r2641; + and r2589 2048u32 into r2642; + is.neq r2642 0u32 into r2643; + mul r2641 8325689215117605888u128 into r2644; + shr r2644 63u8 into r2645; + ternary r2643 r2645 r2641 into r2646; + and r2589 4096u32 into r2647; + is.neq r2647 0u32 into r2648; + mul r2646 7515375139346884608u128 into r2649; + shr r2649 63u8 into r2650; + ternary r2648 r2650 r2646 into r2651; + and r2589 8192u32 into r2652; + is.neq r2652 0u32 into r2653; + mul r2651 6123667489441693696u128 into r2654; + shr r2654 63u8 into r2655; + ternary r2653 r2655 r2651 into r2656; + and r2589 16384u32 into r2657; + is.neq r2657 0u32 into r2658; + mul r2656 4065682634442729984u128 into r2659; + shr r2659 63u8 into r2660; + ternary r2658 r2660 r2656 into r2661; + and r2589 32768u32 into r2662; + is.neq r2662 0u32 into r2663; + mul r2661 1792161827361994496u128 into r2664; + shr r2664 63u8 into r2665; + ternary r2663 r2665 r2661 into r2666; + and r2589 65536u32 into r2667; + is.neq r2667 0u32 into r2668; + mul r2666 348228825923923264u128 into r2669; + shr r2669 63u8 into r2670; + ternary r2668 r2670 r2666 into r2671; + and r2589 131072u32 into r2672; + is.neq r2672 0u32 into r2673; + mul r2671 13147394978735516u128 into r2674; + shr r2674 63u8 into r2675; + ternary r2673 r2675 r2671 into r2676; + and r2589 262144u32 into r2677; + is.neq r2677 0u32 into r2678; + mul r2676 18740867660568u128 into r2679; + shr r2679 63u8 into r2680; + ternary r2678 r2680 r2676 into r2681; + and r2589 524288u32 into r2682; + is.neq r2682 0u32 into r2683; + mul r2681 38079361u128 into r2684; + shr r2684 63u8 into r2685; + ternary r2683 r2685 r2681 into r2686; + gt r2581 0i32 into r2687; + div 85070591730234615865843651857942052864u128 r2686 into r2688; + ternary r2687 r2688 r2686 into r2689; + gt r2689 r2191 into r2690; + sub r2581 1i32 into r2691; + ternary r2690 r2691 r2581 into r2692; + ternary r2328 r3.tk r2692 into r2693; + ternary r2280 r2327 r2693 into r2694; + ternary r0.z r2.prev r1 into r2695; + ternary r2280 r2695 r3.nb into r2696; + ternary r0.z r1 r2.next into r2697; + ternary r2280 r2697 r3.na into r2698; + cast r2191 r2203 r2204 r2276 r2325 r2694 r2280 r2199 r2696 r2698 r2263 into r2699 as SwapIterState; + output r2699 as SwapIterState.public; + output r2309 as Tick.public; + +function swap: + input r0 as dynamic.record; + input r1 as field.private; + input r2 as address.public; + input r3 as field.public; + input r4 as boolean.public; + input r5 as u128.public; + input r6 as u128.public; + input r7 as u128.public; + input r8 as u64.public; + input r9 as u32.public; + input r10 as field.public; + input r11 as field.public; + call verify_blinded_address shield_swap_v3.aleo self.signer r1 r2; + cast r3 r4 r5 r6 r7 r2 r8 r9 into r12 as SwapRequest; + cast r3 r4 r5 r7 r2 r8 r2 into r13 as SwapKey; + hash.bhp256 r13 into r14 as field; + ternary r4 r10 r11 into r15; + ternary r4 r11 r10 into r16; + cast aleo1t08epjqqv8h7jpuy2m2cxm80zy2pcy5c4f3m82hnac4sjmdrjyysvx3s2h r14 r15 r16 r12 self.caller r2 into r17 as SwapComplianceRecord.record; + call.dynamic r15 'aleo' 'transfer_private_to_public' with r0 shield_swap_v3.aleo r5 (as dynamic.record address.public u128.public) into r18 r19 (as dynamic.record dynamic.future); + async swap r19 r12 r10 r11 r14 r15 r16 r2 into r20; + output r14 as field.public; + output r18 as dynamic.record; + output r17 as SwapComplianceRecord.record; + output r20 as shield_swap_v3.aleo/swap.future; + +finalize swap: + input r0 as dynamic.future; + input r1 as SwapRequest.public; + input r2 as field.public; + input r3 as field.public; + input r4 as field.public; + input r5 as field.public; + input r6 as field.public; + input r7 as address.public; + await r0; + lte block.height r1.deadline into r8; + assert.eq r8 true; + get.or_use global_paused[true] false into r9; + not r9 into r10; + assert.eq r10 true; + get pools[r1.pool] into r11; + assert.eq r11.enabled true; + get.or_use token_paused[r11.token0] false into r12; + not r12 into r13; + assert.eq r13 true; + get.or_use token_paused[r11.token1] false into r14; + not r14 into r15; + assert.eq r15 true; + cast r11.token0 r11.token1 into r16 as PairKey; + get.or_use pair_paused[r16] false into r17; + not r17 into r18; + assert.eq r18 true; + is.eq r11.token0 r2 into r19; + assert.eq r19 true; + is.eq r11.token1 r3 into r20; + assert.eq r20 true; + get slots[r1.pool] into r21; + cast r11.fee into r22 as u32; + gte r1.sqrt_price_limit 19029805711u128 into r23; + lte r1.sqrt_price_limit 4470386772317930780047134862u128 into r24; + and r23 r24 into r25; + assert.eq r25 true; + lt r1.sqrt_price_limit r21.sqrt_price into r26; + gt r1.sqrt_price_limit r21.sqrt_price into r27; + ternary r1.zero_for_one r26 r27 into r28; + assert.eq r28 true; + gt r1.amount_in 0u128 into r29; + assert.eq r29 true; + ternary r1.zero_for_one r11.scale0 r11.scale1 into r30; + ternary r1.zero_for_one r11.scale1 r11.scale0 into r31; + rem r1.amount_in r30 into r32; + is.eq r32 0u128 into r33; + assert.eq r33 true; + div r1.amount_in r30 into r34; + ternary r1.zero_for_one r21.fee_growth_global0_x_64 r21.fee_growth_global1_x_64 into r35; + ternary r1.zero_for_one r21.fee_residual0_x_64 r21.fee_residual1_x_64 into r36; + cast r1.zero_for_one r1.sqrt_price_limit r22 r21.fee_protocol r21.fee_growth_global0_x_64 r21.fee_growth_global1_x_64 into r37 as SwapIterCfg; + ternary r1.zero_for_one r21.next_init_below r21.next_init_above into r38; + cast r1.pool r38 into r39 as TickKey; + hash.bhp256 r39 into r40 as field; + get ticks[r40] into r41; + cast r21.sqrt_price r34 0u128 r35 r21.liquidity r21.tick true 0u128 r21.next_init_below r21.next_init_above r36 into r42 as SwapIterState; + call view_swap_iteration r37 r38 r41 r42 into r43 r44; + cast r1.pool r38 into r45 as TickKey; + hash.bhp256 r45 into r46 as field; + set r44 into ticks[r46]; + ternary r1.zero_for_one r43.nb r43.na into r47; + cast r1.pool r47 into r48 as TickKey; + hash.bhp256 r48 into r49 as field; + get ticks[r49] into r50; + cast r43.sp r43.rem r43.out r43.fg r43.liq r43.tk r43.crossed r43.pf r43.nb r43.na r43.resid into r51 as SwapIterState; + call view_swap_iteration r37 r47 r50 r51 into r52 r53; + cast r1.pool r47 into r54 as TickKey; + hash.bhp256 r54 into r55 as field; + set r53 into ticks[r55]; + ternary r1.zero_for_one r52.nb r52.na into r56; + cast r1.pool r56 into r57 as TickKey; + hash.bhp256 r57 into r58 as field; + get ticks[r58] into r59; + cast r52.sp r52.rem r52.out r52.fg r52.liq r52.tk r52.crossed r52.pf r52.nb r52.na r52.resid into r60 as SwapIterState; + call view_swap_iteration r37 r56 r59 r60 into r61 r62; + cast r1.pool r56 into r63 as TickKey; + hash.bhp256 r63 into r64 as field; + set r62 into ticks[r64]; + ternary r1.zero_for_one r61.nb r61.na into r65; + cast r1.pool r65 into r66 as TickKey; + hash.bhp256 r66 into r67 as field; + get ticks[r67] into r68; + cast r61.sp r61.rem r61.out r61.fg r61.liq r61.tk r61.crossed r61.pf r61.nb r61.na r61.resid into r69 as SwapIterState; + call view_swap_iteration r37 r65 r68 r69 into r70 r71; + cast r1.pool r65 into r72 as TickKey; + hash.bhp256 r72 into r73 as field; + set r71 into ticks[r73]; + ternary r1.zero_for_one r70.nb r70.na into r74; + cast r1.pool r74 into r75 as TickKey; + hash.bhp256 r75 into r76 as field; + get ticks[r76] into r77; + cast r70.sp r70.rem r70.out r70.fg r70.liq r70.tk r70.crossed r70.pf r70.nb r70.na r70.resid into r78 as SwapIterState; + call view_swap_iteration r37 r74 r77 r78 into r79 r80; + cast r1.pool r74 into r81 as TickKey; + hash.bhp256 r81 into r82 as field; + set r80 into ticks[r82]; + mul r79.out r31 into r83; + mul r79.rem r30 into r84; + gte r83 r1.amount_out_min into r85; + assert.eq r85 true; + add r21.protocol_fees0 r79.pf into r86; + ternary r1.zero_for_one r86 r21.protocol_fees0 into r87; + add r21.protocol_fees1 r79.pf into r88; + ternary r1.zero_for_one r21.protocol_fees1 r88 into r89; + ternary r1.zero_for_one r79.fg r21.fee_growth_global0_x_64 into r90; + ternary r1.zero_for_one r21.fee_growth_global1_x_64 r79.fg into r91; + ternary r1.zero_for_one r79.resid r21.fee_residual0_x_64 into r92; + ternary r1.zero_for_one r21.fee_residual1_x_64 r79.resid into r93; + cast r79.tk r21.tick_spacing r79.sp r21.fee_protocol r79.liq r90 r91 r92 r93 r21.max_liquidity_per_tick r87 r89 r79.nb r79.na into r94 as Slot; + set r94 into slots[r1.pool]; + contains swap_outputs[r4] into r95; + not r95 into r96; + assert.eq r96 true; + cast r1.recipient r7 r5 r6 r83 r84 r5 0u128 r5 0u128 into r97 as SwapOutput; + set r97 into swap_outputs[r4]; + contains used_blinded_addresses[r7] into r98; + not r98 into r99; + assert.eq r99 true; + set true into used_blinded_addresses[r7]; + +function claim_swap_output: + input r0 as field.private; + input r1 as address.public; + input r2 as field.public; + input r3 as field.public; + input r4 as field.public; + input r5 as u128.public; + input r6 as u128.public; + call verify_blinded_address shield_swap_v3.aleo self.signer r0 r1; + call.dynamic r4 'aleo' 'transfer_public_to_private' with self.signer r5 (as address.private u128.public) into r7 r8 (as dynamic.record dynamic.future); + call.dynamic r3 'aleo' 'transfer_public_to_private' with self.signer r6 (as address.private u128.public) into r9 r10 (as dynamic.record dynamic.future); + async claim_swap_output r8 r10 r2 r3 r4 r5 r6 r1 into r11; + output r7 as dynamic.record; + output r9 as dynamic.record; + output r11 as shield_swap_v3.aleo/claim_swap_output.future; + +finalize claim_swap_output: + input r0 as dynamic.future; + input r1 as dynamic.future; + input r2 as field.public; + input r3 as field.public; + input r4 as field.public; + input r5 as u128.public; + input r6 as u128.public; + input r7 as address.public; + await r0; + await r1; + get swap_outputs[r2] into r8; + is.eq r8.caller r7 into r9; + assert.eq r9 true; + is.eq r8.recipient r7 into r10; + assert.eq r10 true; + is.eq r8.token_in r3 into r11; + assert.eq r11 true; + is.eq r8.token_out r4 into r12; + assert.eq r12 true; + is.eq r8.amount_out r5 into r13; + assert.eq r13 true; + is.eq r8.amount_remaining r6 into r14; + assert.eq r14 true; + is.eq r8.amount_remaining_1 0u128 into r15; + assert.eq r15 true; + is.eq r8.amount_remaining_2 0u128 into r16; + assert.eq r16 true; + remove swap_outputs[r2]; + +function swap_multi_hop: + input r0 as field.private; + input r1 as address.public; + input r2 as dynamic.record; + input r3 as field.public; + input r4 as field.public; + input r5 as u128.public; + input r6 as u128.public; + input r7 as SwapHop.public; + input r8 as SwapHop.public; + input r9 as SwapHop.public; + input r10 as u8.public; + input r11 as u64.public; + input r12 as u32.public; + call verify_blinded_address shield_swap_v3.aleo self.signer r0 r1; + cast r3 r4 r5 r6 r1 r7 r8 r9 r10 r11 r12 r1 into r13 as SwapMultiHopRequest; + hash.bhp256 r13 into r14 as field; + cast aleo1t08epjqqv8h7jpuy2m2cxm80zy2pcy5c4f3m82hnac4sjmdrjyysvx3s2h r14 r13 self.caller r1 into r15 as MultiHopSwapComplianceRecord.record; + call.dynamic r3 'aleo' 'transfer_private_to_public' with r2 shield_swap_v3.aleo r5 (as dynamic.record address.public u128.public) into r16 r17 (as dynamic.record dynamic.future); + async swap_multi_hop r17 r13 r14 into r18; + output r14 as field.public; + output r16 as dynamic.record; + output r15 as MultiHopSwapComplianceRecord.record; + output r18 as shield_swap_v3.aleo/swap_multi_hop.future; + +finalize swap_multi_hop: + input r0 as dynamic.future; + input r1 as SwapMultiHopRequest.public; + input r2 as field.public; + await r0; + lte block.height r1.deadline into r3; + assert.eq r3 true; + gte r1.hop_count 2u8 into r4; + lte r1.hop_count 3u8 into r5; + and r4 r5 into r6; + assert.eq r6 true; + gt r1.amount_in 0u128 into r7; + assert.eq r7 true; + get.or_use global_paused[true] false into r8; + not r8 into r9; + assert.eq r9 true; + get pools[r1.hop0.pool] into r10; + assert.eq r10.enabled true; + get.or_use token_paused[r10.token0] false into r11; + not r11 into r12; + assert.eq r12 true; + get.or_use token_paused[r10.token1] false into r13; + not r13 into r14; + assert.eq r14 true; + cast r10.token0 r10.token1 into r15 as PairKey; + get.or_use pair_paused[r15] false into r16; + not r16 into r17; + assert.eq r17 true; + ternary r1.hop0.zero_for_one r10.token0 r10.token1 into r18; + ternary r1.hop0.zero_for_one r10.token1 r10.token0 into r19; + is.eq r18 r1.token_in into r20; + assert.eq r20 true; + get slots[r1.hop0.pool] into r21; + cast r10.fee into r22 as u32; + gte r1.hop0.sqrt_price_limit 19029805711u128 into r23; + lte r1.hop0.sqrt_price_limit 4470386772317930780047134862u128 into r24; + and r23 r24 into r25; + assert.eq r25 true; + lt r1.hop0.sqrt_price_limit r21.sqrt_price into r26; + gt r1.hop0.sqrt_price_limit r21.sqrt_price into r27; + ternary r1.hop0.zero_for_one r26 r27 into r28; + assert.eq r28 true; + ternary r1.hop0.zero_for_one r10.scale0 r10.scale1 into r29; + rem r1.amount_in r29 into r30; + is.eq r30 0u128 into r31; + assert.eq r31 true; + div r1.amount_in r29 into r32; + ternary r1.hop0.zero_for_one r21.fee_growth_global0_x_64 r21.fee_growth_global1_x_64 into r33; + ternary r1.hop0.zero_for_one r21.fee_residual0_x_64 r21.fee_residual1_x_64 into r34; + cast r1.hop0.zero_for_one r1.hop0.sqrt_price_limit r22 r21.fee_protocol r21.fee_growth_global0_x_64 r21.fee_growth_global1_x_64 into r35 as SwapIterCfg; + ternary r1.hop0.zero_for_one r21.next_init_below r21.next_init_above into r36; + cast r1.hop0.pool r36 into r37 as TickKey; + hash.bhp256 r37 into r38 as field; + get ticks[r38] into r39; + cast r21.sqrt_price r32 0u128 r33 r21.liquidity r21.tick true 0u128 r21.next_init_below r21.next_init_above r34 into r40 as SwapIterState; + call view_swap_iteration r35 r36 r39 r40 into r41 r42; + cast r1.hop0.pool r36 into r43 as TickKey; + hash.bhp256 r43 into r44 as field; + set r42 into ticks[r44]; + ternary r1.hop0.zero_for_one r41.nb r41.na into r45; + cast r1.hop0.pool r45 into r46 as TickKey; + hash.bhp256 r46 into r47 as field; + get ticks[r47] into r48; + cast r41.sp r41.rem r41.out r41.fg r41.liq r41.tk r41.crossed r41.pf r41.nb r41.na r41.resid into r49 as SwapIterState; + call view_swap_iteration r35 r45 r48 r49 into r50 r51; + cast r1.hop0.pool r45 into r52 as TickKey; + hash.bhp256 r52 into r53 as field; + set r51 into ticks[r53]; + ternary r1.hop0.zero_for_one r50.nb r50.na into r54; + cast r1.hop0.pool r54 into r55 as TickKey; + hash.bhp256 r55 into r56 as field; + get ticks[r56] into r57; + cast r50.sp r50.rem r50.out r50.fg r50.liq r50.tk r50.crossed r50.pf r50.nb r50.na r50.resid into r58 as SwapIterState; + call view_swap_iteration r35 r54 r57 r58 into r59 r60; + cast r1.hop0.pool r54 into r61 as TickKey; + hash.bhp256 r61 into r62 as field; + set r60 into ticks[r62]; + add r21.protocol_fees0 r59.pf into r63; + ternary r1.hop0.zero_for_one r63 r21.protocol_fees0 into r64; + add r21.protocol_fees1 r59.pf into r65; + ternary r1.hop0.zero_for_one r21.protocol_fees1 r65 into r66; + ternary r1.hop0.zero_for_one r59.fg r21.fee_growth_global0_x_64 into r67; + ternary r1.hop0.zero_for_one r21.fee_growth_global1_x_64 r59.fg into r68; + ternary r1.hop0.zero_for_one r59.resid r21.fee_residual0_x_64 into r69; + ternary r1.hop0.zero_for_one r21.fee_residual1_x_64 r59.resid into r70; + cast r59.tk r21.tick_spacing r59.sp r21.fee_protocol r59.liq r67 r68 r69 r70 r21.max_liquidity_per_tick r64 r66 r59.nb r59.na into r71 as Slot; + set r71 into slots[r1.hop0.pool]; + get pools[r1.hop1.pool] into r72; + assert.eq r72.enabled true; + get.or_use token_paused[r72.token0] false into r73; + not r73 into r74; + assert.eq r74 true; + get.or_use token_paused[r72.token1] false into r75; + not r75 into r76; + assert.eq r76 true; + cast r72.token0 r72.token1 into r77 as PairKey; + get.or_use pair_paused[r77] false into r78; + not r78 into r79; + assert.eq r79 true; + ternary r1.hop1.zero_for_one r72.token0 r72.token1 into r80; + ternary r1.hop1.zero_for_one r72.token1 r72.token0 into r81; + is.eq r80 r19 into r82; + assert.eq r82 true; + get slots[r1.hop1.pool] into r83; + cast r72.fee into r84 as u32; + gte r1.hop1.sqrt_price_limit 19029805711u128 into r85; + lte r1.hop1.sqrt_price_limit 4470386772317930780047134862u128 into r86; + and r85 r86 into r87; + assert.eq r87 true; + lt r1.hop1.sqrt_price_limit r83.sqrt_price into r88; + gt r1.hop1.sqrt_price_limit r83.sqrt_price into r89; + ternary r1.hop1.zero_for_one r88 r89 into r90; + assert.eq r90 true; + ternary r1.hop1.zero_for_one r83.fee_growth_global0_x_64 r83.fee_growth_global1_x_64 into r91; + ternary r1.hop1.zero_for_one r83.fee_residual0_x_64 r83.fee_residual1_x_64 into r92; + cast r1.hop1.zero_for_one r1.hop1.sqrt_price_limit r84 r83.fee_protocol r83.fee_growth_global0_x_64 r83.fee_growth_global1_x_64 into r93 as SwapIterCfg; + ternary r1.hop1.zero_for_one r83.next_init_below r83.next_init_above into r94; + cast r1.hop1.pool r94 into r95 as TickKey; + hash.bhp256 r95 into r96 as field; + get ticks[r96] into r97; + cast r83.sqrt_price r59.out 0u128 r91 r83.liquidity r83.tick true 0u128 r83.next_init_below r83.next_init_above r92 into r98 as SwapIterState; + call view_swap_iteration r93 r94 r97 r98 into r99 r100; + cast r1.hop1.pool r94 into r101 as TickKey; + hash.bhp256 r101 into r102 as field; + set r100 into ticks[r102]; + ternary r1.hop1.zero_for_one r99.nb r99.na into r103; + cast r1.hop1.pool r103 into r104 as TickKey; + hash.bhp256 r104 into r105 as field; + get ticks[r105] into r106; + cast r99.sp r99.rem r99.out r99.fg r99.liq r99.tk r99.crossed r99.pf r99.nb r99.na r99.resid into r107 as SwapIterState; + call view_swap_iteration r93 r103 r106 r107 into r108 r109; + cast r1.hop1.pool r103 into r110 as TickKey; + hash.bhp256 r110 into r111 as field; + set r109 into ticks[r111]; + ternary r1.hop1.zero_for_one r108.nb r108.na into r112; + cast r1.hop1.pool r112 into r113 as TickKey; + hash.bhp256 r113 into r114 as field; + get ticks[r114] into r115; + cast r108.sp r108.rem r108.out r108.fg r108.liq r108.tk r108.crossed r108.pf r108.nb r108.na r108.resid into r116 as SwapIterState; + call view_swap_iteration r93 r112 r115 r116 into r117 r118; + cast r1.hop1.pool r112 into r119 as TickKey; + hash.bhp256 r119 into r120 as field; + set r118 into ticks[r120]; + add r83.protocol_fees0 r117.pf into r121; + ternary r1.hop1.zero_for_one r121 r83.protocol_fees0 into r122; + add r83.protocol_fees1 r117.pf into r123; + ternary r1.hop1.zero_for_one r83.protocol_fees1 r123 into r124; + ternary r1.hop1.zero_for_one r117.fg r83.fee_growth_global0_x_64 into r125; + ternary r1.hop1.zero_for_one r83.fee_growth_global1_x_64 r117.fg into r126; + ternary r1.hop1.zero_for_one r117.resid r83.fee_residual0_x_64 into r127; + ternary r1.hop1.zero_for_one r83.fee_residual1_x_64 r117.resid into r128; + cast r117.tk r83.tick_spacing r117.sp r83.fee_protocol r117.liq r125 r126 r127 r128 r83.max_liquidity_per_tick r122 r124 r117.nb r117.na into r129 as Slot; + set r129 into slots[r1.hop1.pool]; + is.eq r1.hop_count 3u8 into r130; + cast 0field 0field 0u16 false 1u128 1u128 into r131 as PoolState; + get.or_use pools[r1.hop2.pool] r131 into r132; + branch.eq r130 false to end_then_0_0; + assert.eq r132.enabled true; + get.or_use token_paused[r132.token0] false into r133; + not r133 into r134; + assert.eq r134 true; + get.or_use token_paused[r132.token1] false into r135; + not r135 into r136; + assert.eq r136 true; + cast r132.token0 r132.token1 into r137 as PairKey; + get.or_use pair_paused[r137] false into r138; + not r138 into r139; + assert.eq r139 true; + branch.eq true true to end_otherwise_0_1; + position end_then_0_0; + position end_otherwise_0_1; + ternary r1.hop2.zero_for_one r132.token0 r132.token1 into r140; + ternary r1.hop2.zero_for_one r132.token1 r132.token0 into r141; + not r130 into r142; + is.eq r140 r81 into r143; + or r142 r143 into r144; + assert.eq r144 true; + ternary r130 r141 r81 into r145; + is.eq r145 r1.token_out into r146; + assert.eq r146 true; + cast 0i32 1u32 9223372036854775808u128 0u8 0u128 0u128 0u128 0u128 0u128 0u128 0u128 0u128 0i32 0i32 into r147 as Slot; + get.or_use slots[r1.hop2.pool] r147 into r148; + cast r132.fee into r149 as u32; + gte r1.hop2.sqrt_price_limit 19029805711u128 into r150; + lte r1.hop2.sqrt_price_limit 4470386772317930780047134862u128 into r151; + and r150 r151 into r152; + or r142 r152 into r153; + assert.eq r153 true; + lt r1.hop2.sqrt_price_limit r148.sqrt_price into r154; + gt r1.hop2.sqrt_price_limit r148.sqrt_price into r155; + ternary r1.hop2.zero_for_one r154 r155 into r156; + or r142 r156 into r157; + assert.eq r157 true; + ternary r1.hop2.zero_for_one r148.fee_growth_global0_x_64 r148.fee_growth_global1_x_64 into r158; + ternary r1.hop2.zero_for_one r148.fee_residual0_x_64 r148.fee_residual1_x_64 into r159; + cast r1.hop2.zero_for_one r1.hop2.sqrt_price_limit r149 r148.fee_protocol r148.fee_growth_global0_x_64 r148.fee_growth_global1_x_64 into r160 as SwapIterCfg; + ternary r1.hop2.zero_for_one r148.next_init_below r148.next_init_above into r161; + cast r1.hop2.pool 0i128 0u128 r161 0u128 0u128 r161 r161 into r162 as Tick; + cast r1.hop2.pool r161 into r163 as TickKey; + hash.bhp256 r163 into r164 as field; + get.or_use ticks[r164] r162 into r165; + cast r148.sqrt_price r117.out 0u128 r158 r148.liquidity r148.tick r130 0u128 r148.next_init_below r148.next_init_above r159 into r166 as SwapIterState; + call view_swap_iteration r160 r161 r165 r166 into r167 r168; + branch.eq r130 false to end_then_0_2; + cast r1.hop2.pool r161 into r169 as TickKey; + hash.bhp256 r169 into r170 as field; + set r168 into ticks[r170]; + branch.eq true true to end_otherwise_0_3; + position end_then_0_2; + position end_otherwise_0_3; + ternary r1.hop2.zero_for_one r167.nb r167.na into r171; + cast r1.hop2.pool 0i128 0u128 r171 0u128 0u128 r171 r171 into r172 as Tick; + cast r1.hop2.pool r171 into r173 as TickKey; + hash.bhp256 r173 into r174 as field; + get.or_use ticks[r174] r172 into r175; + cast r167.sp r167.rem r167.out r167.fg r167.liq r167.tk r167.crossed r167.pf r167.nb r167.na r167.resid into r176 as SwapIterState; + call view_swap_iteration r160 r171 r175 r176 into r177 r178; + branch.eq r130 false to end_then_0_4; + cast r1.hop2.pool r171 into r179 as TickKey; + hash.bhp256 r179 into r180 as field; + set r178 into ticks[r180]; + branch.eq true true to end_otherwise_0_5; + position end_then_0_4; + position end_otherwise_0_5; + ternary r1.hop2.zero_for_one r177.nb r177.na into r181; + cast r1.hop2.pool 0i128 0u128 r181 0u128 0u128 r181 r181 into r182 as Tick; + cast r1.hop2.pool r181 into r183 as TickKey; + hash.bhp256 r183 into r184 as field; + get.or_use ticks[r184] r182 into r185; + cast r177.sp r177.rem r177.out r177.fg r177.liq r177.tk r177.crossed r177.pf r177.nb r177.na r177.resid into r186 as SwapIterState; + call view_swap_iteration r160 r181 r185 r186 into r187 r188; + branch.eq r130 false to end_then_0_6; + cast r1.hop2.pool r181 into r189 as TickKey; + hash.bhp256 r189 into r190 as field; + set r188 into ticks[r190]; + branch.eq true true to end_otherwise_0_7; + position end_then_0_6; + position end_otherwise_0_7; + add r148.protocol_fees0 r187.pf into r191; + ternary r1.hop2.zero_for_one r191 r148.protocol_fees0 into r192; + add r148.protocol_fees1 r187.pf into r193; + ternary r1.hop2.zero_for_one r148.protocol_fees1 r193 into r194; + branch.eq r130 false to end_then_0_8; + ternary r1.hop2.zero_for_one r187.fg r148.fee_growth_global0_x_64 into r195; + ternary r1.hop2.zero_for_one r148.fee_growth_global1_x_64 r187.fg into r196; + ternary r1.hop2.zero_for_one r187.resid r148.fee_residual0_x_64 into r197; + ternary r1.hop2.zero_for_one r148.fee_residual1_x_64 r187.resid into r198; + cast r187.tk r148.tick_spacing r187.sp r148.fee_protocol r187.liq r195 r196 r197 r198 r148.max_liquidity_per_tick r192 r194 r187.nb r187.na into r199 as Slot; + set r199 into slots[r1.hop2.pool]; + branch.eq true true to end_otherwise_0_9; + position end_then_0_8; + position end_otherwise_0_9; + ternary r1.hop1.zero_for_one r72.scale0 r72.scale1 into r200; + ternary r1.hop2.zero_for_one r132.scale0 r132.scale1 into r201; + ternary r1.hop2.zero_for_one r132.scale1 r132.scale0 into r202; + ternary r1.hop1.zero_for_one r72.scale1 r72.scale0 into r203; + ternary r130 r202 r203 into r204; + ternary r130 r187.out r117.out into r205; + mul r205 r204 into r206; + gte r206 r1.amount_out_min into r207; + assert.eq r207 true; + contains swap_outputs[r2] into r208; + not r208 into r209; + assert.eq r209 true; + ternary r130 r140 r80 into r210; + mul r59.rem r29 into r211; + mul r117.rem r200 into r212; + mul r187.rem r201 into r213; + ternary r130 r213 0u128 into r214; + cast r1.recipient r1.caller r18 r1.token_out r206 r211 r80 r212 r210 r214 into r215 as SwapOutput; + set r215 into swap_outputs[r2]; + contains used_blinded_addresses[r1.caller] into r216; + not r216 into r217; + assert.eq r217 true; + set true into used_blinded_addresses[r1.caller]; + +function claim_multi_hop_output: + input r0 as field.private; + input r1 as address.public; + input r2 as field.public; + input r3 as field.public; + input r4 as field.public; + input r5 as u128.public; + input r6 as u128.public; + input r7 as field.public; + input r8 as u128.public; + input r9 as field.public; + input r10 as u128.public; + call verify_blinded_address shield_swap_v3.aleo self.signer r0 r1; + call.dynamic r4 'aleo' 'transfer_public_to_private' with self.signer r5 (as address.private u128.public) into r11 r12 (as dynamic.record dynamic.future); + call.dynamic r3 'aleo' 'transfer_public_to_private' with self.signer r6 (as address.private u128.public) into r13 r14 (as dynamic.record dynamic.future); + call.dynamic r7 'aleo' 'transfer_public_to_private' with self.signer r8 (as address.private u128.public) into r15 r16 (as dynamic.record dynamic.future); + call.dynamic r9 'aleo' 'transfer_public_to_private' with self.signer r10 (as address.private u128.public) into r17 r18 (as dynamic.record dynamic.future); + async claim_multi_hop_output r12 r14 r16 r18 r2 r3 r4 r5 r6 r7 r8 r9 r10 r1 into r19; + output r11 as dynamic.record; + output r13 as dynamic.record; + output r15 as dynamic.record; + output r17 as dynamic.record; + output r19 as shield_swap_v3.aleo/claim_multi_hop_output.future; + +finalize claim_multi_hop_output: + input r0 as dynamic.future; + input r1 as dynamic.future; + input r2 as dynamic.future; + input r3 as dynamic.future; + input r4 as field.public; + input r5 as field.public; + input r6 as field.public; + input r7 as u128.public; + input r8 as u128.public; + input r9 as field.public; + input r10 as u128.public; + input r11 as field.public; + input r12 as u128.public; + input r13 as address.public; + await r0; + await r1; + await r2; + await r3; + get swap_outputs[r4] into r14; + is.eq r14.caller r13 into r15; + assert.eq r15 true; + is.eq r14.recipient r13 into r16; + assert.eq r16 true; + is.eq r14.token_in r5 into r17; + assert.eq r17 true; + is.eq r14.token_out r6 into r18; + assert.eq r18 true; + is.eq r14.amount_out r7 into r19; + assert.eq r19 true; + is.eq r14.amount_remaining r8 into r20; + assert.eq r20 true; + is.eq r14.token_in_1 r9 into r21; + assert.eq r21 true; + is.eq r14.amount_remaining_1 r10 into r22; + assert.eq r22 true; + is.eq r14.token_in_2 r11 into r23; + assert.eq r23 true; + is.eq r14.amount_remaining_2 r12 into r24; + assert.eq r24 true; + remove swap_outputs[r4]; + +constructor: + is.eq edition 0u16 into r0; + branch.eq r0 false to end_then_0_0; + contains admin[true] into r1; + not r1 into r2; + assert.eq r2 true; + set aleo1z3zwzgpgakk89xpknync5rtklkjkyv33g7cvaqe0gku64zs3lv9qyux0qc into admin[true]; + set false into pool_creation_is_open[true]; + set false into global_paused[true]; + branch.eq true true to end_otherwise_0_1; + position end_then_0_0; + position end_otherwise_0_1; + gt edition 0u16 into r3; + branch.eq r3 false to end_then_0_2; + cast checksum edition into r4 as ChecksumEdition; + hash.bhp256 r4 into r5 as field; + cast shield_swap_v3.aleo r5 into r6 as test_shield_swap_multisig_core.aleo/WalletSigningOpId; + hash.bhp256 r6 into r7 as field; + contains test_shield_swap_multisig_core.aleo/completed_signing_ops[r7] into r8; + assert.eq r8 true; + branch.eq true true to end_otherwise_0_3; + position end_then_0_2; + position end_otherwise_0_3; diff --git a/shield-swap-sdk/pyproject.toml b/shield-swap-sdk/pyproject.toml new file mode 100644 index 00000000..4eb4412f --- /dev/null +++ b/shield-swap-sdk/pyproject.toml @@ -0,0 +1,19 @@ +[project] +name = "shield-swap-sdk" +version = "0.2.0" +description = "Python SDK for the shield swap AMM Dex on Aleo" +readme = "README.md" +requires-python = ">=3.10" +dependencies = ["aleo-sdk>=0.2", "requests>=2"] + +[project.optional-dependencies] +async = ["httpx>=0.27"] +mcp = ["mcp>=1.0"] +dev = ["datamodel-code-generator>=0.25", "pytest>=8", "pytest-asyncio>=0.23"] + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.hatch.build.targets.wheel] +packages = ["python/aleo_shield_swap"] diff --git a/shield-swap-sdk/pyrightconfig.json b/shield-swap-sdk/pyrightconfig.json new file mode 100644 index 00000000..9294a93c --- /dev/null +++ b/shield-swap-sdk/pyrightconfig.json @@ -0,0 +1,8 @@ +{ + "include": ["python/aleo_shield_swap"], + "exclude": ["python/aleo_shield_swap/_generated.py", "python/aleo_shield_swap/_api_models.py"], + "extraPaths": ["../sdk/python"], + "venvPath": "../sdk", + "venv": ".env", + "reportMissingModuleSource": false +} diff --git a/shield-swap-sdk/pytest.ini b/shield-swap-sdk/pytest.ini new file mode 100644 index 00000000..d06a1824 --- /dev/null +++ b/shield-swap-sdk/pytest.ini @@ -0,0 +1,10 @@ +[pytest] +pythonpath = python +testpaths = tests +markers = + live: tests that hit the REAL testnet REST API / DEX API (run with -m live) + slow: proving/funded write tests that spend real testnet funds (run with -m "live and slow") + devnode: hermetic tests needing a local aleo-devnode binary (run with -m devnode) +addopts = -m "not live and not devnode" + +asyncio_mode = auto diff --git a/shield-swap-sdk/python/aleo_shield_swap/__init__.py b/shield-swap-sdk/python/aleo_shield_swap/__init__.py new file mode 100644 index 00000000..3013fee8 --- /dev/null +++ b/shield-swap-sdk/python/aleo_shield_swap/__init__.py @@ -0,0 +1,60 @@ +"""shield-swap-sdk — typed Python client for the shield_swap AMM on Aleo. + +:: + + from aleo import Aleo + from aleo_shield_swap import ShieldSwap + + aleo = Aleo(Aleo.HTTPProvider("https://api.provable.com")) + aleo.default_account = account + dex = ShieldSwap(aleo) + + pools = dex.api.get_pools() + handle = dex.swap(pool_key=pools[0].key, token_in_id=pools[0].token0, + amount_in=10**9).delegate() + out = dex.claim_swap_output(handle).delegate() +""" +from .client import ShieldSwap as ShieldSwap +from .async_client import AsyncShieldSwap as AsyncShieldSwap +from .api import ApiClient as ApiClient, AsyncApiClient as AsyncApiClient +from .types import ( + ClaimResult as ClaimResult, + MintResult as MintResult, + SlotView as SlotView, + SwapHandle as SwapHandle, + TxResult as TxResult, +) +from .derivations import ( + BlindedIdentity as BlindedIdentity, + derive_blinded_address as derive_blinded_address, + derive_blinding_factor as derive_blinding_factor, + derive_pool_key as derive_pool_key, + derive_tick_key as derive_tick_key, +) +from .errors import ( + DexApiError as DexApiError, + InsufficientRecordsError as InsufficientRecordsError, + InvalidFeeTierError as InvalidFeeTierError, + PoolNotFoundError as PoolNotFoundError, + PoolNotInitializedError as PoolNotInitializedError, + ShieldSwapError as ShieldSwapError, + SwapOutputNotFinalizedError as SwapOutputNotFinalizedError, +) +from .agent import ( + dispatch_tool as dispatch_tool, + shield_swap_tools as shield_swap_tools, +) + +__version__ = "0.2.0" + +__all__ = [ + "ShieldSwap", "AsyncShieldSwap", "ApiClient", "AsyncApiClient", + "SwapHandle", "ClaimResult", "MintResult", "TxResult", "SlotView", + "BlindedIdentity", "derive_blinding_factor", "derive_blinded_address", + "derive_pool_key", "derive_tick_key", + "ShieldSwapError", "SwapOutputNotFinalizedError", "PoolNotFoundError", + "PoolNotInitializedError", "InsufficientRecordsError", + "InvalidFeeTierError", "DexApiError", + "shield_swap_tools", "dispatch_tool", + "__version__", +] diff --git a/shield-swap-sdk/python/aleo_shield_swap/_api_models.py b/shield-swap-sdk/python/aleo_shield_swap/_api_models.py new file mode 100644 index 00000000..7ce95c33 --- /dev/null +++ b/shield-swap-sdk/python/aleo_shield_swap/_api_models.py @@ -0,0 +1,832 @@ +# Generated by datamodel-code-generator — DO NOT EDIT. + +from __future__ import annotations + +from dataclasses import dataclass +from enum import Enum + + +@dataclass +class AccessCodeRow: + code: str + created_at: str + redeemed_at: str | None = None + redeemed_by: str | None = None + + +@dataclass +class AccessGenerateRequest: + count: int + + +@dataclass +class AccessGenerateResponse: + codes: list[str] + + +@dataclass +class AccessGenerateResponseDoc: + data: AccessGenerateResponse + + +@dataclass +class AccessListResponse: + available: int + codes: list[AccessCodeRow] + redeemed: int + total: int + + +@dataclass +class AccessListResponseDoc: + data: AccessListResponse + + +@dataclass +class AccessRedeemRequest: + code: str + + +@dataclass +class AccessRedeemResponse: + code: str + status: str + token: str + + +@dataclass +class AccessRedeemResponseDoc: + data: AccessRedeemResponse + + +@dataclass +class AccessStatusResponse: + has_access: bool + + +@dataclass +class AccessStatusResponseDoc: + data: AccessStatusResponse + + +@dataclass +class AirdropRequest: + address: str + + +@dataclass +class AirdropResult: + amount: str + status: str + symbol: str + token_address: str + wrapper_program: str + error: str | None = None + tx_id: str | None = None + + +@dataclass +class AirdropStartResult: + job_id: str + status: str + + +@dataclass +class ApiTokenCreateRequest: + name: str + expires_in_days: int | None = None + + +@dataclass +class ApiTokenCreatedResponse: + created_at: str + id: str + name: str + token: str + token_prefix: str + expires_at: str | None = None + + +@dataclass +class ApiTokenCreatedResponseDoc: + data: ApiTokenCreatedResponse + + +@dataclass +class ApiTokenRevokeResponse: + id: str + revoked: bool + + +@dataclass +class ApiTokenRevokeResponseDoc: + data: ApiTokenRevokeResponse + + +@dataclass +class ApiTokenRow: + created_at: str + id: str + name: str + token_prefix: str + expires_at: str | None = None + last_used_at: str | None = None + revoked_at: str | None = None + + +@dataclass +class AuthTokenPayload: + token: str + + +@dataclass +class AuthTokenResponseDoc: + data: AuthTokenPayload + + +@dataclass +class ChallengePayload: + message: str + nonce: str + + +@dataclass +class ChallengeRequestDoc: + address: str + + +@dataclass +class ChallengeResponseDoc: + data: ChallengePayload + + +@dataclass +class CreateTokenRequestDoc: + address: str + decimals: int + name: str + symbol: str + wrapper_program: str | None = None + + +@dataclass +class DeployTokenRequest: + decimals: int + name: str + recipient: str + symbol: str + supply: str | None = None + + +@dataclass +class DeployTokenResult: + program_id: str + recipient: str + status: str + + +@dataclass +class ErrorResponseDoc: + error: str + ref: str | None = None + + +@dataclass +class FeeTierDoc: + created_at: str + fee_tier: int + id: str + transaction: str + + +@dataclass +class FeeTierListResponseDoc: + data: list[FeeTierDoc] + + +@dataclass +class GlobalConfigStatus: + global_paused: bool + pool_creation_is_open: bool + + +class GranularityDoc(Enum): + field_1m = '1m' + field_5m = '5m' + field_15m = '15m' + field_30m = '30m' + field_1h = '1h' + field_6h = '6h' + field_12h = '12h' + field_1d = '1d' + + +@dataclass +class InitializedTicksResponseDoc: + data: list[int] + + +@dataclass +class MintTokenRequest: + amount: str + recipient: str + wrapper_program: str + + +@dataclass +class MintTokenResult: + status: str + tx_id: str | None = None + + +@dataclass +class OhlcvDoc: + c: str + granularity: GranularityDoc + h: str + l: str + o: str + pool: str + timestamp: int + v: str + + +@dataclass +class OhlcvResponseDoc: + data: list[OhlcvDoc] + + +@dataclass +class PaginationMeta: + limit: int + offset: int + total: int + + +@dataclass +class PairComplianceStatus: + paused: bool + token0: str + token1: str + + +@dataclass +class PendingSwapOutputDoc: + amount_out: str + amount_remaining: str + recipient: str + token_in: str + token_out: str + amount_remaining_1: str | None = None + amount_remaining_2: str | None = None + token_in_1: str | None = None + token_in_2: str | None = None + + +@dataclass +class PoolStateDoc: + created_at: str + creator: str + enabled: bool + fee: str + id: str + init_tx: str + key: str + scale0: str + scale1: str + token0: str + token1: str + + +@dataclass +class PoolStats24hDoc: + high_24h: str + liquidity: str + low_24h: str + open_24h: str + price: str + price_reversed: str + volume_24h: str + change_24h_pct: str | None = None + + +@dataclass +class PoolStats24hResponseDoc: + data: PoolStats24hDoc + + +@dataclass +class PoolStatsDoc: + active_tick: int + fee_growth_global0_x_64: str + fee_growth_global1_x_64: str + fee_protocol: int + id: str + liquidity: str + max_liquidity_per_tick: str + next_init_above: int + next_init_below: int + pool: str + price: str + price_reversed: str + protocol_fees0: str + protocol_fees1: str + tick_spacing: int + + +class PoolTradeFilterDoc(Enum): + mint = 'mint' + add_liquidity = 'add_liquidity' + remove_liquidity = 'remove_liquidity' + burn = 'burn' + collect = 'collect' + swap = 'swap' + + +class PoolTradeTypeDoc(Enum): + mint = 'mint' + add_liquidity = 'add_liquidity' + remove_liquidity = 'remove_liquidity' + burn = 'burn' + collect = 'collect' + swap = 'swap' + swap_multi_hop = 'swap_multi_hop' + + +@dataclass +class PositionDoc: + amount0: str + amount1: str + created_at: str + fee_growth_inside0_last_64: str + fee_growth_inside1_last_64: str + id: str + is_burned: bool + is_frozen: bool + is_private: bool + liquidity: str + pool: str + tick_lower: int + tick_upper: int + token_id: str + tokens_owed0: str + tokens_owed1: str + transaction: str + user: str + frozen_at: str | None = None + transaction_hash: str | None = None + + +@dataclass +class PositionListResponseDoc: + data: list[PositionDoc] + pagination: PaginationMeta + + +@dataclass +class PositionResponseDoc: + data: PositionDoc + + +@dataclass +class ReferralAdminCheckResponse: + is_admin: bool + + +@dataclass +class ReferralAdminResponseDoc: + data: ReferralAdminCheckResponse + + +@dataclass +class ReferralCodeRow: + code: str + created_at: str + issued_to: str | None = None + redeemed_at: str | None = None + redeemed_by: str | None = None + + +@dataclass +class ReferralGenerateRequest: + count: int + + +@dataclass +class ReferralGenerateResponse: + codes: list[str] + + +@dataclass +class ReferralGenerateResponseDoc: + data: ReferralGenerateResponse + + +@dataclass +class ReferralListResponse: + available: int + codes: list[ReferralCodeRow] + redeemed: int + total: int + + +@dataclass +class ReferralListResponseDoc: + data: ReferralListResponse + + +@dataclass +class ReferralMyCodeRow: + code: str + redeemed_at: str | None = None + redeemed_by: str | None = None + + +@dataclass +class ReferralMyCodesResponse: + codes: list[ReferralMyCodeRow] + quota: int + + +@dataclass +class ReferralMyCodesResponseDoc: + data: ReferralMyCodesResponse + + +@dataclass +class ReferralRedeemRequest: + code: str + + +@dataclass +class ReferralRedeemResponse: + code: str + status: str + token: str + + +@dataclass +class ReferralRedeemResponseDoc: + data: ReferralRedeemResponse + + +@dataclass +class ReferralSettingsResponse: + codes_per_user: int + codes_per_user_limit: int + max_users: int | None = None + + +@dataclass +class ReferralSettingsResponseDoc: + data: ReferralSettingsResponse + + +@dataclass +class ReferralStatusResponse: + has_access: bool + code: str | None = None + + +@dataclass +class ReferralStatusResponseDoc: + data: ReferralStatusResponse + + +@dataclass +class ReferralUpdateSettingsRequest: + codes_per_user: int + max_users: int | None = None + + +@dataclass +class RouteHopDoc: + fee: str + initialized_ticks: list[int] + pool_key: str + token_in: str + token_out: str + zero_for_one: bool + active_tick: int | None = None + liquidity: str | None = None + price: str | None = None + sqrt_price_raw: str | None = None + tick_spacing: int | None = None + + +@dataclass +class RouteResultDoc: + hops: list[RouteHopDoc] + token_in: str + token_out: str + estimated_amount_out: str | None = None + + +@dataclass +class SchemaField: + description: str + name: str + type: str + visibility: str + fields: list[SchemaField] | None = None + + +@dataclass +class SwapHopDoc: + pool: str + zero_for_one: bool + + +@dataclass +class TickLiquidityDoc: + liquidity_net: str + tick: int + + +@dataclass +class TickSpacingDoc: + id: str + tick_spacing: int + + +@dataclass +class TickSpacingListResponseDoc: + data: list[TickSpacingDoc] + + +@dataclass +class TickStatusDoc: + exists: bool + tick: int + tick_mapping_key: str + raw_value: str | None = None + + +@dataclass +class TokenBalanceDoc: + balance: str + decimals: int + name: str + symbol: str + token_address: str + token_id: str + + +@dataclass +class TokenComplianceStatus: + allowed: bool + paused: bool + token_id: str + + +@dataclass +class TokenDoc: + address: str + decimals: int + id: str + name: str + symbol: str + image: str | None = None + wrapper_program: str | None = None + + +@dataclass +class TokenListResponseDoc: + data: list[TokenDoc] + + +@dataclass +class TokenResponseDoc: + data: TokenDoc + + +@dataclass +class VerifyRequestDoc: + address: str + signature: str + + +@dataclass +class AirdropJob: + results: list[AirdropResult] + status: str + total: int + + +@dataclass +class AirdropJobResponseDoc: + data: AirdropJob + + +@dataclass +class AirdropStartResponseDoc: + data: AirdropStartResult + + +@dataclass +class ApiTokenListResponse: + tokens: list[ApiTokenRow] + + +@dataclass +class ApiTokenListResponseDoc: + data: ApiTokenListResponse + + +@dataclass +class BalanceListResponseDoc: + data: list[TokenBalanceDoc] + + +@dataclass +class DeployTokenResponseDoc: + data: DeployTokenResult + + +@dataclass +class FunctionSchema: + description: str + function: str + id: str + inputs: list[SchemaField] + program: str + visibility: str + follow_up: list[str] | None = None + + +@dataclass +class GlobalConfigResponseDoc: + data: GlobalConfigStatus + + +@dataclass +class LiquidityDistributionResponseDoc: + data: list[TickLiquidityDoc] + + +@dataclass +class MintTokenResponseDoc: + data: MintTokenResult + + +@dataclass +class PairComplianceResponseDoc: + data: PairComplianceStatus + + +@dataclass +class PendingSwapDoc: + is_multi_hop: bool + is_private: bool + output: PendingSwapOutputDoc + swap_id: str + swap_tx_hash: str + token_in_info: TokenDoc | None = None + token_out_info: TokenDoc | None = None + + +@dataclass +class PoolDebugInfoDoc: + pool_key: str + tick_statuses: list[TickStatusDoc] + active_tick: int | None = None + liquidity: str | None = None + slot_raw: str | None = None + sqrt_price: str | None = None + tick_spacing: str | None = None + + +@dataclass +class PoolDebugResponseDoc: + data: PoolDebugInfoDoc + + +@dataclass +class PoolResponseDoc(PoolStateDoc): + token0_info: TokenDoc | None = None + token1_info: TokenDoc | None = None + + +@dataclass +class PoolStats24hBatchResponseDoc: + data: dict[str, PoolStats24hDoc] + + +@dataclass +class PoolTradeDoc: + amount0: str + amount1: str + executedAt: str + id: str + pool: str + tradeType: PoolTradeTypeDoc + + +@dataclass +class PoolTradesResponseDoc: + data: list[PoolTradeDoc] + pagination: PaginationMeta + + +@dataclass +class PoolWithStatsDoc(PoolStateDoc): + stats: PoolStatsDoc | None = None + token0_info: TokenDoc | None = None + token1_info: TokenDoc | None = None + + +@dataclass +class PoolWithStatsResponseDoc: + data: PoolWithStatsDoc + + +@dataclass +class PositionWithOwedDoc: + is_private: bool + pool: str + scale0: str + scale1: str + tick_lower: int + tick_upper: int + token_id: str + tokens_owed0: str + tokens_owed1: str + token0_info: TokenDoc | None = None + token1_info: TokenDoc | None = None + transaction_hash: str | None = None + + +@dataclass +class RouteResponseDoc: + data: RouteResultDoc + + +@dataclass +class SwapDoc: + amount_remaining: str + amount_remaining_1: str + amount_remaining_2: str + executed_at: str + hops: list[SwapHopDoc] + id: str + input_amount: str + input_token: str + is_private: bool + nonce: str + output_amount: str + output_token: str + pool: str + recipient: str + swap_id: str + transaction: str + user: str + claim_tx: str | None = None + claimed_at: str | None = None + input_token_info: TokenDoc | None = None + output_token_info: TokenDoc | None = None + token_in_1: str | None = None + token_in_2: str | None = None + trade: str | None = None + + +@dataclass +class SwapListResponseDoc: + data: list[SwapDoc] + pagination: PaginationMeta + + +@dataclass +class SwapResponseDoc: + data: SwapDoc + + +@dataclass +class TokenComplianceResponseDoc: + data: TokenComplianceStatus + + +@dataclass +class TradingSchemaListResponse: + data: list[FunctionSchema] + + +@dataclass +class TradingSchemaResponse: + data: FunctionSchema + + +@dataclass +class UnclaimedPayloadDoc: + pending_swaps: list[PendingSwapDoc] + positions_with_owed: list[PositionWithOwedDoc] + + +@dataclass +class UnclaimedResponseDoc: + data: UnclaimedPayloadDoc + + +@dataclass +class PoolListResponseDoc: + data: list[PoolResponseDoc] + pagination: PaginationMeta diff --git a/shield-swap-sdk/python/aleo_shield_swap/_calls.py b/shield-swap-sdk/python/aleo_shield_swap/_calls.py new file mode 100644 index 00000000..71b81aea --- /dev/null +++ b/shield-swap-sdk/python/aleo_shield_swap/_calls.py @@ -0,0 +1,98 @@ +"""DexCall — a facade BoundCall plus a typed result builder. + +Preserves the facade's verb ladder on every DEX write: the consumer picks +the proving path (``simulate`` / ``transact`` / ``delegate``) and gets a +typed result back instead of a bare transaction id. + +Output harvesting is scoped to the ROOT transition — the one whose program +and function match the call. Aleo executions order transitions child-first +(token-program transfers precede the shield_swap root, and a fee transition +may follow), so "first output of the transaction" would read a child's +output. +""" +from __future__ import annotations + +from typing import Any, Callable, Generic, TypeVar + +R = TypeVar("R") + + +def extract_tx_id(payload: Any) -> str: + """Transaction id from a DPS result payload (dict variants or bare id).""" + if isinstance(payload, str) and payload.strip(): + return payload.strip() + if isinstance(payload, dict): + for key in ("transaction_id", "transactionId", "id", "txid", "tx_id"): + if payload.get(key): + return str(payload[key]) + raise ValueError(f"Cannot find a transaction id in DPS payload: {payload!r}") + + +def output_values(outputs: Any) -> list[str]: + """Normalize transition outputs (dicts or raw objects) to value strings.""" + vals: list[str] = [] + for o in outputs: + if isinstance(o, dict): + v = o.get("value") + vals.append(v if isinstance(v, str) else str(v)) + else: + vals.append(str(o)) + return vals + + +def root_outputs(decoded_transitions: list[dict[str, Any]], + program: str, function: str) -> list[str]: + """Output values of the LAST transition matching *program*/*function*.""" + for entry in reversed(decoded_transitions): + if (str(entry.get("program")) == program + and str(entry.get("function")) == function): + return output_values(entry.get("outputs", [])) + return [] + + +class DexCall(Generic[R]): + """A prepared DEX write. ``build_result(transaction_id, root_outputs) + -> R`` turns the submitted transaction into the verb's typed result.""" + + def __init__(self, aleo: Any, bound: Any, + build_result: Callable[[str, list[str]], R]) -> None: + self._aleo = aleo + self._bound = bound + self._build = build_result + + def __repr__(self) -> str: + return f"DexCall({self._bound!r})" + + def simulate(self, account: Any = None) -> Any: + """Local authorization — no proof, no send; inspect before spending.""" + return self._bound.simulate(account) + + def transact(self, account: Any = None, **fee_kwargs: Any) -> R: + """Prove locally, broadcast, and build the typed result. + + Root-transition outputs are harvested from the built transaction + before broadcast, so the result is complete without waiting for + confirmation. + """ + tx = self._bound.build_transaction(account, **fee_kwargs) + outputs = root_outputs(tx.decoded(), self._bound.program_id, + self._bound.function_name) + # Same submit path the facade's BoundCall.transact uses. + self._aleo.network.submit_transaction(tx.raw) + return self._build(tx.id, outputs) + + def delegate(self, account: Any = None, **fee_kwargs: Any) -> R: + """Delegate proving to the DPS (fee master pays by default), wait for + the transaction, and build the typed result from its root transition.""" + payload = self._bound.delegate(account, **fee_kwargs) + tx_id = extract_tx_id(payload) + self._aleo.network.wait_for_transaction(tx_id) + tx = self._aleo.network.get_transaction_object(tx_id) + decoded = [ + {"program": str(t.program_id), "function": str(t.function_name), + "outputs": list(t.outputs())} + for t in tx.transitions() + ] + outputs = root_outputs(decoded, self._bound.program_id, + self._bound.function_name) + return self._build(tx_id, outputs) diff --git a/shield-swap-sdk/python/aleo_shield_swap/_core.py b/shield-swap-sdk/python/aleo_shield_swap/_core.py new file mode 100644 index 00000000..b8f7effc --- /dev/null +++ b/shield-swap-sdk/python/aleo_shield_swap/_core.py @@ -0,0 +1,311 @@ +"""Shared pure logic for the sync and async clients. + +Param resolution, deadlines, nonces, dynamic-dispatch import resolution, and +token-record selection — everything both ``client.py`` and +``async_client.py`` need but that does no client-specific I/O itself. +``resolve_swap_params`` is a line-for-line port of the TS SDK's +``utils/params.ts``. +""" +from __future__ import annotations + +import re +import secrets +from dataclasses import dataclass +from typing import Any, Optional + +from aleo.codegen.runtime import parse_plaintext + +from .errors import InsufficientRecordsError +from .tick_math import MAX_SQRT_PRICE, MIN_SQRT_PRICE, Q64 + + +@dataclass(frozen=True) +class ResolvedSwap: + """A friendly swap intent resolved into the contract's raw arguments.""" + + zero_for_one: bool + token_out_id: str + amount_out_min: int + sqrt_price_limit: int + + +def resolve_swap_params( + *, + pool: Any, + slot: Any, + token_in_id: str, + amount_in: int, + slippage_bps: int, + expected_out: Optional[int] = None, + sqrt_price_limit: Optional[int] = None, +) -> ResolvedSwap: + """Resolve a swap intent against live pool state. + + Determines direction from the pool's token ordering, validates the + amount against the contract's no-dust rule, and computes + ``amount_out_min`` from the slippage tolerance. Without *expected_out* + a spot estimate from ``slot.sqrt_price`` is used — it ignores price + impact and fees, so pass a real quote for anything beyond a tiny trade. + Pure and local. + """ + if not 0 <= slippage_bps <= 10_000: + raise ValueError(f"slippage_bps must be within [0, 10000], got {slippage_bps}") + + token0, token1 = str(pool.token0), str(pool.token1) + scale0, scale1 = int(pool.scale0), int(pool.scale1) + + zero_for_one = token_in_id == token0 + if not zero_for_one and token_in_id != token1: + raise ValueError(f"Token {token_in_id} is not in this pool ({token0} / {token1})") + token_out_id = token1 if zero_for_one else token0 + + # The contract normalizes amounts by the token's scale and asserts + # raw % scale == 0 — reject dust here instead of paying for a revert. + scale_in = scale0 if zero_for_one else scale1 + if amount_in % scale_in != 0: + raise ValueError( + f"amount_in {amount_in} is not a multiple of the token's scale " + f"{scale_in} — the contract rejects amounts with non-zero dust digits" + ) + + expected = expected_out + if expected is None: + # Spot estimate in normalized units: price = (sqrtP/Q64)^2 token1/token0. + scale_out = scale1 if zero_for_one else scale0 + norm_in = amount_in // scale_in + sq = int(slot.sqrt_price) + if zero_for_one: + norm_out = (norm_in * sq * sq) // (Q64 * Q64) + else: + norm_out = (norm_in * Q64 * Q64) // (sq * sq) + expected = norm_out * scale_out + + amount_out_min = (expected * (10_000 - slippage_bps)) // 10_000 + + # Default price bound: the directional extreme — amount_out_min is the + # real protection; a tight sqrt limit turns into partial fills instead. + default_limit = MIN_SQRT_PRICE if zero_for_one else MAX_SQRT_PRICE + limit = sqrt_price_limit if sqrt_price_limit is not None else default_limit + if not MIN_SQRT_PRICE <= limit <= MAX_SQRT_PRICE: + raise ValueError( + f"sqrt_price_limit {limit} outside the contract's accepted range " + f"[{MIN_SQRT_PRICE}, {MAX_SQRT_PRICE}]" + ) + + return ResolvedSwap(zero_for_one, token_out_id, amount_out_min, limit) + + +def get_deadline(aleo: Any, offset_blocks: int = 100) -> int: + """Absolute block-height deadline: current height + *offset_blocks*. + + The contract's ``deadline`` is a height (u32), not a timestamp; the + finalize asserts the current height is below it. + """ + return int(aleo.network_client.get_latest_height()) + offset_blocks + + +def generate_swap_nonce() -> int: + """Uniform random u64 — uniquifies the swap id in ``swap_outputs``.""" + return secrets.randbits(64) + + +def generate_field_nonce() -> str: + """Random field literal for ``mint`` (hashed into the position id). + 248 bits keeps the value below the field modulus.""" + return f"{secrets.randbits(248)}field" + + +# ── Shared pure helpers (sync + async clients) ─────────────────────────────── + +def normalize_mapping_value(raw: Any) -> Optional[str]: + """A mapping read normalized to plaintext, or ``None`` when absent. + + Node deployments variously return ``None``, ``"null"``, the empty string, + or a JSON-quoted value — one place decides what "absent" means. + """ + if raw in (None, "", "null"): + return None + text = str(raw).strip() + if text.startswith('"') and text.endswith('"'): + text = text[1:-1] + return None if text in ("", "null") else text + + +def pick_covering_record(records: Any, *, min_amount: int, + token_id: Optional[str]) -> Optional[str]: + """Smallest unspent token-record plaintext covering *min_amount*, or None. + + *token_id* filters registry-style records; wrapper-program records carry + no ``token_id`` and match any. + """ + candidates: list[tuple[int, str]] = [] + for rec in records: + plaintext = (rec.get("record_plaintext") if isinstance(rec, dict) + else getattr(rec, "record_plaintext", None)) + if not plaintext: + continue + info = parse_token_record_info(plaintext) + if info is None or info["amount"] < min_amount: + continue + if token_id is not None and "token_id" in info and info["token_id"] != token_id: + continue + candidates.append((info["amount"], plaintext)) + return min(candidates)[1] if candidates else None + + +def find_position_plaintext(records: Any, pool_key: str) -> Optional[str]: + """First unspent PositionNFT plaintext whose ``pool`` matches, or None.""" + for rec in records: + plaintext = (rec.get("record_plaintext") if isinstance(rec, dict) + else getattr(rec, "record_plaintext", None)) + if not plaintext: + continue + try: + decoded = parse_plaintext(plaintext) + except (ValueError, TypeError): + continue + if isinstance(decoded, dict) and decoded.get("pool") == pool_key: + return plaintext + return None + + +# ── Dynamic-dispatch imports ───────────────────────────────────────────────── + +_IMPORTS_CACHE: dict[tuple[str, str], str] = {} + + +def resolve_imports( + aleo: Any, + program_ids: list[str], + overrides: Optional[dict[str, str]] = None, +) -> dict[str, str]: + """Program sources for dynamic-dispatch dependencies. + + ``shield_swap`` calls token programs through a dynamic interface, so the + prover cannot discover them statically — every record-spending write + needs the involved token programs' sources. Sources are fetched via the + bound client once and memoized per (network, program); *overrides* win + without fetching. + """ + out: dict[str, str] = {} + # Key by the provider (not just the network name): a devnode and testnet + # both report "testnet" but serve different program deployments. + scope = repr(getattr(aleo, "provider", None) or getattr(aleo, "network_name", "")) + for pid in dict.fromkeys(program_ids): # de-dup, keep order + if overrides and pid in overrides: + out[pid] = overrides[pid] + continue + key = (scope, pid) + if key not in _IMPORTS_CACHE: + _IMPORTS_CACHE[key] = str(aleo.programs.get(pid).source) + out[pid] = _IMPORTS_CACHE[key] + return out + + +_IMPORT_LINE = re.compile(r"^import\s+(\S+?);\s*$", re.MULTILINE) + + +def program_imports(source: str) -> list[str]: + """Program ids named by ``import X.aleo;`` lines in *source*.""" + return _IMPORT_LINE.findall(source) + + +def register_program_sources(aleo: Any, sources: dict[str, str]) -> None: + """Add *sources* to the bound client's snarkVM process, dependencies + first (by declared ``import`` lines, within the provided closure). + + ``Process.load()`` seeds only ``credits.aleo``; every other program a + write touches — the DEX program itself and the dynamically-dispatched + token wrapper programs — must be added before ``authorize`` can resolve + the call. Idempotent: already-registered programs are skipped. + """ + process = aleo.process + if aleo.network_name == "testnet": + from aleo import testnet as net + else: + from aleo import mainnet as net + + added: set[str] = set() + + def add(pid: str) -> None: + if pid == "credits.aleo" or pid in added or pid not in sources: + return + added.add(pid) + if process.contains_program(net.ProgramID.from_string(pid)): + return + for dep in program_imports(sources[pid]): + add(dep) # dependencies before dependents + process.add_program(net.Program.from_source(sources[pid])) + + for pid in sources: + add(pid) + + +def ensure_programs(aleo: Any, program_ids: list[str], + overrides: Optional[dict[str, str]] = None) -> None: + """Fetch the import closure of *program_ids* (sync) and register it. + + Sources come from *overrides* first, else via ``aleo.programs.get`` + (memoized by :func:`resolve_imports`). + """ + sources: dict[str, str] = {} + stack = [pid for pid in dict.fromkeys(program_ids) if pid != "credits.aleo"] + while stack: + pid = stack.pop() + if pid in sources or pid == "credits.aleo": + continue + sources[pid] = resolve_imports(aleo, [pid], overrides)[pid] + stack.extend(program_imports(sources[pid])) + register_program_sources(aleo, sources) + + +# ── Token record selection ─────────────────────────────────────────────────── + +def parse_token_record_info(plaintext: str) -> Optional[dict[str, Any]]: + """Decode a token record's ``amount`` (and ``token_id`` when present). + + Handles both registry-token records (``owner``, ``amount``, ``token_id``, + …) and ARC-20 wrapper-program records (``owner``, ``amount`` only). + Returns ``None`` when the plaintext has no ``amount`` — not a token record. + """ + try: + decoded = parse_plaintext(plaintext) + except (ValueError, TypeError): + return None + if not isinstance(decoded, dict) or not isinstance(decoded.get("amount"), int): + return None + info: dict[str, Any] = {"amount": decoded["amount"]} + if isinstance(decoded.get("token_id"), str): + info["token_id"] = decoded["token_id"] + return info + + +def select_token_record( + aleo: Any, + *, + program: str, + min_amount: int, + token_id: Optional[str] = None, + account: Any = None, +) -> str: + """One unspent record plaintext from *program* covering *min_amount*. + + Scans via ``aleo.record_provider.find`` and picks the smallest covering + record (leaves larger records intact for larger trades). *token_id* + filters registry-style records; wrapper-program records carry no + ``token_id`` and match any. + """ + provider = aleo.record_provider + if provider is None: + raise InsufficientRecordsError( + "No record provider configured (aleo.record_provider is None) — " + "pass token_record= explicitly or configure a scanner." + ) + records = provider.find(account, program=program, unspent=True) + chosen = pick_covering_record(records, min_amount=min_amount, token_id=token_id) + if chosen is None: + raise InsufficientRecordsError( + f"No unspent {program} record covers {min_amount} " + f"(token_id={token_id or 'any'}) — privatize funds or pass token_record=." + ) + return chosen diff --git a/shield-swap-sdk/python/aleo_shield_swap/_generated.py b/shield-swap-sdk/python/aleo_shield_swap/_generated.py new file mode 100644 index 00000000..a2f07f4c --- /dev/null +++ b/shield-swap-sdk/python/aleo_shield_swap/_generated.py @@ -0,0 +1,508 @@ +# Generated by aleo.codegen — DO NOT EDIT. +from dataclasses import dataclass +from typing import Any, Callable, Optional +from aleo.codegen.runtime import (parse_plaintext, fmt_int, fmt_bool, fmt_fieldlike, fmt_address) + +PROGRAM_ID = "shield_swap_v3.aleo" + +@dataclass(frozen=True) +class SwapRequest: + pool: str + zero_for_one: bool + amount_in: int + amount_out_min: int + sqrt_price_limit: int + recipient: str + nonce: int + deadline: int + + def to_plaintext(self) -> str: + parts = [ + "pool: " + fmt_fieldlike(self.pool, 'field'), + "zero_for_one: " + fmt_bool(self.zero_for_one), + "amount_in: " + fmt_int(self.amount_in, 'u128'), + "amount_out_min: " + fmt_int(self.amount_out_min, 'u128'), + "sqrt_price_limit: " + fmt_int(self.sqrt_price_limit, 'u128'), + "recipient: " + fmt_address(self.recipient), + "nonce: " + fmt_int(self.nonce, 'u64'), + "deadline: " + fmt_int(self.deadline, 'u32'), + ] + return "{ " + ", ".join(parts) + " }" + + @classmethod + def from_decoded(cls, d: dict) -> "SwapRequest": + return cls(pool=d['pool'], zero_for_one=d['zero_for_one'], amount_in=d['amount_in'], amount_out_min=d['amount_out_min'], sqrt_price_limit=d['sqrt_price_limit'], recipient=d['recipient'], nonce=d['nonce'], deadline=d['deadline']) + + @classmethod + def from_plaintext(cls, text: str) -> "SwapRequest": + return cls.from_decoded(parse_plaintext(text)) + + +@dataclass(frozen=True) +class SwapHop: + pool: str + zero_for_one: bool + sqrt_price_limit: int + + def to_plaintext(self) -> str: + parts = [ + "pool: " + fmt_fieldlike(self.pool, 'field'), + "zero_for_one: " + fmt_bool(self.zero_for_one), + "sqrt_price_limit: " + fmt_int(self.sqrt_price_limit, 'u128'), + ] + return "{ " + ", ".join(parts) + " }" + + @classmethod + def from_decoded(cls, d: dict) -> "SwapHop": + return cls(pool=d['pool'], zero_for_one=d['zero_for_one'], sqrt_price_limit=d['sqrt_price_limit']) + + @classmethod + def from_plaintext(cls, text: str) -> "SwapHop": + return cls.from_decoded(parse_plaintext(text)) + + +@dataclass(frozen=True) +class SwapMultiHopRequest: + token_in: str + token_out: str + amount_in: int + amount_out_min: int + recipient: str + hop0: SwapHop + hop1: SwapHop + hop2: SwapHop + hop_count: int + nonce: int + deadline: int + caller: str + + def to_plaintext(self) -> str: + parts = [ + "token_in: " + fmt_fieldlike(self.token_in, 'field'), + "token_out: " + fmt_fieldlike(self.token_out, 'field'), + "amount_in: " + fmt_int(self.amount_in, 'u128'), + "amount_out_min: " + fmt_int(self.amount_out_min, 'u128'), + "recipient: " + fmt_address(self.recipient), + "hop0: " + self.hop0.to_plaintext(), + "hop1: " + self.hop1.to_plaintext(), + "hop2: " + self.hop2.to_plaintext(), + "hop_count: " + fmt_int(self.hop_count, 'u8'), + "nonce: " + fmt_int(self.nonce, 'u64'), + "deadline: " + fmt_int(self.deadline, 'u32'), + "caller: " + fmt_address(self.caller), + ] + return "{ " + ", ".join(parts) + " }" + + @classmethod + def from_decoded(cls, d: dict) -> "SwapMultiHopRequest": + return cls(token_in=d['token_in'], token_out=d['token_out'], amount_in=d['amount_in'], amount_out_min=d['amount_out_min'], recipient=d['recipient'], hop0=SwapHop.from_decoded(d['hop0']), hop1=SwapHop.from_decoded(d['hop1']), hop2=SwapHop.from_decoded(d['hop2']), hop_count=d['hop_count'], nonce=d['nonce'], deadline=d['deadline'], caller=d['caller']) + + @classmethod + def from_plaintext(cls, text: str) -> "SwapMultiHopRequest": + return cls.from_decoded(parse_plaintext(text)) + + +@dataclass(frozen=True) +class MintPositionRequest: + pool: str + tick_lower: int + tick_upper: int + amount0_desired: int + amount1_desired: int + amount0_min: int + amount1_min: int + tick_lower_hint: int + tick_upper_hint: int + + def to_plaintext(self) -> str: + parts = [ + "pool: " + fmt_fieldlike(self.pool, 'field'), + "tick_lower: " + fmt_int(self.tick_lower, 'i32'), + "tick_upper: " + fmt_int(self.tick_upper, 'i32'), + "amount0_desired: " + fmt_int(self.amount0_desired, 'u128'), + "amount1_desired: " + fmt_int(self.amount1_desired, 'u128'), + "amount0_min: " + fmt_int(self.amount0_min, 'u128'), + "amount1_min: " + fmt_int(self.amount1_min, 'u128'), + "tick_lower_hint: " + fmt_int(self.tick_lower_hint, 'i32'), + "tick_upper_hint: " + fmt_int(self.tick_upper_hint, 'i32'), + ] + return "{ " + ", ".join(parts) + " }" + + @classmethod + def from_decoded(cls, d: dict) -> "MintPositionRequest": + return cls(pool=d['pool'], tick_lower=d['tick_lower'], tick_upper=d['tick_upper'], amount0_desired=d['amount0_desired'], amount1_desired=d['amount1_desired'], amount0_min=d['amount0_min'], amount1_min=d['amount1_min'], tick_lower_hint=d['tick_lower_hint'], tick_upper_hint=d['tick_upper_hint']) + + @classmethod + def from_plaintext(cls, text: str) -> "MintPositionRequest": + return cls.from_decoded(parse_plaintext(text)) + + +@dataclass(frozen=True) +class PoolState: + token0: str + token1: str + fee: int + enabled: bool + scale0: int + scale1: int + + def to_plaintext(self) -> str: + parts = [ + "token0: " + fmt_fieldlike(self.token0, 'field'), + "token1: " + fmt_fieldlike(self.token1, 'field'), + "fee: " + fmt_int(self.fee, 'u16'), + "enabled: " + fmt_bool(self.enabled), + "scale0: " + fmt_int(self.scale0, 'u128'), + "scale1: " + fmt_int(self.scale1, 'u128'), + ] + return "{ " + ", ".join(parts) + " }" + + @classmethod + def from_decoded(cls, d: dict) -> "PoolState": + return cls(token0=d['token0'], token1=d['token1'], fee=d['fee'], enabled=d['enabled'], scale0=d['scale0'], scale1=d['scale1']) + + @classmethod + def from_plaintext(cls, text: str) -> "PoolState": + return cls.from_decoded(parse_plaintext(text)) + + +@dataclass(frozen=True) +class Slot: + tick: int + tick_spacing: int + sqrt_price: int + fee_protocol: int + liquidity: int + fee_growth_global0_x_64: int + fee_growth_global1_x_64: int + fee_residual0_x_64: int + fee_residual1_x_64: int + max_liquidity_per_tick: int + protocol_fees0: int + protocol_fees1: int + next_init_below: int + next_init_above: int + + def to_plaintext(self) -> str: + parts = [ + "tick: " + fmt_int(self.tick, 'i32'), + "tick_spacing: " + fmt_int(self.tick_spacing, 'u32'), + "sqrt_price: " + fmt_int(self.sqrt_price, 'u128'), + "fee_protocol: " + fmt_int(self.fee_protocol, 'u8'), + "liquidity: " + fmt_int(self.liquidity, 'u128'), + "fee_growth_global0_x_64: " + fmt_int(self.fee_growth_global0_x_64, 'u128'), + "fee_growth_global1_x_64: " + fmt_int(self.fee_growth_global1_x_64, 'u128'), + "fee_residual0_x_64: " + fmt_int(self.fee_residual0_x_64, 'u128'), + "fee_residual1_x_64: " + fmt_int(self.fee_residual1_x_64, 'u128'), + "max_liquidity_per_tick: " + fmt_int(self.max_liquidity_per_tick, 'u128'), + "protocol_fees0: " + fmt_int(self.protocol_fees0, 'u128'), + "protocol_fees1: " + fmt_int(self.protocol_fees1, 'u128'), + "next_init_below: " + fmt_int(self.next_init_below, 'i32'), + "next_init_above: " + fmt_int(self.next_init_above, 'i32'), + ] + return "{ " + ", ".join(parts) + " }" + + @classmethod + def from_decoded(cls, d: dict) -> "Slot": + return cls(tick=d['tick'], tick_spacing=d['tick_spacing'], sqrt_price=d['sqrt_price'], fee_protocol=d['fee_protocol'], liquidity=d['liquidity'], fee_growth_global0_x_64=d['fee_growth_global0_x_64'], fee_growth_global1_x_64=d['fee_growth_global1_x_64'], fee_residual0_x_64=d['fee_residual0_x_64'], fee_residual1_x_64=d['fee_residual1_x_64'], max_liquidity_per_tick=d['max_liquidity_per_tick'], protocol_fees0=d['protocol_fees0'], protocol_fees1=d['protocol_fees1'], next_init_below=d['next_init_below'], next_init_above=d['next_init_above']) + + @classmethod + def from_plaintext(cls, text: str) -> "Slot": + return cls.from_decoded(parse_plaintext(text)) + + +@dataclass(frozen=True) +class Tick: + pool: str + liquidity_net: int + liquidity_gross: int + tick: int + fee_growth_outside0_64: int + fee_growth_outside1_64: int + prev: int + next: int + + def to_plaintext(self) -> str: + parts = [ + "pool: " + fmt_fieldlike(self.pool, 'field'), + "liquidity_net: " + fmt_int(self.liquidity_net, 'i128'), + "liquidity_gross: " + fmt_int(self.liquidity_gross, 'u128'), + "tick: " + fmt_int(self.tick, 'i32'), + "fee_growth_outside0_64: " + fmt_int(self.fee_growth_outside0_64, 'u128'), + "fee_growth_outside1_64: " + fmt_int(self.fee_growth_outside1_64, 'u128'), + "prev: " + fmt_int(self.prev, 'i32'), + "next: " + fmt_int(self.next, 'i32'), + ] + return "{ " + ", ".join(parts) + " }" + + @classmethod + def from_decoded(cls, d: dict) -> "Tick": + return cls(pool=d['pool'], liquidity_net=d['liquidity_net'], liquidity_gross=d['liquidity_gross'], tick=d['tick'], fee_growth_outside0_64=d['fee_growth_outside0_64'], fee_growth_outside1_64=d['fee_growth_outside1_64'], prev=d['prev'], next=d['next']) + + @classmethod + def from_plaintext(cls, text: str) -> "Tick": + return cls.from_decoded(parse_plaintext(text)) + + +@dataclass(frozen=True) +class Position: + token_id: str + pool: str + tick_lower: int + tick_upper: int + liquidity: int + fee_growth_inside0_last_64: int + fee_growth_inside1_last_64: int + tokens_owed0: int + tokens_owed1: int + + def to_plaintext(self) -> str: + parts = [ + "token_id: " + fmt_fieldlike(self.token_id, 'field'), + "pool: " + fmt_fieldlike(self.pool, 'field'), + "tick_lower: " + fmt_int(self.tick_lower, 'i32'), + "tick_upper: " + fmt_int(self.tick_upper, 'i32'), + "liquidity: " + fmt_int(self.liquidity, 'u128'), + "fee_growth_inside0_last_64: " + fmt_int(self.fee_growth_inside0_last_64, 'u128'), + "fee_growth_inside1_last_64: " + fmt_int(self.fee_growth_inside1_last_64, 'u128'), + "tokens_owed0: " + fmt_int(self.tokens_owed0, 'u128'), + "tokens_owed1: " + fmt_int(self.tokens_owed1, 'u128'), + ] + return "{ " + ", ".join(parts) + " }" + + @classmethod + def from_decoded(cls, d: dict) -> "Position": + return cls(token_id=d['token_id'], pool=d['pool'], tick_lower=d['tick_lower'], tick_upper=d['tick_upper'], liquidity=d['liquidity'], fee_growth_inside0_last_64=d['fee_growth_inside0_last_64'], fee_growth_inside1_last_64=d['fee_growth_inside1_last_64'], tokens_owed0=d['tokens_owed0'], tokens_owed1=d['tokens_owed1']) + + @classmethod + def from_plaintext(cls, text: str) -> "Position": + return cls.from_decoded(parse_plaintext(text)) + + +@dataclass(frozen=True) +class PairKey: + token0: str + token1: str + + def to_plaintext(self) -> str: + parts = [ + "token0: " + fmt_fieldlike(self.token0, 'field'), + "token1: " + fmt_fieldlike(self.token1, 'field'), + ] + return "{ " + ", ".join(parts) + " }" + + @classmethod + def from_decoded(cls, d: dict) -> "PairKey": + return cls(token0=d['token0'], token1=d['token1']) + + @classmethod + def from_plaintext(cls, text: str) -> "PairKey": + return cls.from_decoded(parse_plaintext(text)) + + +@dataclass(frozen=True) +class SwapIterCfg: + z: bool + lim: int + fee_pips: int + fee_protocol: int + slot_fg0: int + slot_fg1: int + + def to_plaintext(self) -> str: + parts = [ + "z: " + fmt_bool(self.z), + "lim: " + fmt_int(self.lim, 'u128'), + "fee_pips: " + fmt_int(self.fee_pips, 'u32'), + "fee_protocol: " + fmt_int(self.fee_protocol, 'u8'), + "slot_fg0: " + fmt_int(self.slot_fg0, 'u128'), + "slot_fg1: " + fmt_int(self.slot_fg1, 'u128'), + ] + return "{ " + ", ".join(parts) + " }" + + @classmethod + def from_decoded(cls, d: dict) -> "SwapIterCfg": + return cls(z=d['z'], lim=d['lim'], fee_pips=d['fee_pips'], fee_protocol=d['fee_protocol'], slot_fg0=d['slot_fg0'], slot_fg1=d['slot_fg1']) + + @classmethod + def from_plaintext(cls, text: str) -> "SwapIterCfg": + return cls.from_decoded(parse_plaintext(text)) + + +@dataclass(frozen=True) +class SwapIterState: + sp: int + rem: int + out: int + fg: int + liq: int + tk: int + crossed: bool + pf: int + nb: int + na: int + resid: int + + def to_plaintext(self) -> str: + parts = [ + "sp: " + fmt_int(self.sp, 'u128'), + "rem: " + fmt_int(self.rem, 'u128'), + "out: " + fmt_int(self.out, 'u128'), + "fg: " + fmt_int(self.fg, 'u128'), + "liq: " + fmt_int(self.liq, 'u128'), + "tk: " + fmt_int(self.tk, 'i32'), + "crossed: " + fmt_bool(self.crossed), + "pf: " + fmt_int(self.pf, 'u128'), + "nb: " + fmt_int(self.nb, 'i32'), + "na: " + fmt_int(self.na, 'i32'), + "resid: " + fmt_int(self.resid, 'u128'), + ] + return "{ " + ", ".join(parts) + " }" + + @classmethod + def from_decoded(cls, d: dict) -> "SwapIterState": + return cls(sp=d['sp'], rem=d['rem'], out=d['out'], fg=d['fg'], liq=d['liq'], tk=d['tk'], crossed=d['crossed'], pf=d['pf'], nb=d['nb'], na=d['na'], resid=d['resid']) + + @classmethod + def from_plaintext(cls, text: str) -> "SwapIterState": + return cls.from_decoded(parse_plaintext(text)) + + +@dataclass(frozen=True) +class SwapOutput: + recipient: str + caller: str + token_in: str + token_out: str + amount_out: int + amount_remaining: int + token_in_1: str + amount_remaining_1: int + token_in_2: str + amount_remaining_2: int + + def to_plaintext(self) -> str: + parts = [ + "recipient: " + fmt_address(self.recipient), + "caller: " + fmt_address(self.caller), + "token_in: " + fmt_fieldlike(self.token_in, 'field'), + "token_out: " + fmt_fieldlike(self.token_out, 'field'), + "amount_out: " + fmt_int(self.amount_out, 'u128'), + "amount_remaining: " + fmt_int(self.amount_remaining, 'u128'), + "token_in_1: " + fmt_fieldlike(self.token_in_1, 'field'), + "amount_remaining_1: " + fmt_int(self.amount_remaining_1, 'u128'), + "token_in_2: " + fmt_fieldlike(self.token_in_2, 'field'), + "amount_remaining_2: " + fmt_int(self.amount_remaining_2, 'u128'), + ] + return "{ " + ", ".join(parts) + " }" + + @classmethod + def from_decoded(cls, d: dict) -> "SwapOutput": + return cls(recipient=d['recipient'], caller=d['caller'], token_in=d['token_in'], token_out=d['token_out'], amount_out=d['amount_out'], amount_remaining=d['amount_remaining'], token_in_1=d['token_in_1'], amount_remaining_1=d['amount_remaining_1'], token_in_2=d['token_in_2'], amount_remaining_2=d['amount_remaining_2']) + + @classmethod + def from_plaintext(cls, text: str) -> "SwapOutput": + return cls.from_decoded(parse_plaintext(text)) + + +@dataclass(frozen=True) +class PositionNFT: + owner: str + token_id: str + token0_id: str + token1_id: str + pool: str + tick_lower: int + tick_upper: int + _nonce: Optional[str] = None + + @classmethod + def from_decoded(cls, d: dict) -> "PositionNFT": + return cls(owner=d['owner'], token_id=d['token_id'], token0_id=d['token0_id'], token1_id=d['token1_id'], pool=d['pool'], tick_lower=d['tick_lower'], tick_upper=d['tick_upper'], _nonce=d.get('_nonce')) + + @classmethod + def from_plaintext(cls, text: str) -> "PositionNFT": + return cls.from_decoded(parse_plaintext(text)) + + +@dataclass(frozen=True) +class SwapComplianceRecord: + owner: str + swap_id: str + token_in: str + token_out: str + request: SwapRequest + caller: str + blinded_address: str + _nonce: Optional[str] = None + + @classmethod + def from_decoded(cls, d: dict) -> "SwapComplianceRecord": + return cls(owner=d['owner'], swap_id=d['swap_id'], token_in=d['token_in'], token_out=d['token_out'], request=SwapRequest.from_decoded(d['request']), caller=d['caller'], blinded_address=d['blinded_address'], _nonce=d.get('_nonce')) + + @classmethod + def from_plaintext(cls, text: str) -> "SwapComplianceRecord": + return cls.from_decoded(parse_plaintext(text)) + + +@dataclass(frozen=True) +class MultiHopSwapComplianceRecord: + owner: str + swap_id: str + request: SwapMultiHopRequest + caller: str + blinded_address: str + _nonce: Optional[str] = None + + @classmethod + def from_decoded(cls, d: dict) -> "MultiHopSwapComplianceRecord": + return cls(owner=d['owner'], swap_id=d['swap_id'], request=SwapMultiHopRequest.from_decoded(d['request']), caller=d['caller'], blinded_address=d['blinded_address'], _nonce=d.get('_nonce')) + + @classmethod + def from_plaintext(cls, text: str) -> "MultiHopSwapComplianceRecord": + return cls.from_decoded(parse_plaintext(text)) + + +@dataclass(frozen=True) +class MintComplianceRecord: + owner: str + token_id: str + token0_id: str + token1_id: str + request: MintPositionRequest + caller: str + recipient: str + _nonce: Optional[str] = None + + @classmethod + def from_decoded(cls, d: dict) -> "MintComplianceRecord": + return cls(owner=d['owner'], token_id=d['token_id'], token0_id=d['token0_id'], token1_id=d['token1_id'], request=MintPositionRequest.from_decoded(d['request']), caller=d['caller'], recipient=d['recipient'], _nonce=d.get('_nonce')) + + @classmethod + def from_plaintext(cls, text: str) -> "MintComplianceRecord": + return cls.from_decoded(parse_plaintext(text)) + + +MAPPING_VALUE_DECODERS: dict[str, Callable[[str], Any]] = { + "pools": PoolState.from_plaintext, + "slots": Slot.from_plaintext, + "ticks": Tick.from_plaintext, + "initialized_pools": parse_plaintext, + "tick_spacings": parse_plaintext, + "fee_tiers": parse_plaintext, + "fee_to_tick_spacing": parse_plaintext, + "positions": Position.from_plaintext, + "swap_outputs": SwapOutput.from_plaintext, + "admin": parse_plaintext, + "pending_admin": parse_plaintext, + "used_blinded_addresses": parse_plaintext, + "token_decimals": parse_plaintext, + "pool_creation_is_open": parse_plaintext, + "global_paused": parse_plaintext, + "token_allowed": parse_plaintext, + "token_paused": parse_plaintext, + "pair_paused": parse_plaintext, + "frozen_position": parse_plaintext, +} + +ABI: dict = {'program': 'shield_swap_v3.aleo', 'structs': [{'path': ['SwapRequest'], 'fields': [{'name': 'pool', 'ty': {'Primitive': 'Field'}}, {'name': 'zero_for_one', 'ty': {'Primitive': 'Boolean'}}, {'name': 'amount_in', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'amount_out_min', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'sqrt_price_limit', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'recipient', 'ty': {'Primitive': 'Address'}}, {'name': 'nonce', 'ty': {'Primitive': {'UInt': 'U64'}}}, {'name': 'deadline', 'ty': {'Primitive': {'UInt': 'U32'}}}]}, {'path': ['SwapHop'], 'fields': [{'name': 'pool', 'ty': {'Primitive': 'Field'}}, {'name': 'zero_for_one', 'ty': {'Primitive': 'Boolean'}}, {'name': 'sqrt_price_limit', 'ty': {'Primitive': {'UInt': 'U128'}}}]}, {'path': ['SwapMultiHopRequest'], 'fields': [{'name': 'token_in', 'ty': {'Primitive': 'Field'}}, {'name': 'token_out', 'ty': {'Primitive': 'Field'}}, {'name': 'amount_in', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'amount_out_min', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'recipient', 'ty': {'Primitive': 'Address'}}, {'name': 'hop0', 'ty': {'Struct': {'path': ['SwapHop'], 'program': 'shield_swap_v3.aleo'}}}, {'name': 'hop1', 'ty': {'Struct': {'path': ['SwapHop'], 'program': 'shield_swap_v3.aleo'}}}, {'name': 'hop2', 'ty': {'Struct': {'path': ['SwapHop'], 'program': 'shield_swap_v3.aleo'}}}, {'name': 'hop_count', 'ty': {'Primitive': {'UInt': 'U8'}}}, {'name': 'nonce', 'ty': {'Primitive': {'UInt': 'U64'}}}, {'name': 'deadline', 'ty': {'Primitive': {'UInt': 'U32'}}}, {'name': 'caller', 'ty': {'Primitive': 'Address'}}]}, {'path': ['MintPositionRequest'], 'fields': [{'name': 'pool', 'ty': {'Primitive': 'Field'}}, {'name': 'tick_lower', 'ty': {'Primitive': {'Int': 'I32'}}}, {'name': 'tick_upper', 'ty': {'Primitive': {'Int': 'I32'}}}, {'name': 'amount0_desired', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'amount1_desired', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'amount0_min', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'amount1_min', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'tick_lower_hint', 'ty': {'Primitive': {'Int': 'I32'}}}, {'name': 'tick_upper_hint', 'ty': {'Primitive': {'Int': 'I32'}}}]}, {'path': ['PoolState'], 'fields': [{'name': 'token0', 'ty': {'Primitive': 'Field'}}, {'name': 'token1', 'ty': {'Primitive': 'Field'}}, {'name': 'fee', 'ty': {'Primitive': {'UInt': 'U16'}}}, {'name': 'enabled', 'ty': {'Primitive': 'Boolean'}}, {'name': 'scale0', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'scale1', 'ty': {'Primitive': {'UInt': 'U128'}}}]}, {'path': ['Slot'], 'fields': [{'name': 'tick', 'ty': {'Primitive': {'Int': 'I32'}}}, {'name': 'tick_spacing', 'ty': {'Primitive': {'UInt': 'U32'}}}, {'name': 'sqrt_price', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'fee_protocol', 'ty': {'Primitive': {'UInt': 'U8'}}}, {'name': 'liquidity', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'fee_growth_global0_x_64', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'fee_growth_global1_x_64', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'fee_residual0_x_64', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'fee_residual1_x_64', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'max_liquidity_per_tick', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'protocol_fees0', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'protocol_fees1', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'next_init_below', 'ty': {'Primitive': {'Int': 'I32'}}}, {'name': 'next_init_above', 'ty': {'Primitive': {'Int': 'I32'}}}]}, {'path': ['Tick'], 'fields': [{'name': 'pool', 'ty': {'Primitive': 'Field'}}, {'name': 'liquidity_net', 'ty': {'Primitive': {'Int': 'I128'}}}, {'name': 'liquidity_gross', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'tick', 'ty': {'Primitive': {'Int': 'I32'}}}, {'name': 'fee_growth_outside0_64', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'fee_growth_outside1_64', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'prev', 'ty': {'Primitive': {'Int': 'I32'}}}, {'name': 'next', 'ty': {'Primitive': {'Int': 'I32'}}}]}, {'path': ['Position'], 'fields': [{'name': 'token_id', 'ty': {'Primitive': 'Field'}}, {'name': 'pool', 'ty': {'Primitive': 'Field'}}, {'name': 'tick_lower', 'ty': {'Primitive': {'Int': 'I32'}}}, {'name': 'tick_upper', 'ty': {'Primitive': {'Int': 'I32'}}}, {'name': 'liquidity', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'fee_growth_inside0_last_64', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'fee_growth_inside1_last_64', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'tokens_owed0', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'tokens_owed1', 'ty': {'Primitive': {'UInt': 'U128'}}}]}, {'path': ['PairKey'], 'fields': [{'name': 'token0', 'ty': {'Primitive': 'Field'}}, {'name': 'token1', 'ty': {'Primitive': 'Field'}}]}, {'path': ['SwapIterCfg'], 'fields': [{'name': 'z', 'ty': {'Primitive': 'Boolean'}}, {'name': 'lim', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'fee_pips', 'ty': {'Primitive': {'UInt': 'U32'}}}, {'name': 'fee_protocol', 'ty': {'Primitive': {'UInt': 'U8'}}}, {'name': 'slot_fg0', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'slot_fg1', 'ty': {'Primitive': {'UInt': 'U128'}}}]}, {'path': ['SwapIterState'], 'fields': [{'name': 'sp', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'rem', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'out', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'fg', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'liq', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'tk', 'ty': {'Primitive': {'Int': 'I32'}}}, {'name': 'crossed', 'ty': {'Primitive': 'Boolean'}}, {'name': 'pf', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'nb', 'ty': {'Primitive': {'Int': 'I32'}}}, {'name': 'na', 'ty': {'Primitive': {'Int': 'I32'}}}, {'name': 'resid', 'ty': {'Primitive': {'UInt': 'U128'}}}]}, {'path': ['SwapOutput'], 'fields': [{'name': 'recipient', 'ty': {'Primitive': 'Address'}}, {'name': 'caller', 'ty': {'Primitive': 'Address'}}, {'name': 'token_in', 'ty': {'Primitive': 'Field'}}, {'name': 'token_out', 'ty': {'Primitive': 'Field'}}, {'name': 'amount_out', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'amount_remaining', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'token_in_1', 'ty': {'Primitive': 'Field'}}, {'name': 'amount_remaining_1', 'ty': {'Primitive': {'UInt': 'U128'}}}, {'name': 'token_in_2', 'ty': {'Primitive': 'Field'}}, {'name': 'amount_remaining_2', 'ty': {'Primitive': {'UInt': 'U128'}}}]}], 'records': [{'path': ['PositionNFT'], 'fields': [{'name': 'owner', 'ty': {'Primitive': 'Address'}, 'mode': 'Public'}, {'name': 'token_id', 'ty': {'Primitive': 'Field'}, 'mode': 'Private'}, {'name': 'token0_id', 'ty': {'Primitive': 'Field'}, 'mode': 'Private'}, {'name': 'token1_id', 'ty': {'Primitive': 'Field'}, 'mode': 'Private'}, {'name': 'pool', 'ty': {'Primitive': 'Field'}, 'mode': 'Private'}, {'name': 'tick_lower', 'ty': {'Primitive': {'Int': 'I32'}}, 'mode': 'Private'}, {'name': 'tick_upper', 'ty': {'Primitive': {'Int': 'I32'}}, 'mode': 'Private'}]}, {'path': ['SwapComplianceRecord'], 'fields': [{'name': 'owner', 'ty': {'Primitive': 'Address'}, 'mode': 'Public'}, {'name': 'swap_id', 'ty': {'Primitive': 'Field'}, 'mode': 'Private'}, {'name': 'token_in', 'ty': {'Primitive': 'Field'}, 'mode': 'Private'}, {'name': 'token_out', 'ty': {'Primitive': 'Field'}, 'mode': 'Private'}, {'name': 'request', 'ty': {'Struct': {'path': ['SwapRequest'], 'program': 'shield_swap_v3.aleo'}}, 'mode': 'Private'}, {'name': 'caller', 'ty': {'Primitive': 'Address'}, 'mode': 'Private'}, {'name': 'blinded_address', 'ty': {'Primitive': 'Address'}, 'mode': 'Private'}]}, {'path': ['MultiHopSwapComplianceRecord'], 'fields': [{'name': 'owner', 'ty': {'Primitive': 'Address'}, 'mode': 'Public'}, {'name': 'swap_id', 'ty': {'Primitive': 'Field'}, 'mode': 'Private'}, {'name': 'request', 'ty': {'Struct': {'path': ['SwapMultiHopRequest'], 'program': 'shield_swap_v3.aleo'}}, 'mode': 'Private'}, {'name': 'caller', 'ty': {'Primitive': 'Address'}, 'mode': 'Private'}, {'name': 'blinded_address', 'ty': {'Primitive': 'Address'}, 'mode': 'Private'}]}, {'path': ['MintComplianceRecord'], 'fields': [{'name': 'owner', 'ty': {'Primitive': 'Address'}, 'mode': 'Public'}, {'name': 'token_id', 'ty': {'Primitive': 'Field'}, 'mode': 'Private'}, {'name': 'token0_id', 'ty': {'Primitive': 'Field'}, 'mode': 'Private'}, {'name': 'token1_id', 'ty': {'Primitive': 'Field'}, 'mode': 'Private'}, {'name': 'request', 'ty': {'Struct': {'path': ['MintPositionRequest'], 'program': 'shield_swap_v3.aleo'}}, 'mode': 'Private'}, {'name': 'caller', 'ty': {'Primitive': 'Address'}, 'mode': 'Private'}, {'name': 'recipient', 'ty': {'Primitive': 'Address'}, 'mode': 'Private'}]}], 'mappings': [{'name': 'pools', 'key': {'Primitive': 'Field'}, 'value': {'Struct': {'path': ['PoolState'], 'program': 'shield_swap_v3.aleo'}}}, {'name': 'slots', 'key': {'Primitive': 'Field'}, 'value': {'Struct': {'path': ['Slot'], 'program': 'shield_swap_v3.aleo'}}}, {'name': 'ticks', 'key': {'Primitive': 'Field'}, 'value': {'Struct': {'path': ['Tick'], 'program': 'shield_swap_v3.aleo'}}}, {'name': 'initialized_pools', 'key': {'Primitive': 'Field'}, 'value': {'Primitive': 'Boolean'}}, {'name': 'tick_spacings', 'key': {'Primitive': {'UInt': 'U32'}}, 'value': {'Primitive': 'Boolean'}}, {'name': 'fee_tiers', 'key': {'Primitive': {'UInt': 'U16'}}, 'value': {'Primitive': 'Boolean'}}, {'name': 'fee_to_tick_spacing', 'key': {'Primitive': {'UInt': 'U16'}}, 'value': {'Primitive': {'UInt': 'U32'}}}, {'name': 'positions', 'key': {'Primitive': 'Field'}, 'value': {'Struct': {'path': ['Position'], 'program': 'shield_swap_v3.aleo'}}}, {'name': 'swap_outputs', 'key': {'Primitive': 'Field'}, 'value': {'Struct': {'path': ['SwapOutput'], 'program': 'shield_swap_v3.aleo'}}}, {'name': 'admin', 'key': {'Primitive': 'Boolean'}, 'value': {'Primitive': 'Address'}}, {'name': 'pending_admin', 'key': {'Primitive': 'Boolean'}, 'value': {'Primitive': 'Address'}}, {'name': 'used_blinded_addresses', 'key': {'Primitive': 'Address'}, 'value': {'Primitive': 'Boolean'}}, {'name': 'token_decimals', 'key': {'Primitive': 'Field'}, 'value': {'Primitive': {'UInt': 'U8'}}}, {'name': 'pool_creation_is_open', 'key': {'Primitive': 'Boolean'}, 'value': {'Primitive': 'Boolean'}}, {'name': 'global_paused', 'key': {'Primitive': 'Boolean'}, 'value': {'Primitive': 'Boolean'}}, {'name': 'token_allowed', 'key': {'Primitive': 'Field'}, 'value': {'Primitive': 'Boolean'}}, {'name': 'token_paused', 'key': {'Primitive': 'Field'}, 'value': {'Primitive': 'Boolean'}}, {'name': 'pair_paused', 'key': {'Struct': {'path': ['PairKey'], 'program': 'shield_swap_v3.aleo'}}, 'value': {'Primitive': 'Boolean'}}, {'name': 'frozen_position', 'key': {'Primitive': 'Field'}, 'value': {'Primitive': {'UInt': 'U32'}}}], 'storage_variables': [], 'functions': [{'name': 'transfer_admin', 'inputs': [{'Plaintext': {'ty': {'Primitive': 'Address'}, 'mode': 'Public'}}], 'outputs': ['Final']}, {'name': 'accept_admin', 'inputs': [], 'outputs': ['Final']}, {'name': 'add_tick_spacing', 'inputs': [{'Plaintext': {'ty': {'Primitive': {'UInt': 'U32'}}, 'mode': 'Public'}}], 'outputs': ['Final']}, {'name': 'add_fee_tier', 'inputs': [{'Plaintext': {'ty': {'Primitive': {'UInt': 'U16'}}, 'mode': 'Public'}}], 'outputs': ['Final']}, {'name': 'bind_fee_to_tick_spacing', 'inputs': [{'Plaintext': {'ty': {'Primitive': {'UInt': 'U16'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U32'}}, 'mode': 'Public'}}], 'outputs': ['Final']}, {'name': 'set_token_decimals', 'inputs': [{'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U8'}}, 'mode': 'Public'}}], 'outputs': ['Final']}, {'name': 'set_pool_enabled', 'inputs': [{'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': 'Boolean'}, 'mode': 'Public'}}], 'outputs': ['Final']}, {'name': 'set_pool_creation_is_open', 'inputs': [{'Plaintext': {'ty': {'Primitive': 'Boolean'}, 'mode': 'Public'}}], 'outputs': ['Final']}, {'name': 'set_global_paused', 'inputs': [{'Plaintext': {'ty': {'Primitive': 'Boolean'}, 'mode': 'Public'}}], 'outputs': ['Final']}, {'name': 'allow_token', 'inputs': [{'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}], 'outputs': ['Final']}, {'name': 'set_token_paused', 'inputs': [{'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': 'Boolean'}, 'mode': 'Public'}}], 'outputs': ['Final']}, {'name': 'set_pair_paused', 'inputs': [{'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': 'Boolean'}, 'mode': 'Public'}}], 'outputs': ['Final']}, {'name': 'freeze_position', 'inputs': [{'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}], 'outputs': ['Final']}, {'name': 'unfreeze_position', 'inputs': [{'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}], 'outputs': ['Final']}, {'name': 'set_fee_protocol', 'inputs': [{'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U8'}}, 'mode': 'Public'}}], 'outputs': ['Final']}, {'name': 'collect_protocol', 'inputs': [{'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': 'Address'}, 'mode': 'Public'}}], 'outputs': ['Final']}, {'name': 'create_pool', 'inputs': [{'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U16'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U32'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'Int': 'I32'}}, 'mode': 'Public'}}], 'outputs': [{'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': 'Address'}, 'mode': 'Public'}}, 'Final']}, {'name': 'mint', 'inputs': [{'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Private'}}, 'DynamicRecord', 'DynamicRecord', {'Plaintext': {'ty': {'Primitive': 'Address'}, 'mode': 'Private'}}, {'Plaintext': {'ty': {'Struct': {'path': ['MintPositionRequest'], 'program': 'shield_swap_v3.aleo'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}], 'outputs': [{'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, {'Record': {'path': ['PositionNFT'], 'program': 'shield_swap_v3.aleo'}}, 'DynamicRecord', 'DynamicRecord', {'Record': {'path': ['MintComplianceRecord'], 'program': 'shield_swap_v3.aleo'}}, 'Final']}, {'name': 'decrease_liquidity', 'inputs': [{'Record': {'path': ['PositionNFT'], 'program': 'shield_swap_v3.aleo'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}], 'outputs': [{'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, {'Record': {'path': ['PositionNFT'], 'program': 'shield_swap_v3.aleo'}}, 'Final']}, {'name': 'increase_liquidity', 'inputs': [{'Record': {'path': ['PositionNFT'], 'program': 'shield_swap_v3.aleo'}}, 'DynamicRecord', 'DynamicRecord', {'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'Int': 'I32'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'Int': 'I32'}}, 'mode': 'Public'}}], 'outputs': [{'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, {'Record': {'path': ['PositionNFT'], 'program': 'shield_swap_v3.aleo'}}, 'DynamicRecord', 'DynamicRecord', 'Final']}, {'name': 'collect', 'inputs': [{'Record': {'path': ['PositionNFT'], 'program': 'shield_swap_v3.aleo'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': 'Address'}, 'mode': 'Private'}}], 'outputs': [{'Record': {'path': ['PositionNFT'], 'program': 'shield_swap_v3.aleo'}}, 'DynamicRecord', 'DynamicRecord', 'Final']}, {'name': 'burn', 'inputs': [{'Record': {'path': ['PositionNFT'], 'program': 'shield_swap_v3.aleo'}}], 'outputs': [{'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': 'Address'}, 'mode': 'Public'}}, 'Final']}, {'name': 'swap', 'inputs': ['DynamicRecord', {'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Private'}}, {'Plaintext': {'ty': {'Primitive': 'Address'}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': 'Boolean'}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U64'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U32'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}], 'outputs': [{'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, 'DynamicRecord', {'Record': {'path': ['SwapComplianceRecord'], 'program': 'shield_swap_v3.aleo'}}, 'Final']}, {'name': 'claim_swap_output', 'inputs': [{'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Private'}}, {'Plaintext': {'ty': {'Primitive': 'Address'}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}], 'outputs': ['DynamicRecord', 'DynamicRecord', 'Final']}, {'name': 'swap_multi_hop', 'inputs': [{'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Private'}}, {'Plaintext': {'ty': {'Primitive': 'Address'}, 'mode': 'Public'}}, 'DynamicRecord', {'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Struct': {'path': ['SwapHop'], 'program': 'shield_swap_v3.aleo'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Struct': {'path': ['SwapHop'], 'program': 'shield_swap_v3.aleo'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Struct': {'path': ['SwapHop'], 'program': 'shield_swap_v3.aleo'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U8'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U64'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U32'}}, 'mode': 'Public'}}], 'outputs': [{'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, 'DynamicRecord', {'Record': {'path': ['MultiHopSwapComplianceRecord'], 'program': 'shield_swap_v3.aleo'}}, 'Final']}, {'name': 'claim_multi_hop_output', 'inputs': [{'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Private'}}, {'Plaintext': {'ty': {'Primitive': 'Address'}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': 'Field'}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}], 'outputs': ['DynamicRecord', 'DynamicRecord', 'DynamicRecord', 'DynamicRecord', 'Final']}], 'views': [{'name': 'view_sqrt_price_at_tick', 'inputs': [{'Plaintext': {'ty': {'Primitive': {'Int': 'I32'}}, 'mode': 'Public'}}], 'outputs': [{'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}]}, {'name': 'view_amounts_for_liquidity', 'inputs': [{'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': 'Boolean'}, 'mode': 'Public'}}], 'outputs': [{'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}]}, {'name': 'view_liquidity_for_amounts', 'inputs': [{'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}], 'outputs': [{'Plaintext': {'ty': {'Primitive': {'UInt': 'U128'}}, 'mode': 'Public'}}]}, {'name': 'view_swap_iteration', 'inputs': [{'Plaintext': {'ty': {'Struct': {'path': ['SwapIterCfg'], 'program': 'shield_swap_v3.aleo'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Primitive': {'Int': 'I32'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Struct': {'path': ['Tick'], 'program': 'shield_swap_v3.aleo'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Struct': {'path': ['SwapIterState'], 'program': 'shield_swap_v3.aleo'}}, 'mode': 'Public'}}], 'outputs': [{'Plaintext': {'ty': {'Struct': {'path': ['SwapIterState'], 'program': 'shield_swap_v3.aleo'}}, 'mode': 'Public'}}, {'Plaintext': {'ty': {'Struct': {'path': ['Tick'], 'program': 'shield_swap_v3.aleo'}}, 'mode': 'Public'}}]}]} diff --git a/shield-swap-sdk/python/aleo_shield_swap/agent.py b/shield-swap-sdk/python/aleo_shield_swap/agent.py new file mode 100644 index 00000000..6404ed90 --- /dev/null +++ b/shield-swap-sdk/python/aleo_shield_swap/agent.py @@ -0,0 +1,177 @@ +"""Framework-neutral agent tools over a ShieldSwap client. + +``shield_swap_tools()`` returns tool definitions in the Claude API ``tools=`` +shape (name / description / input_schema) — they plug into any framework +that speaks JSON-schema tools. ``dispatch_tool(dex, name, args)`` executes +one against a :class:`~aleo_shield_swap.client.ShieldSwap` (write verbs run +``.delegate()``) and returns a JSON-serializable result; handles serialize +as dicts so an agent can persist and resume the two-step swap flow. +""" +from __future__ import annotations + +import json +from dataclasses import asdict, is_dataclass +from typing import Any, Callable + +from .types import SwapHandle + +_S = {"type": "string"} +_I = {"type": "integer"} + + +def _schema(properties: dict[str, Any], required: list[str]) -> dict[str, Any]: + return {"type": "object", "properties": properties, "required": required} + + +def _serialize(value: Any) -> Any: + if is_dataclass(value) and not isinstance(value, type): + return asdict(value) + if isinstance(value, list): + return [_serialize(v) for v in value] + if isinstance(value, dict): + return {k: _serialize(v) for k, v in value.items()} + raw = getattr(value, "raw", None) # SlotView and friends + if raw is not None and is_dataclass(raw) and not isinstance(raw, type): + return asdict(raw) + return value + + +def _h_get_pools(dex: Any, args: dict[str, Any]) -> Any: + return [{"key": p.key, "token0": p.token0, "token1": p.token1, + "fee": p.fee, + "token0_symbol": p.token0_info.symbol if p.token0_info else None, + "token1_symbol": p.token1_info.symbol if p.token1_info else None} + for p in dex.api.get_pools()] + + +def _h_get_route(dex: Any, args: dict[str, Any]) -> Any: + return _serialize(dex.api.get_route( + token_in=args["token_in"], token_out=args["token_out"], + amount_in=args.get("amount_in"))) + + +def _h_get_slot(dex: Any, args: dict[str, Any]) -> Any: + return _serialize(dex.get_slot(args["pool_key"])) + + +def _h_get_balances(dex: Any, args: dict[str, Any]) -> Any: + return dex.get_balances(address=args.get("address")) + + +def _h_swap(dex: Any, args: dict[str, Any]) -> Any: + call = dex.swap( + pool_key=args["pool_key"], token_in_id=args["token_in_id"], + amount_in=int(args["amount_in"]), + slippage_bps=int(args.get("slippage_bps", 50)), + expected_out=(int(args["expected_out"]) + if args.get("expected_out") is not None else None), + token_in_program=args.get("token_in_program")) + return asdict(call.delegate()) + + +def _h_claim(dex: Any, args: dict[str, Any]) -> Any: + handle = SwapHandle.from_json(json.dumps(args["handle"])) + return asdict(dex.claim_swap_output(handle).delegate()) + + +def _h_increase(dex: Any, args: dict[str, Any]) -> Any: + call = dex.increase_liquidity( + pool_key=args["pool_key"], + amount0_desired=int(args["amount0_desired"]), + amount1_desired=int(args["amount1_desired"]), + token0_program=args.get("token0_program"), + token1_program=args.get("token1_program")) + return asdict(call.delegate()) + + +def _h_decrease(dex: Any, args: dict[str, Any]) -> Any: + call = dex.decrease_liquidity( + pool_key=args["pool_key"], + liquidity_to_remove=int(args["liquidity_to_remove"])) + return asdict(call.delegate()) + + +def _h_collect(dex: Any, args: dict[str, Any]) -> Any: + call = dex.collect( + pool_key=args["pool_key"], + amount0_requested=int(args["amount0_requested"]), + amount1_requested=int(args["amount1_requested"])) + return asdict(call.delegate()) + + +def _h_burn(dex: Any, args: dict[str, Any]) -> Any: + return asdict(dex.burn(pool_key=args["pool_key"]).delegate()) + + +def _h_create_pool(dex: Any, args: dict[str, Any]) -> Any: + call = dex.create_pool( + token0_id=args["token0_id"], token1_id=args["token1_id"], + fee=int(args["fee"]), initial_tick=int(args["initial_tick"])) + return asdict(call.delegate()) + + +def _h_mint(dex: Any, args: dict[str, Any]) -> Any: + call = dex.mint( + pool_key=args["pool_key"], + tick_lower=int(args["tick_lower"]), tick_upper=int(args["tick_upper"]), + amount0_desired=int(args["amount0_desired"]), + amount1_desired=int(args["amount1_desired"]), + token0_program=args.get("token0_program"), + token1_program=args.get("token1_program")) + return asdict(call.delegate()) + + +_TOOLS: list[tuple[str, str, dict[str, Any], Callable[[Any, dict[str, Any]], Any]]] = [ + ("get_pools", "List shield_swap pools with their token pairs and fee tiers.", + _schema({}, []), _h_get_pools), + ("get_route", "Quote a trade route between two tokens; returns the estimated output.", + _schema({"token_in": _S, "token_out": _S, "amount_in": _I}, + ["token_in", "token_out"]), _h_get_route), + ("get_slot", "Live pool state: sqrt price, current tick, in-range liquidity.", + _schema({"pool_key": _S}, ["pool_key"]), _h_get_slot), + ("get_balances", "Public + private + total balances per token for an address.", + _schema({"address": _S}, []), _h_get_balances), + ("swap", "Request a private swap (phase 1 of 2). Returns the swap handle — " + "persist it; claim_swap_output consumes it after finalization.", + _schema({"pool_key": _S, "token_in_id": _S, "amount_in": _I, + "slippage_bps": _I, "expected_out": _I, "token_in_program": _S}, + ["pool_key", "token_in_id", "amount_in"]), _h_swap), + ("claim_swap_output", "Claim a private swap's output (phase 2). Takes the " + "handle returned by swap; retry if not finalized yet.", + _schema({"handle": {"type": "object"}}, ["handle"]), _h_claim), + ("mint", "Mint a concentrated-liquidity position over a tick range.", + _schema({"pool_key": _S, "tick_lower": _I, "tick_upper": _I, + "amount0_desired": _I, "amount1_desired": _I, + "token0_program": _S, "token1_program": _S}, + ["pool_key", "tick_lower", "tick_upper", + "amount0_desired", "amount1_desired"]), _h_mint), + ("increase_liquidity", "Add funds to an existing position (range fixed at mint).", + _schema({"pool_key": _S, "amount0_desired": _I, "amount1_desired": _I, + "token0_program": _S, "token1_program": _S}, + ["pool_key", "amount0_desired", "amount1_desired"]), _h_increase), + ("decrease_liquidity", "Remove liquidity from a position; owed amounts become collectable.", + _schema({"pool_key": _S, "liquidity_to_remove": _I}, + ["pool_key", "liquidity_to_remove"]), _h_decrease), + ("collect", "Collect owed token amounts from a position.", + _schema({"pool_key": _S, "amount0_requested": _I, "amount1_requested": _I}, + ["pool_key", "amount0_requested", "amount1_requested"]), _h_collect), + ("burn", "Burn an empty position NFT.", + _schema({"pool_key": _S}, ["pool_key"]), _h_burn), + ("create_pool", "Create a new pool for a token pair at a registered fee tier.", + _schema({"token0_id": _S, "token1_id": _S, "fee": _I, "initial_tick": _I}, + ["token0_id", "token1_id", "fee", "initial_tick"]), _h_create_pool), +] + + +def shield_swap_tools() -> list[dict[str, Any]]: + """Tool definitions (Claude API ``tools=`` shape).""" + return [{"name": name, "description": desc, "input_schema": schema} + for name, desc, schema, _ in _TOOLS] + + +def dispatch_tool(dex: Any, name: str, args: dict[str, Any]) -> Any: + """Execute one tool against *dex*; returns a JSON-serializable result.""" + for tool_name, _, _, handler in _TOOLS: + if tool_name == name: + return handler(dex, args) + raise ValueError(f"Unknown shield_swap tool: {name!r}") diff --git a/shield-swap-sdk/python/aleo_shield_swap/api.py b/shield-swap-sdk/python/aleo_shield_swap/api.py new file mode 100644 index 00000000..96e3bf0b --- /dev/null +++ b/shield-swap-sdk/python/aleo_shield_swap/api.py @@ -0,0 +1,236 @@ +"""Typed client for the off-chain DEX API (amm-api). + +Route paths and response shapes come from ``codegen/amm_api.openapi.json`` — +when they drift, rerun ``codegen/regen-openapi.sh`` and fix here. + +The live API returns MORE fields than the documented schemas (e.g. pools +entries carry undocumented ``token0_info``/``token1_info``), so models are +built tolerantly: unknown keys are dropped instead of raising, and the pools +token info is surfaced through :class:`PoolEntry`. +""" +from __future__ import annotations + +from dataclasses import dataclass, fields +from typing import Any, Optional, TypeVar + +import requests + +from . import _api_models as models +from .errors import DexApiError + +DEFAULT_API_URL = "https://amm-api.dev.provable.com" +_TIMEOUT = 30.0 + +T = TypeVar("T") + + +def _build(cls: type[T], d: Any) -> T: + """Build a generated model from a response dict, dropping unknown keys.""" + if not isinstance(d, dict): + raise DexApiError(200, f"expected an object for {cls.__name__}, got {d!r}") + names = {f.name for f in fields(cls)} # type: ignore[arg-type] + return cls(**{k: v for k, v in d.items() if k in names}) + + +@dataclass(frozen=True) +class PoolEntry: + """One ``/pools`` entry: the documented pool state plus the undocumented + per-token info (which carries the load-bearing ``wrapper_program``). + Delegates attribute access to the pool state, so ``entry.key`` works.""" + + pool: models.PoolStateDoc + token0_info: Optional[models.TokenDoc] + token1_info: Optional[models.TokenDoc] + + def __getattr__(self, name: str) -> Any: + return getattr(self.pool, name) + + +class ApiClient: + """Synchronous DEX REST client; every method returns generated models. + + Some endpoints (route quoting, OHLCV, balances) are auth-gated: call + :meth:`authenticate` once with any Aleo account — the API authenticates + by signature (challenge/verify), no funds required — or adopt a + previously issued JWT via ``token=``/:meth:`set_token`. + """ + + def __init__(self, base_url: str = DEFAULT_API_URL, session: Any | None = None, + token: str | None = None) -> None: + self.base_url = base_url.rstrip("/") + self._session = session or requests.Session() + self._token = token + + def __repr__(self) -> str: + return f"ApiClient({self.base_url!r})" + + def _headers(self) -> dict[str, str]: + headers = {"accept": "application/json"} + if self._token: + headers["authorization"] = f"Bearer {self._token}" + return headers + + def _get(self, path: str, params: dict[str, Any] | None = None) -> Any: + resp = self._session.get(f"{self.base_url}{path}", params=params, + headers=self._headers(), timeout=_TIMEOUT) + if not 200 <= resp.status_code < 300: + raise DexApiError(resp.status_code, resp.text) + return resp.json() + + def _post(self, path: str, body: dict[str, Any]) -> Any: + resp = self._session.post(f"{self.base_url}{path}", json=body, + headers=self._headers(), timeout=_TIMEOUT) + if not 200 <= resp.status_code < 300: + raise DexApiError(resp.status_code, resp.text) + return resp.json() + + # ── Auth ─────────────────────────────────────────────────────────────── + + def authenticate(self, address: str, sign: Any) -> str: + """Challenge/verify handshake; stores and returns the JWT. + + *sign* is a callable taking the challenge message string and + returning an Aleo signature literal (``sign1…``) — e.g.:: + + api.authenticate(str(acct.address), + lambda msg: str(aleo.account.sign(msg.encode(), acct))) + """ + challenge = self._post("/auth/challenge", {"address": address}) + signature = sign(challenge["data"]["message"]) + verified = self._post("/auth/verify", + {"address": address, "signature": str(signature)}) + self._token = verified["data"]["token"] + return self._token + + def set_token(self, token: str) -> None: + """Adopt a previously issued JWT.""" + self._token = token + + # ── Pools & tokens ───────────────────────────────────────────────────── + + def get_pools(self) -> list[PoolEntry]: + entries = self._get("/pools")["data"] + return [ + PoolEntry( + pool=_build(models.PoolStateDoc, e), + token0_info=_build(models.TokenDoc, e["token0_info"]) if e.get("token0_info") else None, + token1_info=_build(models.TokenDoc, e["token1_info"]) if e.get("token1_info") else None, + ) + for e in entries + ] + + def get_tokens(self) -> list[models.TokenDoc]: + return [_build(models.TokenDoc, t) for t in self._get("/tokens")["data"]] + + # ── Trading ──────────────────────────────────────────────────────────── + + def get_route(self, *, token_in: str, token_out: str, + amount_in: int | None = None) -> models.RouteResultDoc: + params: dict[str, Any] = {"token_in": token_in, "token_out": token_out} + if amount_in is not None: + params["amount_in"] = str(amount_in) + return _build(models.RouteResultDoc, self._get("/route", params)["data"]) + + def get_swap(self, swap_id: str) -> models.SwapDoc: + return _build(models.SwapDoc, self._get(f"/swaps/{swap_id}")["data"]) + + def get_ohlcv(self, pool_key: str, *, granularity: str, + from_ts: str, to_ts: str) -> list[models.OhlcvDoc]: + data = self._get(f"/pools/{pool_key}/ohlcv", + {"granularity": granularity, "from": from_ts, "to": to_ts})["data"] + return [_build(models.OhlcvDoc, o) for o in data] + + # ── Balances ─────────────────────────────────────────────────────────── + + def get_public_balances(self, user: str) -> list[models.TokenBalanceDoc]: + return [_build(models.TokenBalanceDoc, b) + for b in self._get("/balances", {"user": user})["data"]] + + +class AsyncApiClient: + """Async mirror of :class:`ApiClient` (httpx — the ``[async]`` extra).""" + + def __init__(self, base_url: str = DEFAULT_API_URL, client: Any | None = None, + token: str | None = None) -> None: + self.base_url = base_url.rstrip("/") + if client is None: + try: + import httpx + except ImportError as exc: # pragma: no cover - env-dependent + raise ImportError( + "AsyncApiClient requires httpx — install the async extra: " + "pip install 'shield-swap-sdk[async]'" + ) from exc + client = httpx.AsyncClient(timeout=_TIMEOUT) + self._client = client + self._token = token + + def __repr__(self) -> str: + return f"AsyncApiClient({self.base_url!r})" + + def _headers(self) -> dict[str, str]: + headers = {"accept": "application/json"} + if self._token: + headers["authorization"] = f"Bearer {self._token}" + return headers + + async def _get(self, path: str, params: dict[str, Any] | None = None) -> Any: + resp = await self._client.get(f"{self.base_url}{path}", params=params, + headers=self._headers()) + if not 200 <= resp.status_code < 300: + raise DexApiError(resp.status_code, resp.text) + return resp.json() + + async def _post(self, path: str, body: dict[str, Any]) -> Any: + resp = await self._client.post(f"{self.base_url}{path}", json=body, + headers=self._headers()) + if not 200 <= resp.status_code < 300: + raise DexApiError(resp.status_code, resp.text) + return resp.json() + + async def authenticate(self, address: str, sign: Any) -> str: + """Async challenge/verify handshake; stores and returns the JWT.""" + challenge = await self._post("/auth/challenge", {"address": address}) + signature = sign(challenge["data"]["message"]) + verified = await self._post("/auth/verify", + {"address": address, "signature": str(signature)}) + self._token = verified["data"]["token"] + return self._token + + def set_token(self, token: str) -> None: + self._token = token + + async def get_pools(self) -> list[PoolEntry]: + entries = (await self._get("/pools"))["data"] + return [ + PoolEntry( + pool=_build(models.PoolStateDoc, e), + token0_info=_build(models.TokenDoc, e["token0_info"]) if e.get("token0_info") else None, + token1_info=_build(models.TokenDoc, e["token1_info"]) if e.get("token1_info") else None, + ) + for e in entries + ] + + async def get_tokens(self) -> list[models.TokenDoc]: + return [_build(models.TokenDoc, t) for t in (await self._get("/tokens"))["data"]] + + async def get_route(self, *, token_in: str, token_out: str, + amount_in: int | None = None) -> models.RouteResultDoc: + params: dict[str, Any] = {"token_in": token_in, "token_out": token_out} + if amount_in is not None: + params["amount_in"] = str(amount_in) + return _build(models.RouteResultDoc, (await self._get("/route", params))["data"]) + + async def get_swap(self, swap_id: str) -> models.SwapDoc: + return _build(models.SwapDoc, (await self._get(f"/swaps/{swap_id}"))["data"]) + + async def get_ohlcv(self, pool_key: str, *, granularity: str, + from_ts: str, to_ts: str) -> list[models.OhlcvDoc]: + data = (await self._get(f"/pools/{pool_key}/ohlcv", + {"granularity": granularity, "from": from_ts, + "to": to_ts}))["data"] + return [_build(models.OhlcvDoc, o) for o in data] + + async def get_public_balances(self, user: str) -> list[models.TokenBalanceDoc]: + return [_build(models.TokenBalanceDoc, b) + for b in (await self._get("/balances", {"user": user}))["data"]] diff --git a/shield-swap-sdk/python/aleo_shield_swap/async_client.py b/shield-swap-sdk/python/aleo_shield_swap/async_client.py new file mode 100644 index 00000000..f1c750d1 --- /dev/null +++ b/shield-swap-sdk/python/aleo_shield_swap/async_client.py @@ -0,0 +1,323 @@ +"""AsyncShieldSwap — the shield_swap client over an ``AsyncAleo`` facade. + +Reads, balances, and the two-transaction private-swap flow of +:class:`~aleo_shield_swap.client.ShieldSwap`, with every I/O method +``async``. Liquidity verbs are sync-client-only for now. Pure logic is +shared from ``_core``/``derivations`` — only the I/O differs. +""" +from __future__ import annotations + +from typing import Any, Callable, Generic, Optional, TypeVar + +from . import _generated as g +from ._calls import extract_tx_id, root_outputs +from ._core import ( + find_position_plaintext, + normalize_mapping_value, + generate_swap_nonce, + parse_token_record_info, + pick_covering_record, + program_imports, + register_program_sources, + resolve_swap_params, +) +from .api import AsyncApiClient, DEFAULT_API_URL +from .derivations import ( + BlindedIdentity, + derive_blinded_address, + derive_blinding_factor, + derive_pool_key as _derive_pool_key, + derive_tick_key as _derive_tick_key, +) +from .errors import ( + InsufficientRecordsError, + PoolNotFoundError, + PoolNotInitializedError, + SwapOutputNotFinalizedError, +) +from .types import ClaimResult, SlotView, SwapHandle + +R = TypeVar("R") + + +class AsyncDexCall(Generic[R]): + """Async mirror of :class:`~aleo_shield_swap._calls.DexCall`.""" + + def __init__(self, aleo: Any, bound: Any, + build_result: Callable[[str, list[Any]], R]) -> None: + self._aleo = aleo + self._bound = bound + self._build = build_result + + def simulate(self, account: Any = None) -> Any: + # AsyncBoundCall.simulate is synchronous (local authorization). + return self._bound.simulate(account) + + async def transact(self, account: Any = None, **fee_kwargs: Any) -> R: + tx = await self._bound.build_transaction(account, **fee_kwargs) + outputs = root_outputs(tx.decoded(), self._bound.program_id, + self._bound.function_name) + await self._aleo.network.submit_transaction(tx.raw) + return self._build(tx.id, outputs) + + async def delegate(self, account: Any = None, **fee_kwargs: Any) -> R: + payload = await self._bound.delegate(account, **fee_kwargs) + tx_id = extract_tx_id(payload) + await self._aleo.network.wait_for_transaction(tx_id) + tx = await self._aleo.network.get_transaction_object(tx_id) + decoded = [ + {"program": str(t.program_id), "function": str(t.function_name), + "outputs": list(t.outputs())} + for t in tx.transitions() + ] + outputs = root_outputs(decoded, self._bound.program_id, + self._bound.function_name) + return self._build(tx_id, outputs) + + +class AsyncShieldSwap: + """Typed async client for the shield_swap AMM over ``AsyncAleo``.""" + + def __init__(self, aleo: Any, *, program: str = g.PROGRAM_ID, + api_url: str = DEFAULT_API_URL) -> None: + self._aleo = aleo + self.program = program + self.api = AsyncApiClient(api_url) + + def __repr__(self) -> str: + return f"AsyncShieldSwap(program={self.program!r}, api={self.api.base_url!r})" + + # ── Mapping plumbing ───────────────────────────────────────────────────── + + async def _mapping_value(self, mapping: str, key: str) -> Optional[str]: + prog = await self._aleo.programs.get(self.program) + raw = await prog.mapping(mapping).get(key) + return normalize_mapping_value(raw) + + # ── Chain reads ────────────────────────────────────────────────────────── + + async def get_pool(self, pool_key: str) -> g.PoolState: + raw = await self._mapping_value("pools", pool_key) + if raw is None: + raise PoolNotFoundError(pool_key) + return g.PoolState.from_plaintext(raw) + + async def get_slot(self, pool_key: str) -> SlotView: + raw = await self._mapping_value("slots", pool_key) + if raw is None: + if await self._mapping_value("pools", pool_key) is not None: + raise PoolNotInitializedError(pool_key) + raise PoolNotFoundError(pool_key) + return SlotView(g.Slot.from_plaintext(raw)) + + async def get_swap_output(self, swap: "SwapHandle | str") -> g.SwapOutput: + swap_id = swap.swap_id if isinstance(swap, SwapHandle) else swap + if not swap_id: + raise ValueError("SwapHandle has no swap_id yet — wait for the " + "request transaction and recover it first.") + raw = await self._mapping_value("swap_outputs", swap_id) + if raw is None: + raise SwapOutputNotFinalizedError(swap_id) + return g.SwapOutput.from_plaintext(raw) + + async def is_pool_initialized(self, pool_key: str) -> bool: + raw = await self._mapping_value("initialized_pools", pool_key) + return raw is not None and "true" in raw + + # ── Pure derivations (sync — no I/O) ───────────────────────────────────── + + def derive_pool_key(self, token0: str, token1: str, fee: int) -> str: + return _derive_pool_key(token0, token1, fee, network=self._aleo.network_name) + + def derive_tick_key(self, pool_key: str, tick: int) -> str: + return _derive_tick_key(pool_key, tick, network=self._aleo.network_name) + + # ── Async record/identity/imports helpers ─────────────────────────────── + + async def _next_blinded_identity(self, account: Any) -> BlindedIdentity: + network = self._aleo.network_name + scalar = str(account.view_key.to_scalar()) + signer = str(account.address) + prog = await self._aleo.programs.get(self.program) + mapping = prog.mapping("used_blinded_addresses") + for counter in range(64): + bf = derive_blinding_factor(scalar, counter, self.program, network=network) + ba = derive_blinded_address(bf, signer, self.program, network=network) + if (await mapping.get(ba)) in (None, "", "null", "false"): + return BlindedIdentity(counter, bf, ba) + raise ValueError(f"No unused blinded address in 64 counters for {self.program}") + + async def _select_token_record(self, *, program: str, min_amount: int, + token_id: Optional[str], account: Any) -> str: + provider = self._aleo.record_provider + if provider is None: + raise InsufficientRecordsError( + "No record provider configured — pass token_record= explicitly.") + records = await provider.find(account, program=program, unspent=True) + chosen = pick_covering_record(records, min_amount=min_amount, token_id=token_id) + if chosen is None: + raise InsufficientRecordsError( + f"No unspent {program} record covers {min_amount} " + f"(token_id={token_id or 'any'}) — privatize funds or pass token_record=.") + return chosen + + async def _select_position_record(self, pool_key: str, account: Any) -> str: + records = await self._aleo.record_provider.find( + account, program=self.program, unspent=True) + plaintext = find_position_plaintext(records, pool_key) + if plaintext is None: + raise InsufficientRecordsError( + f"No unspent PositionNFT record for pool {pool_key}.") + return plaintext + + async def _ensure(self, token_programs: list, imports=None) -> None: + """Fetch the import closure (async) and register it with the process.""" + sources: dict = dict(imports or {}) + stack = [self.program, *token_programs, *sources] + seen: set = set() + while stack: + pid = stack.pop() + if pid in seen or pid == "credits.aleo": + continue + seen.add(pid) + if pid not in sources: + prog = await self._aleo.programs.get(pid) + sources[pid] = str(prog.source) + stack.extend(program_imports(sources[pid])) + register_program_sources(self._aleo, sources) + + async def _token_program(self, token_id: str) -> str: + for tok in await self.api.get_tokens(): + if tok.address == token_id and tok.wrapper_program: + return tok.wrapper_program + raise ValueError( + f"Cannot resolve the wrapper program for {token_id} — pass " + "token_in_program= (or token_record=) explicitly.") + + def _account(self, account: Any = None) -> Any: + acct = account if account is not None else self._aleo.default_account + if acct is None: + raise ValueError("No signer: pass account= or set aleo.default_account") + return acct + + # ── Balances ───────────────────────────────────────────────────────────── + + async def get_private_balances(self, programs: list[str], + account: Any = None) -> dict[str, int]: + provider = self._aleo.record_provider + out: dict[str, int] = {} + for program in programs: + total = 0 + for rec in await provider.find(account, program=program, unspent=True): + plaintext = (rec.get("record_plaintext") if isinstance(rec, dict) + else getattr(rec, "record_plaintext", None)) + info = parse_token_record_info(plaintext) if plaintext else None + if info is not None: + total += info["amount"] + out[program] = total + return out + + async def get_balances(self, address: Optional[str] = None, + account: Any = None) -> dict[str, dict[str, Any]]: + acct = account if account is not None else self._aleo.default_account + addr = address or (str(acct.address) if acct is not None else None) + if addr is None: + raise ValueError("No address: pass address= or set aleo.default_account") + tokens = await self.api.get_tokens() + by_program = {t.wrapper_program: t for t in tokens if t.wrapper_program} + private = await self.get_private_balances(list(by_program), account=acct) + out: dict[str, dict[str, Any]] = {} + for bal in await self.api.get_public_balances(addr): + entry = out.setdefault(bal.token_id, { + "symbol": bal.symbol, "decimals": bal.decimals, + "public": 0, "private": 0}) + entry["public"] += int(bal.balance) + for program, amount in private.items(): + tok = by_program[program] + if amount == 0 and tok.address not in out: + continue + entry = out.setdefault(tok.address, { + "symbol": tok.symbol, "decimals": tok.decimals, + "public": 0, "private": 0}) + entry["private"] += amount + for entry in out.values(): + entry["total"] = entry["public"] + entry["private"] + return out + + # ── Writes ─────────────────────────────────────────────────────────────── + + async def swap(self, *, pool_key: str, token_in_id: str, amount_in: int, + slippage_bps: int = 50, expected_out: Optional[int] = None, + sqrt_price_limit: Optional[int] = None, + deadline_offset_blocks: int = 100, + nonce: Optional[int] = None, + token_in_program: Optional[str] = None, + token_record: Optional[str] = None, + imports: Optional[dict[str, str]] = None, + account: Any = None) -> AsyncDexCall[SwapHandle]: + acct = self._account(account) + pool = await self.get_pool(pool_key) + slot = await self.get_slot(pool_key) + resolved = resolve_swap_params( + pool=pool, slot=slot, token_in_id=token_in_id, amount_in=amount_in, + slippage_bps=slippage_bps, expected_out=expected_out, + sqrt_price_limit=sqrt_price_limit) + deadline = int(await self._aleo.network.get_latest_height()) + deadline_offset_blocks + swap_nonce = nonce if nonce is not None else generate_swap_nonce() + identity = await self._next_blinded_identity(acct) + + record = token_record + if record is None: + program = token_in_program or await self._token_program(token_in_id) + record = await self._select_token_record( + program=program, min_amount=amount_in, + token_id=token_in_id, account=acct) + token_programs = [program] + else: + token_programs = [token_in_program] if token_in_program else [] + await self._ensure(token_programs, imports) + + inputs = [ + record, identity.blinding_factor, identity.blinded_address, + pool_key, resolved.zero_for_one, + f"{amount_in}u128", f"{resolved.amount_out_min}u128", + f"{resolved.sqrt_price_limit}u128", + f"{swap_nonce}u64", f"{deadline}u32", + pool.token0, pool.token1, + ] + prog = await self._aleo.programs.get(self.program) + bound = prog.functions.swap(*inputs) + + def build_result(tx_id: str, outputs: list[Any]) -> SwapHandle: + swap_id = next((o for o in outputs + if isinstance(o, str) and o.endswith("field")), None) + return SwapHandle( + swap_id=swap_id, + blinding_factor=identity.blinding_factor, + blinded_address=identity.blinded_address, + token_in_id=token_in_id, token_out_id=resolved.token_out_id, + pool_key=pool_key, amount_in=amount_in, + transaction_id=tx_id, program=self.program) + + return AsyncDexCall(self._aleo, bound, build_result) + + async def claim_swap_output(self, handle: SwapHandle, *, + imports: Optional[dict[str, str]] = None, + account: Any = None) -> AsyncDexCall[ClaimResult]: + self._account(account) + if not handle.swap_id: + raise ValueError("handle.swap_id is not set — recover it from the " + "confirmed request transaction before claiming.") + if not handle.blinding_factor or not handle.blinded_address: + raise ValueError("Claims need handle.blinding_factor and " + "handle.blinded_address (set by swap()).") + out = await self.get_swap_output(handle.swap_id) + await self._ensure([], imports) + inputs = [handle.blinding_factor, handle.blinded_address, handle.swap_id, + out.token_in, out.token_out, + f"{out.amount_out}u128", f"{out.amount_remaining}u128"] + prog = await self._aleo.programs.get(self.program) + bound = prog.functions.claim_swap_output(*inputs) + return AsyncDexCall(self._aleo, bound, + lambda tx_id, _o: ClaimResult(tx_id, out.amount_out, + out.amount_remaining)) diff --git a/shield-swap-sdk/python/aleo_shield_swap/client.py b/shield-swap-sdk/python/aleo_shield_swap/client.py new file mode 100644 index 00000000..8a44e422 --- /dev/null +++ b/shield-swap-sdk/python/aleo_shield_swap/client.py @@ -0,0 +1,603 @@ +"""ShieldSwap — the synchronous shield_swap client, bound to an ``Aleo`` facade. + +Construction wires nothing new: signer, record provider, proving config, and +network all come from the bound client. On-chain reads and writes live +directly on this object; the off-chain DEX API is namespaced under ``.api`` +so a call site always shows whether a value came from the chain or the +service. +""" +from __future__ import annotations + +from typing import Any, Optional + +from aleo.codegen.runtime import parse_plaintext + +from . import _generated as g +from ._core import ( + ensure_programs, + find_position_plaintext, + generate_field_nonce, + generate_swap_nonce, + get_deadline, + normalize_mapping_value, + parse_token_record_info, + resolve_swap_params, + select_token_record, +) +from .api import ApiClient, DEFAULT_API_URL +from .derivations import ( + derive_pool_key as _derive_pool_key, + derive_tick_key as _derive_tick_key, + next_blinded_identity, +) +from .errors import ( + InsufficientRecordsError, + InvalidFeeTierError, + PoolNotFoundError, + PoolNotInitializedError, + SwapOutputNotFinalizedError, +) +from .types import ClaimResult, MintResult, SlotView, SwapHandle, TxResult +from ._calls import DexCall +from .tick_hints import pick_insert_hint +from .tick_math import ( + MAX_TICK, + MIN_TICK, + get_sqrt_price_at_tick, + round_tick_to_spacing, +) + + +class ShieldSwap: + """Typed client for the shield_swap AMM, over an existing facade client. + + :: + + aleo = Aleo(Aleo.HTTPProvider(ENDPOINT)) + aleo.default_account = account + dex = ShieldSwap(aleo) + """ + + def __init__(self, aleo: Any, *, program: str = g.PROGRAM_ID, + api_url: str = DEFAULT_API_URL) -> None: + self._aleo = aleo + self.program = program + self.api = ApiClient(api_url) + + def __repr__(self) -> str: + return f"ShieldSwap(program={self.program!r}, api={self.api.base_url!r})" + + # ── Mapping plumbing ───────────────────────────────────────────────────── + + def _mapping_value(self, mapping: str, key: str) -> Optional[str]: + raw = self._aleo.programs.get(self.program).mapping(mapping).get(key) + return normalize_mapping_value(raw) + + # ── Chain reads ────────────────────────────────────────────────────────── + + def get_pool(self, pool_key: str) -> g.PoolState: + """Static pool configuration (token pair, fee, decimal scales).""" + raw = self._mapping_value("pools", pool_key) + if raw is None: + raise PoolNotFoundError(pool_key) + return g.PoolState.from_plaintext(raw) + + def get_slot(self, pool_key: str) -> SlotView: + """Live trading state (sqrt price, tick, in-range liquidity). + + Raises :class:`PoolNotFoundError` when the pool does not exist, or + :class:`PoolNotInitializedError` when it exists but has no slot yet. + """ + raw = self._mapping_value("slots", pool_key) + if raw is None: + if self._mapping_value("pools", pool_key) is not None: + raise PoolNotInitializedError(pool_key) + raise PoolNotFoundError(pool_key) + return SlotView(g.Slot.from_plaintext(raw)) + + def get_swap_output(self, swap: "SwapHandle | str") -> g.SwapOutput: + """Chain-computed output of a finalized swap request. + + Accepts the :class:`SwapHandle` from ``swap()`` or a bare swap id. + Raises :class:`SwapOutputNotFinalizedError` when the entry is absent — + not finalized yet (retry after a few blocks) or already claimed. + """ + swap_id = swap.swap_id if isinstance(swap, SwapHandle) else swap + if not swap_id: + raise ValueError("SwapHandle has no swap_id yet — wait for the " + "request transaction and recover it first.") + raw = self._mapping_value("swap_outputs", swap_id) + if raw is None: + raise SwapOutputNotFinalizedError(swap_id) + return g.SwapOutput.from_plaintext(raw) + + def is_pool_initialized(self, pool_key: str) -> bool: + raw = self._mapping_value("initialized_pools", pool_key) + return raw is not None and "true" in raw + + # ── Pure derivations (no network) ──────────────────────────────────────── + + def derive_pool_key(self, token0: str, token1: str, fee: int) -> str: + return _derive_pool_key(token0, token1, fee, + network=self._aleo.network_name) + + def derive_tick_key(self, pool_key: str, tick: int) -> str: + return _derive_tick_key(pool_key, tick, network=self._aleo.network_name) + + # ── Balances ───────────────────────────────────────────────────────────── + + def get_private_balances(self, programs: list[str], + account: Any = None) -> dict[str, int]: + """Sum of unspent record amounts per wrapper program (spendable + privately). Requires a configured record provider.""" + provider = self._aleo.record_provider + out: dict[str, int] = {} + for program in programs: + total = 0 + for rec in provider.find(account, program=program, unspent=True): + plaintext = (rec.get("record_plaintext") if isinstance(rec, dict) + else getattr(rec, "record_plaintext", None)) + info = parse_token_record_info(plaintext) if plaintext else None + if info is not None: + total += info["amount"] + out[program] = total + return out + + def get_balances(self, address: Optional[str] = None, + account: Any = None) -> dict[str, dict[str, Any]]: + """Public + private + total per token id, joined via the API's + token registry. Defaults to the bound account's address; returns + only tokens actually held. + + Private balances can only be scanned for the bound account's view + key — when *address* names someone else, ``private`` is 0 for every + token (their records are not scannable) rather than silently mixing + in the caller's own private holdings. + """ + acct = account if account is not None else self._aleo.default_account + addr = address or (str(acct.address) if acct is not None else None) + if addr is None: + raise ValueError("No address: pass address= or set aleo.default_account") + + tokens = self.api.get_tokens() + by_program = {t.wrapper_program: t for t in tokens if t.wrapper_program} + own_address = str(acct.address) if acct is not None else None + private = (self.get_private_balances(list(by_program), account=acct) + if addr == own_address else {p: 0 for p in by_program}) + + out: dict[str, dict[str, Any]] = {} + for bal in self.api.get_public_balances(addr): + entry = out.setdefault(bal.token_id, { + "symbol": bal.symbol, "decimals": bal.decimals, + "public": 0, "private": 0, + }) + entry["public"] += int(bal.balance) + for program, amount in private.items(): + tok = by_program[program] + if amount == 0 and tok.address not in out: + continue + entry = out.setdefault(tok.address, { + "symbol": tok.symbol, "decimals": tok.decimals, + "public": 0, "private": 0, + }) + entry["private"] += amount + for entry in out.values(): + entry["total"] = entry["public"] + entry["private"] + return out + + # ── Writes ─────────────────────────────────────────────────────────────── + + def _account(self, account: Any = None) -> Any: + acct = account if account is not None else self._aleo.default_account + if acct is None: + raise ValueError("No signer: pass account= or set aleo.default_account") + return acct + + def _ensure(self, token_programs: list[str], + imports: Optional[dict[str, str]]) -> None: + """Register the DEX program, its static imports, the involved token + programs, and any *imports* overrides with the snarkVM process.""" + pids = [self.program, *token_programs, *(imports or {})] + ensure_programs(self._aleo, pids, imports) + + def swap( + self, + *, + pool_key: str, + token_in_id: str, + amount_in: int, + slippage_bps: int = 50, + expected_out: Optional[int] = None, + sqrt_price_limit: Optional[int] = None, + deadline_offset_blocks: int = 100, + nonce: Optional[int] = None, + token_in_program: Optional[str] = None, + token_record: Optional[str] = None, + imports: Optional[dict[str, str]] = None, + account: Any = None, + ) -> DexCall[SwapHandle]: + """Request a private swap — phase one of the two-transaction flow. + + Resolves the intent against live pool state, derives a single-use + blinded identity from the signer's view key, selects an unspent token + record (or takes *token_record* verbatim), and returns a prepared + call. The terminal verb (``transact``/``delegate``) returns a + :class:`~aleo_shield_swap.types.SwapHandle` — persist it if the + process might die before the claim. + + Quote first (``dex.api.get_route``) and pass *expected_out*: without + it a spot estimate is used, which ignores fees and price impact. + """ + acct = self._account(account) + pool = self.get_pool(pool_key) + slot = self.get_slot(pool_key) + resolved = resolve_swap_params( + pool=pool, slot=slot, token_in_id=token_in_id, amount_in=amount_in, + slippage_bps=slippage_bps, expected_out=expected_out, + sqrt_price_limit=sqrt_price_limit, + ) + deadline = get_deadline(self._aleo, deadline_offset_blocks) + swap_nonce = nonce if nonce is not None else generate_swap_nonce() + identity = next_blinded_identity(self._aleo, acct, self.program) + + record = token_record + if record is None: + program = token_in_program or self._token_program(token_in_id) + record = select_token_record( + self._aleo, program=program, min_amount=amount_in, + token_id=token_in_id, account=acct, + ) + token_programs = [program] + else: + token_programs = [token_in_program] if token_in_program else [] + # Dynamic dispatch: the prover cannot discover token callees + # statically — register the DEX program and the involved token + # programs with the process before authorization. + self._ensure(token_programs, imports) + + # Input order per the contract's swap entrypoint (mirrors the TS SDK): + # record, blinding slots, then pool/direction/amounts/bounds/timing/tokens. + inputs = [ + record, + identity.blinding_factor, + identity.blinded_address, + pool_key, + resolved.zero_for_one, + f"{amount_in}u128", + f"{resolved.amount_out_min}u128", + f"{resolved.sqrt_price_limit}u128", + f"{swap_nonce}u64", + f"{deadline}u32", + pool.token0, + pool.token1, + ] + bound = self._aleo.programs.get(self.program).functions.swap(*inputs) + + def build_result(tx_id: str, outputs: list[Any]) -> SwapHandle: + swap_id = next( + (o for o in outputs if isinstance(o, str) and o.endswith("field")), + None, + ) + return SwapHandle( + swap_id=swap_id, + blinding_factor=identity.blinding_factor, + blinded_address=identity.blinded_address, + token_in_id=token_in_id, + token_out_id=resolved.token_out_id, + pool_key=pool_key, + amount_in=amount_in, + transaction_id=tx_id, + program=self.program, + ) + + return DexCall(self._aleo, bound, build_result) + + def claim_swap_output( + self, + handle: SwapHandle, + *, + imports: Optional[dict[str, str]] = None, + account: Any = None, + ) -> DexCall[ClaimResult]: + """Claim a private swap's output — phase two of the lifecycle. + + Reads the chain-computed result from ``swap_outputs`` (never an + off-chain service — these amounts gate money movement), proves + ownership of the blinded identity, and prepares ``claim_swap_output``. + The output and any refund arrive as private records owned by the + signer; the mapping entry is consumed. + + Raises :class:`SwapOutputNotFinalizedError` **at prepare time** when + the output is not readable yet (retry after a few blocks) or was + already claimed. + """ + self._account(account) + if not handle.swap_id: + raise ValueError( + "handle.swap_id is not set — recover it from the confirmed " + "request transaction (first public output of the swap " + "transition) before claiming." + ) + if not handle.blinding_factor or not handle.blinded_address: + raise ValueError( + "Claims need handle.blinding_factor and handle.blinded_address " + "(set by swap())." + ) + # Trust-critical read: the amounts the claim moves come from the chain. + out = self.get_swap_output(handle.swap_id) + self._ensure([], imports) + + inputs = [ + handle.blinding_factor, + handle.blinded_address, + handle.swap_id, + out.token_in, + out.token_out, + f"{out.amount_out}u128", + f"{out.amount_remaining}u128", + ] + bound = self._aleo.programs.get(self.program).functions.claim_swap_output(*inputs) + + def build_result(tx_id: str, outputs: list[Any]) -> ClaimResult: + return ClaimResult(tx_id, out.amount_out, out.amount_remaining) + + return DexCall(self._aleo, bound, build_result) + + def _token_program(self, token_id: str) -> str: + """Wrapper program holding a token's records, from the API registry.""" + for tok in self.api.get_tokens(): + if tok.address == token_id and tok.wrapper_program: + return tok.wrapper_program + raise ValueError( + f"Cannot resolve the wrapper program for {token_id} — pass " + "token_in_program= (or token_record=) explicitly." + ) + + # ── Liquidity ──────────────────────────────────────────────────────────── + + def create_pool( + self, + *, + token0_id: str, + token1_id: str, + fee: int, + initial_tick: int, + tick_spacing: Optional[int] = None, + initial_sqrt_price: Optional[int] = None, + imports: Optional[dict[str, str]] = None, + account: Any = None, + ) -> DexCall[TxResult]: + """Create a pool — a single public transaction, no records involved. + + The fee tier must be registered with the program (validated before + submission); tick spacing defaults to the tier's on-chain binding and + the opening price to the tick's sqrt price. + """ + + self._account(account) + if not MIN_TICK <= initial_tick < MAX_TICK: + raise ValueError(f"initial_tick {initial_tick} outside [{MIN_TICK}, {MAX_TICK})") + # The tier must be registered AND enabled (value exactly true) — + # a disabled tier is present in the mapping with value false. + if self._mapping_value("fee_tiers", f"{fee}u16") != "true": + raise InvalidFeeTierError(f"Fee tier {fee} is not registered with {self.program}") + spacing = tick_spacing + if spacing is None: + raw = self._mapping_value("fee_to_tick_spacing", f"{fee}u16") + if raw is None: + raise InvalidFeeTierError( + f"Fee {fee} has no tick spacing bound on chain — pass tick_spacing=" + ) + spacing = int(raw.removesuffix("u32")) + sqrt_price = (initial_sqrt_price if initial_sqrt_price is not None + else get_sqrt_price_at_tick(initial_tick)) + self._ensure([], imports) + + inputs = [ + token0_id, + token1_id, + f"{fee}u16", + f"{sqrt_price}u128", + f"{spacing}u32", + f"{initial_tick}i32", + ] + bound = self._aleo.programs.get(self.program).functions.create_pool(*inputs) + + def build_result(tx_id: str, outputs: list[Any]) -> TxResult: + key = next((o for o in outputs if isinstance(o, str) and o.endswith("field")), None) + return TxResult(position_token_id=key, transaction_id=tx_id) + + return DexCall(self._aleo, bound, build_result) + + def _select_position_record(self, pool_key: str, account: Any) -> str: + """Unspent PositionNFT plaintext for *pool_key* from the shield_swap + program's own records.""" + records = self._aleo.record_provider.find( + account, program=self.program, unspent=True) + plaintext = find_position_plaintext(records, pool_key) + if plaintext is None: + raise InsufficientRecordsError( + f"No unspent PositionNFT record for pool {pool_key} — mint " + "first or pass position_record=." + ) + return plaintext + + def mint( + self, + *, + pool_key: str, + tick_lower: int, + tick_upper: int, + amount0_desired: int, + amount1_desired: int, + amount0_min: int = 0, + amount1_min: int = 0, + token0_program: Optional[str] = None, + token1_program: Optional[str] = None, + token0_record: Optional[str] = None, + token1_record: Optional[str] = None, + tick_lower_hint: Optional[int] = None, + tick_upper_hint: Optional[int] = None, + recipient: Optional[str] = None, + nonce: Optional[str] = None, + imports: Optional[dict[str, str]] = None, + account: Any = None, + ) -> DexCall[MintResult]: + """Mint a concentrated-liquidity position as a private PositionNFT. + + Tick bounds are rounded to the pool's spacing; insert hints derive + from the slot's neighbors unless given explicitly. + """ + + acct = self._account(account) + pool = self.get_pool(pool_key) + slot = self.get_slot(pool_key) + + lo = round_tick_to_spacing(tick_lower, slot.tick_spacing) + hi = round_tick_to_spacing(tick_upper, slot.tick_spacing) + if lo >= hi: + raise ValueError(f"Empty tick range after spacing alignment: [{lo}, {hi})") + + lo_hint = tick_lower_hint if tick_lower_hint is not None else pick_insert_hint(slot, lo) + upper_pred = tick_upper_hint if tick_upper_hint is not None else pick_insert_hint(slot, hi) + # The finalize inserts tick_lower before validating the upper hint, so + # when nothing initialized sits between the bounds, the upper tick's + # predecessor is the just-inserted lower tick. + hi_hint = lo if (tick_upper_hint is None and lo > upper_pred) else upper_pred + + request = g.MintPositionRequest( + pool=pool_key, tick_lower=lo, tick_upper=hi, + amount0_desired=amount0_desired, amount1_desired=amount1_desired, + amount0_min=amount0_min, amount1_min=amount1_min, + tick_lower_hint=lo_hint, tick_upper_hint=hi_hint, + ).to_plaintext() + + record0 = token0_record or select_token_record( + self._aleo, program=token0_program or self._token_program(pool.token0), + min_amount=amount0_desired, token_id=pool.token0, account=acct) + record1 = token1_record or select_token_record( + self._aleo, program=token1_program or self._token_program(pool.token1), + min_amount=amount1_desired, token_id=pool.token1, account=acct) + self._ensure([p for p in (token0_program, token1_program) if p], imports) + + field_nonce = nonce if nonce is not None else generate_field_nonce() + to = recipient or str(acct.address) + + inputs = [field_nonce, record0, record1, to, request, pool.token0, pool.token1] + bound = self._aleo.programs.get(self.program).functions.mint(*inputs) + return DexCall(self._aleo, bound, self._position_result(MintResult)) + + def increase_liquidity( + self, + *, + pool_key: str, + amount0_desired: int, + amount1_desired: int, + amount0_min: int = 0, + amount1_min: int = 0, + token0_program: Optional[str] = None, + token1_program: Optional[str] = None, + token0_record: Optional[str] = None, + token1_record: Optional[str] = None, + position_record: Optional[str] = None, + tick_lower_hint: Optional[int] = None, + tick_upper_hint: Optional[int] = None, + imports: Optional[dict[str, str]] = None, + account: Any = None, + ) -> DexCall[TxResult]: + """Add funds to an existing position (range fixed at mint).""" + + acct = self._account(account) + pool = self.get_pool(pool_key) + slot = self.get_slot(pool_key) + position = position_record or self._select_position_record(pool_key, acct) + + decoded = parse_plaintext(position) + lo_hint = (tick_lower_hint if tick_lower_hint is not None + else pick_insert_hint(slot, int(decoded["tick_lower"]))) + hi_hint = (tick_upper_hint if tick_upper_hint is not None + else pick_insert_hint(slot, int(decoded["tick_upper"]))) + + record0 = token0_record or select_token_record( + self._aleo, program=token0_program or self._token_program(pool.token0), + min_amount=amount0_desired, token_id=pool.token0, account=acct) + record1 = token1_record or select_token_record( + self._aleo, program=token1_program or self._token_program(pool.token1), + min_amount=amount1_desired, token_id=pool.token1, account=acct) + self._ensure([p for p in (token0_program, token1_program) if p], imports) + + inputs = [ + position, record0, record1, + f"{amount0_desired}u128", f"{amount1_desired}u128", + f"{amount0_min}u128", f"{amount1_min}u128", + pool.token0, pool.token1, + f"{lo_hint}i32", f"{hi_hint}i32", + ] + bound = self._aleo.programs.get(self.program).functions.increase_liquidity(*inputs) + return DexCall(self._aleo, bound, self._position_result(TxResult)) + + def decrease_liquidity( + self, + *, + pool_key: str, + liquidity_to_remove: int, + amount0_min: int = 0, + amount1_min: int = 0, + position_record: Optional[str] = None, + imports: Optional[dict[str, str]] = None, + account: Any = None, + ) -> DexCall[TxResult]: + """Remove liquidity from a position; owed amounts become collectable.""" + acct = self._account(account) + position = position_record or self._select_position_record(pool_key, acct) + self._ensure([], imports) + inputs = [position, f"{liquidity_to_remove}u128", + f"{amount0_min}u128", f"{amount1_min}u128"] + bound = self._aleo.programs.get(self.program).functions.decrease_liquidity(*inputs) + return DexCall(self._aleo, bound, self._position_result(TxResult)) + + def collect( + self, + *, + pool_key: str, + amount0_requested: int, + amount1_requested: int, + recipient: Optional[str] = None, + position_record: Optional[str] = None, + imports: Optional[dict[str, str]] = None, + account: Any = None, + ) -> DexCall[TxResult]: + """Collect owed token amounts from a position.""" + acct = self._account(account) + pool = self.get_pool(pool_key) + position = position_record or self._select_position_record(pool_key, acct) + self._ensure([], imports) + to = recipient or str(acct.address) + inputs = [position, f"{amount0_requested}u128", f"{amount1_requested}u128", + pool.token0, pool.token1, to] + bound = self._aleo.programs.get(self.program).functions.collect(*inputs) + # collect's first output is the re-issued PositionNFT record, not a + # public field — there is no positional id to read back. + return DexCall(self._aleo, bound, + lambda tx_id, outputs: TxResult(None, tx_id)) + + def burn( + self, + *, + pool_key: str, + position_record: Optional[str] = None, + account: Any = None, + ) -> DexCall[TxResult]: + """Burn an empty position NFT.""" + acct = self._account(account) + position = position_record or self._select_position_record(pool_key, acct) + bound = self._aleo.programs.get(self.program).functions.burn(position) + return DexCall(self._aleo, bound, self._position_result(TxResult)) + + @staticmethod + def _position_result(result_cls: Any) -> Any: + """Result builder: first public ``field`` output is the position id.""" + def build(tx_id: str, outputs: list[Any]) -> Any: + pid = next((o for o in outputs if isinstance(o, str) and o.endswith("field")), None) + return result_cls(pid, tx_id) + return build diff --git a/shield-swap-sdk/python/aleo_shield_swap/derivations.py b/shield-swap-sdk/python/aleo_shield_swap/derivations.py new file mode 100644 index 00000000..29d624b5 --- /dev/null +++ b/shield-swap-sdk/python/aleo_shield_swap/derivations.py @@ -0,0 +1,179 @@ +"""Pure derivations: pool keys, tick keys, and the blinded identity. + +Ports of the TS SDK's ``utils/keys.ts`` and ``utils/blinding/identity.ts`` +(which themselves mirror the Provable reference client in ``amm-v3-tests``). +Everything here is pure and local — no network I/O; the view key never +leaves the process. Every function is verified against vectors generated +from the TS implementation. +""" +from __future__ import annotations + +from dataclasses import dataclass +from typing import Any + + +def _net(network: str) -> Any: + if network == "testnet": + from aleo import testnet as net + else: + from aleo import mainnet as net + return net + + +def _strip_suffix(literal: str, suffix: str) -> str: + trimmed = literal.strip() + return trimmed[: -len(suffix)] if trimmed.endswith(suffix) else trimmed + + +def _hash_struct(struct: str, network: str) -> str: + """``BHP256::hash_to_field()`` — the contract's key hash.""" + net = _net(network) + pt = net.Plaintext.from_string(struct) + return str(net.BHP256().hash(pt.to_bits_le())) + + +def derive_pool_key(token0: str, token1: str, fee: int, *, network: str = "testnet") -> str: + """Pool key for a token pair and fee tier, without the network. + + Matches the program byte-for-byte: the pair is sorted ascending (as the + contract does) and hashed as ``PoolKey { token0, token1, fee }`` with the + fee as a u16 in pips (3000 = 0.30%). Token ids may carry or omit the + ``field`` suffix. + """ + if not 0 <= fee <= 0xFFFF: + raise ValueError(f"fee must be a u16 (0–65535 pips), got {fee}") + a = int(_strip_suffix(token0, "field")) + b = int(_strip_suffix(token1, "field")) + lo, hi = (a, b) if a <= b else (b, a) + return _hash_struct( + f"{{ token0: {lo}field, token1: {hi}field, fee: {fee}u16 }}", network + ) + + +def derive_tick_key(pool: str, tick: int, *, network: str = "testnet") -> str: + """Key into the ``ticks`` mapping for one tick of a pool. + + Matches the program's ``get_tick_key``: + ``BHP256::hash_to_field(TickKey { pool, tick })`` with the tick as i32. + """ + if not -(2**31) <= tick < 2**31: + raise ValueError(f"tick must be an i32, got {tick}") + p = _strip_suffix(pool, "field") + return _hash_struct(f"{{ pool: {p}field, tick: {tick}i32 }}", network) + + +# ── Blinded identity ───────────────────────────────────────────────────────── +# +# Port of amm-v3-tests src/client/amm-client.ts (feat/q128) via the TS SDK's +# utils/blinding/identity.ts. The domain separators are pinned from the +# reference client; CLAIM_OR_SWAP_DOMAIN must match the literal the program +# hashes in verify_blinded_address. + +BLINDING_FACTOR_DOMAIN = "42815354924796718559205719970686750292466968495484257field" +CLAIM_OR_SWAP_DOMAIN = "11835072102227764468342786961086432175093421716844963782363567713633field" + +DEFAULT_PROGRAM = "shield_swap_v3.aleo" + + +@dataclass(frozen=True) +class BlindedIdentity: + """A single-use blinded identity for one private swap or claim. + + ``blinding_factor`` is secret — whoever holds it can claim the swap's + output; treat it like a key. ``blinded_address`` is public. + """ + + counter: int + blinding_factor: str + blinded_address: str + + +def _program_address_field(net: Any, program: str) -> Any: + """``self.address as field`` — x-coordinate of the program address.""" + return net.Address.from_program_id(program).to_group().to_x_coordinate() + + +def derive_blinding_factor( + view_key_scalar: str, + counter: int, + program: str = DEFAULT_PROGRAM, + *, + network: str = "testnet", +) -> str: + """Blinding factor for one swap/claim, from the view key and a counter. + + ``Poseidon8::hash([program_address, DOMAIN, view_key as field, + counter as field])`` — deterministic, so identities are re-derivable + without storing them. Pure and local; the view key never leaves the + process. + """ + net = _net(network) + addr_field = _program_address_field(net, program) + vk_field = net.Scalar.from_string(view_key_scalar).to_field() + counter_field = net.U32.from_string(f"{counter}u32").to_scalar().to_field() + preimage = [addr_field, net.Field.from_string(BLINDING_FACTOR_DOMAIN), + vk_field, counter_field] + return str(net.Poseidon8().hash(preimage)) + + +def derive_blinded_address( + blinding_factor: str, + signer_address: str, + program: str = DEFAULT_PROGRAM, + *, + network: str = "testnet", +) -> str: + """Public blinded address for a blinding factor and signer. + + ``Poseidon8::hash_to_address_raw([program_address, CLAIM_OR_SWAP_DOMAIN, + signer, blinding_factor])``. The 252-bit little-endian repacking below + emulates snarkVM's ``Plaintext::Array::to_fields_raw`` and is + load-bearing — a one-bit deviation yields an address the program rejects. + """ + net = _net(network) + size_in_data_bits = 252 + + contract_field = _program_address_field(net, program) + signer_field = net.Address.from_string(signer_address).to_group().to_x_coordinate() + + input_bits: list[bool] = [] + for f in (contract_field, net.Field.from_string(CLAIM_OR_SWAP_DOMAIN), + signer_field, net.Field.from_string(blinding_factor)): + input_bits.extend(f.to_bits_le()) + + preimage = [ + net.Field.from_bits_le(input_bits[i:i + size_in_data_bits]) + for i in range(0, len(input_bits), size_in_data_bits) + ] + blinded_group = net.Poseidon8().hash_to_group(preimage) + return str(net.Address.from_group(blinded_group)) + + +def next_blinded_identity( + aleo: Any, + account: Any, + program: str = DEFAULT_PROGRAM, + *, + start_counter: int = 0, + max_scan: int = 64, +) -> BlindedIdentity: + """First unused single-use identity for *account*. + + Derives at ``start_counter, +1, …`` and probes the program's + ``used_blinded_addresses`` mapping until one is free. ``max_scan`` fails + fast when something is systematically wrong (e.g. wrong program). + """ + network = aleo.network_name + scalar = str(account.view_key.to_scalar()) + signer = str(account.address) + mapping = aleo.programs.get(program).mapping("used_blinded_addresses") + for counter in range(start_counter, start_counter + max_scan): + bf = derive_blinding_factor(scalar, counter, program, network=network) + ba = derive_blinded_address(bf, signer, program, network=network) + used = mapping.get(ba) + if used in (None, "", "null", "false"): + return BlindedIdentity(counter, bf, ba) + raise ValueError( + f"No unused blinded address in counters [{start_counter}, " + f"{start_counter + max_scan}) for {program} — wrong program or scan range?" + ) diff --git a/shield-swap-sdk/python/aleo_shield_swap/errors.py b/shield-swap-sdk/python/aleo_shield_swap/errors.py new file mode 100644 index 00000000..24fa1975 --- /dev/null +++ b/shield-swap-sdk/python/aleo_shield_swap/errors.py @@ -0,0 +1,56 @@ +"""Shield-swap error taxonomy — every package error is a ShieldSwapError. + +The base subclasses the facade's :class:`~aleo.AleoError`, so ``except +AleoError`` catches everything from both layers. Facade errors +(``AleoProvingError``, ``TransactionConfirmationTimeout``, …) pass through +untranslated. +""" +from __future__ import annotations + +from aleo import AleoError + + +class ShieldSwapError(AleoError): + """Base class for all shield-swap-sdk errors.""" + + +class SwapOutputNotFinalizedError(ShieldSwapError): + """``swap_outputs[swap_id]`` is empty — the request has not finalized yet + (retry shortly), or the output was already claimed (a claim consumes the + entry, so a second claim of the same handle sees the same absence).""" + + def __init__(self, swap_id: str) -> None: + super().__init__( + f"swap_outputs[{swap_id}] is empty — the request transaction has " + "not finalized yet (retry shortly), or this output was already claimed." + ) + self.swap_id = swap_id + + +class PoolNotFoundError(ShieldSwapError): + def __init__(self, pool_key: str) -> None: + super().__init__(f"Pool {pool_key} does not exist on-chain.") + self.pool_key = pool_key + + +class PoolNotInitializedError(ShieldSwapError): + def __init__(self, pool_key: str) -> None: + super().__init__(f"Pool {pool_key} exists but is not initialized.") + self.pool_key = pool_key + + +class InsufficientRecordsError(ShieldSwapError): + """The record provider found no unspent record covering the amount.""" + + +class InvalidFeeTierError(ShieldSwapError): + """The fee tier is not registered on-chain (checked before submission).""" + + +class DexApiError(ShieldSwapError): + """A DEX REST API request failed; carries the HTTP status and body.""" + + def __init__(self, status: int, body: str) -> None: + super().__init__(f"DEX API error {status}: {body[:200]}") + self.status = status + self.body = body diff --git a/shield-swap-sdk/python/aleo_shield_swap/mcp.py b/shield-swap-sdk/python/aleo_shield_swap/mcp.py new file mode 100644 index 00000000..c94d1d89 --- /dev/null +++ b/shield-swap-sdk/python/aleo_shield_swap/mcp.py @@ -0,0 +1,101 @@ +"""MCP server exposing shield_swap as tools (the ``[mcp]`` extra). + +Run: ``python -m aleo_shield_swap.mcp`` + +Uses the low-level ``mcp.server.Server`` (not FastMCP) so each tool +advertises the exact JSON schema from :func:`~aleo_shield_swap.agent +.shield_swap_tools` — FastMCP infers schemas from handler signatures, which +would collapse every tool to one opaque ``args`` object. Tools run against +the synchronous :class:`~aleo_shield_swap.client.ShieldSwap` (the full verb +surface) in a worker thread, keeping the event loop free. + +Environment: + ALEO_ENDPOINT API origin (default ``https://api.provable.com`` — + the provider derives ``/v2`` reads, ``/prove``, and + ``/scanner`` from it) + ALEO_PRIVATE_KEY Signer for write tools (omit for read-only) + ALEO_NETWORK ``testnet`` (default) or ``mainnet`` + ALEO_E2E_API_KEY / ALEO_E2E_CONSUMER_ID + Delegated-proving + hosted-scanner credentials +""" +from __future__ import annotations + +import json +import os +from typing import Any + +try: + from mcp.server import Server + from mcp.types import TextContent, Tool +except ImportError as exc: # pragma: no cover - env-dependent + raise ImportError( + "The MCP server requires the mcp package — install the extra: " + "pip install 'shield-swap-sdk[mcp]'" + ) from exc + +from .agent import dispatch_tool, shield_swap_tools + + +def tool_definitions() -> list[Tool]: + """The agent tools as MCP ``Tool`` objects with their exact schemas.""" + return [Tool(name=t["name"], description=t["description"], + inputSchema=t["input_schema"]) + for t in shield_swap_tools()] + + +async def call_tool(dex: Any, name: str, arguments: dict[str, Any]) -> list[TextContent]: + """Execute one tool in a worker thread; result as JSON text content.""" + from anyio import to_thread + + result = await to_thread.run_sync(lambda: dispatch_tool(dex, name, arguments)) + return [TextContent(type="text", text=json.dumps(result))] + + +def build_server(dex: Any, *, name: str = "shield-swap") -> Server: + """An MCP server with every agent tool registered against *dex*.""" + server: Server = Server(name) + + @server.list_tools() + async def _list_tools() -> list[Tool]: + return tool_definitions() + + @server.call_tool() + async def _call_tool(tool_name: str, arguments: dict[str, Any]) -> list[TextContent]: + return await call_tool(dex, tool_name, arguments) + + return server + + +def _build_dex() -> Any: + from aleo import Aleo, HTTPProvider + + from .client import ShieldSwap + + endpoint = os.environ.get("ALEO_ENDPOINT", "https://api.provable.com") + network = os.environ.get("ALEO_NETWORK", "testnet") + api_key = os.environ.get("ALEO_E2E_API_KEY") + aleo = Aleo(HTTPProvider(endpoint, network=network, api_key=api_key)) + consumer = os.environ.get("ALEO_E2E_CONSUMER_ID") + if consumer: + aleo.network_client.consumer_id = consumer + pk = os.environ.get("ALEO_PRIVATE_KEY") + if pk: + aleo.default_account = aleo.account.from_private_key(pk) + return ShieldSwap(aleo) + + +def main() -> None: + import anyio + from mcp.server.stdio import stdio_server + + server = build_server(_build_dex()) + + async def _run() -> None: + async with stdio_server() as (read, write): + await server.run(read, write, server.create_initialization_options()) + + anyio.run(_run) + + +if __name__ == "__main__": + main() diff --git a/shield-swap-sdk/python/aleo_shield_swap/tick_hints.py b/shield-swap-sdk/python/aleo_shield_swap/tick_hints.py new file mode 100644 index 00000000..8baa43f4 --- /dev/null +++ b/shield-swap-sdk/python/aleo_shield_swap/tick_hints.py @@ -0,0 +1,29 @@ +"""Insert-hint selection for position ticks (port of utils/tick-hints.ts). + +The contract keeps initialized ticks in a sorted linked list and asserts +``hint.tick < target && hint.next > target`` — the hint must be the target's +predecessor. This derives the hint from the slot's active-range neighbors, +which covers pools with few initialized ticks around the current price. + +Known limitation (inherited from the reference client): when multiple +initialized ticks lie between the slot's neighbors and the target, this does +not walk the list to the true predecessor; a wrong hint reverts on the +contract's assert. An exact walk is possible with ``derive_tick_key`` — +follow-up. +""" +from __future__ import annotations + +from typing import Any + +from .tick_math import MIN_TICK + + +def pick_insert_hint(slot: Any, target_tick: int) -> int: + """Presumed predecessor of *target_tick*, from the slot's neighbors.""" + if slot is None: + return MIN_TICK + if target_tick > slot.tick: + if slot.next_init_above < target_tick: + return int(slot.next_init_above) + return int(slot.next_init_below) + return int(slot.next_init_below) diff --git a/shield-swap-sdk/python/aleo_shield_swap/tick_math.py b/shield-swap-sdk/python/aleo_shield_swap/tick_math.py new file mode 100644 index 00000000..95c896d7 --- /dev/null +++ b/shield-swap-sdk/python/aleo_shield_swap/tick_math.py @@ -0,0 +1,58 @@ +"""Q64 fixed-point tick math, ported from the TS SDK (utils/tick-math.ts), +which mirrors the on-chain tick_math table in shield_swap. The magic +constants ARE the contract's — do not "improve" them; a one-off value +produces prices the finalize asserts against. +""" +from __future__ import annotations + +Q64 = 9223372036854775808 # 2**63 — the contract's sqrt-price scale +MIN_TICK = -400000 +MAX_TICK = 400000 +# sqrt price at MIN_TICK / MAX_TICK — the bounds the swap finalize accepts. +MIN_SQRT_PRICE = 19029805711 +MAX_SQRT_PRICE = 4470386772317930780047134862 + +# sqrt(1.0001^-bit) in Q64 for each power-of-two tick component. +_MAGIC = { + 1: 9222910902837697536, 2: 9222449791875588096, 3: 9221988703967300608, + 4: 9221527639111677952, 8: 9219683610192801792, 16: 9215996658532725760, + 32: 9208627177859081216, 64: 9193905890596798464, 128: 9164533880601766912, + 256: 9106071067403056128, 512: 8990261907820801024, 1024: 8763043369415622656, + 2048: 8325689215117605888, 4096: 7515375139346884608, 8192: 6123667489441693696, + 16384: 4065682634442729984, 32768: 1792161827361994496, 65536: 348228825923923264, + 131072: 13147394978735516, 262144: 18740867660568, 524288: 38079361, +} +_BITS = (4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, + 16384, 32768, 65536, 131072, 262144, 524288) + + +def get_sqrt_price_at_tick(tick: int) -> int: + """Q64 sqrt price at *tick*, matching the contract's table.""" + if tick < MIN_TICK or tick > MAX_TICK: + raise ValueError(f"Tick {tick} out of range [{MIN_TICK}, {MAX_TICK}]") + if tick == 0: + return Q64 + abs_tick = abs(tick) + low_bits = abs_tick & 0x3 + ratio = Q64 if low_bits == 0 else _MAGIC[low_bits] + for bit in _BITS: + if abs_tick & bit: + ratio = (ratio * _MAGIC[bit]) >> 63 + # The table encodes negative ticks; invert for positive ones. + if tick < 0: + return ratio + return (Q64 * Q64) // ratio + + +def round_tick_to_spacing(tick: int, spacing: int) -> int: + """Largest spacing-aligned tick <= *tick* (mint bounds MUST be aligned).""" + return (tick // spacing) * spacing + + +def dust_scale(decimals: int) -> int: + """Divisor the contract normalizes a token's raw amounts by. + + shield_swap accounts in 9-decimal-normalized units: raw inputs must + satisfy ``raw % dust_scale(decimals) == 0`` or the contract rejects them. + """ + return 10 ** (decimals - 9) if decimals > 9 else 1 diff --git a/shield-swap-sdk/python/aleo_shield_swap/types.py b/shield-swap-sdk/python/aleo_shield_swap/types.py new file mode 100644 index 00000000..9d41ef45 --- /dev/null +++ b/shield-swap-sdk/python/aleo_shield_swap/types.py @@ -0,0 +1,108 @@ +"""Semantic layer over the generated wire classes. + +The generated ``_generated.py`` classes carry the wire shapes; the classes +here carry meaning: the persistable swap handle, typed verb results, and a +``Slot`` view with Q64 price math and range helpers. +""" +from __future__ import annotations + +import json +from dataclasses import asdict, dataclass +from decimal import Decimal +from typing import Optional + +from ._generated import Slot +from .tick_math import Q64, round_tick_to_spacing + + +@dataclass(frozen=True) +class SwapHandle: + """The serializable thread between a private swap's two transactions. + + ``swap()`` returns it; ``claim_swap_output()`` consumes it. Persist it + (``to_json``) if the process might die before the claim — + ``blinding_factor`` is the secret that proves ownership at claim time; + treat it like a key. + """ + + swap_id: Optional[str] + blinding_factor: Optional[str] + blinded_address: Optional[str] + token_in_id: str + token_out_id: str + pool_key: str + amount_in: int + transaction_id: str + program: str + + def to_json(self) -> str: + return json.dumps(asdict(self)) + + @classmethod + def from_json(cls, s: str) -> "SwapHandle": + return cls(**json.loads(s)) + + +@dataclass(frozen=True) +class ClaimResult: + """Chain-computed amounts collected by a claim (raw atomic u128).""" + + transaction_id: str + amount_out: int + amount_remaining: int + + +@dataclass(frozen=True) +class MintResult: + position_token_id: Optional[str] + transaction_id: str + + +@dataclass(frozen=True) +class TxResult: + """Result of a liquidity verb; ``position_token_id`` when the verb + re-issues/identifies a position, else ``None``.""" + + position_token_id: Optional[str] + transaction_id: str + + +class SlotView: + """A :class:`~aleo_shield_swap._generated.Slot` plus meaning. + + Delegates every field to the wrapped slot and adds the Q64 fixed-point + conversions callers would otherwise re-derive subtly wrong. + """ + + def __init__(self, slot: Slot) -> None: + self._slot = slot + + def __getattr__(self, name: str): + return getattr(self._slot, name) + + def __repr__(self) -> str: + return f"SlotView({self._slot!r})" + + @property + def raw(self) -> Slot: + return self._slot + + def price(self, decimals0: int, decimals1: int) -> Decimal: + """Spot price of token1 per 1.0 token0, decimal-adjusted. + + ``sqrt_price`` encodes ``sqrt(token1_norm / token0_norm)`` in Q64 + over the contract's 9-decimal-normalized units; the human price + re-applies ``10^(min(d0,9) - min(d1,9))``. + """ + sqrt = Decimal(self._slot.sqrt_price) / Decimal(Q64) + shift = Decimal(10) ** (min(decimals0, 9) - min(decimals1, 9)) + return sqrt * sqrt * shift + + def tick_range(self, width: int) -> tuple[int, int]: + """A spacing-aligned mint range of ±*width* spacings around the + current tick.""" + s = self._slot + return ( + round_tick_to_spacing(s.tick - s.tick_spacing * width, s.tick_spacing), + round_tick_to_spacing(s.tick + s.tick_spacing * width, s.tick_spacing), + ) diff --git a/shield-swap-sdk/tests/__init__.py b/shield-swap-sdk/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/shield-swap-sdk/tests/conftest.py b/shield-swap-sdk/tests/conftest.py new file mode 100644 index 00000000..f8dda67e --- /dev/null +++ b/shield-swap-sdk/tests/conftest.py @@ -0,0 +1,221 @@ +"""Shared stubs: a facade client stub whose shapes mirror the REAL facade. + +Shape fidelity matters — ``TransactionResult.outputs`` is a property, +``decoded()``/``transitions()`` are methods, executions order transitions +child-first with the root LAST, and writes require programs registered with +the process. The stubs model all of that so shape bugs fail here instead +of on testnet. +""" +from __future__ import annotations + +import pytest + +from aleo_shield_swap.tick_math import Q64 + +SLOT_TEXT = ("{ tick: 4055i32, tick_spacing: 60i32, sqrt_price: " + str(Q64) + "u128, " + "fee_protocol: 0u8, liquidity: 1000u128, fee_growth_global0_x_64: 0u128, " + "fee_growth_global1_x_64: 0u128, fee_residual0_x_64: 0u128, " + "fee_residual1_x_64: 0u128, max_liquidity_per_tick: 0u128, " + "protocol_fees0: 0u128, protocol_fees1: 0u128, " + "next_init_below: 3960i32, next_init_above: 4080i32 }") + +POOL_TEXT = ("{ token0: 1field, token1: 2field, fee: 3000u16, enabled: true, " + "scale0: 1000000000u128, scale1: 1u128 }") + +RECORD_TEXT = ("{ owner: aleo1me.private, amount: 2000000000u128.private, " + "_nonce: 7group.public }") + +# Vector account from test_blinding.py — next_blinded_identity derives real values. +VIEW_KEY_SCALAR = "334926304971763782347498121479281870911723639068413954564748091722770623877scalar" +SIGNER = "aleo1rhgdu77hgyqd3xjj8ucu3jj9r2krwz6mnzyd80gncr5fxcwlh5rsvzp9px" +BLINDING_FACTOR_0 = "4588552248780721950435785476596782217652350429588181106944985529417784595808field" +BLINDED_ADDRESS_0 = "aleo1tucdl48jvu54emu9atq3vf0rslwtdpze83zcc2jrc8zxema0r5gq3zd76l" + +PROGRAM_ID = "shield_swap_v3.aleo" + +# A decoy child transition emitting a field output — root-scoped harvesting +# must NEVER pick this up. +CHILD_TRANSITION = {"program": "tok.aleo", "function": "transfer", + "outputs": [{"value": "999field"}]} + + +def _valid_source(pid: str) -> str: + """Minimal REAL parseable program source (register_program_sources parses + it with the actual snarkVM Program type).""" + name = pid.removesuffix(".aleo").replace(".", "_") + return (f"program {name}.aleo;\n" + "function main:\n" + " input r0 as u64.public;\n" + " output r0 as u64.public;\n") + + +class StubAccount: + class _VK: + def to_scalar(self): + return VIEW_KEY_SCALAR + + view_key = _VK() + address = SIGNER + + +class _Mapping: + def __init__(self, values): + self.values = values + + def get(self, key): + return self.values.get(key) + + +class _StubTransition: + def __init__(self, program, function, output_values): + self.program_id = program + self.function_name = function + self._outputs = output_values + + def outputs(self): + return list(self._outputs) + + +class _Tx: + """Shape-faithful TransactionResult stub: outputs is a PROPERTY, + decoded()/transitions() are methods, root transition LAST.""" + + id = "at1stubtx" + raw = object() + + def __init__(self, fn): + self._fn = fn + + @property + def outputs(self): + return [[{"value": "999field"}], [{"value": "77field"}]] + + def decoded(self): + return [dict(CHILD_TRANSITION), + {"program": PROGRAM_ID, "function": self._fn, + "outputs": [{"value": "77field"}]}] + + def transitions(self): + return [_StubTransition("tok.aleo", "transfer", ["999field"]), + _StubTransition(PROGRAM_ID, self._fn, ["77field"])] + + +class _BoundCall: + def __init__(self, recorder, fn, args): + self.program_id = PROGRAM_ID + self.function_name = fn + self._recorder = recorder + self._recorder.last_call = (fn, list(args)) + + def simulate(self, account=None): + return "simulated" + + def build_transaction(self, account=None, **kw): + return _Tx(self.function_name) + + def delegate(self, account=None, **kw): + self._recorder.delegated_fn = self.function_name + return {"transaction_id": "at1delegated"} + + +class _Functions: + def __init__(self, recorder): + self._recorder = recorder + + def __getattr__(self, fn): + def call(*args): + return _BoundCall(self._recorder, fn, args) + return call + + +class _Program: + def __init__(self, recorder, mappings, pid): + self._recorder = recorder + self._mappings = mappings + self.functions = _Functions(recorder) + self.source = _valid_source(pid) + + def mapping(self, name): + return _Mapping(self._mappings.get(name, {})) + + +class _Programs: + def __init__(self, recorder, mappings): + self._recorder = recorder + self._mappings = mappings + + def get(self, pid): + self._recorder.fetched_programs.append(pid) + return _Program(self._recorder, self._mappings, pid) + + +class _Process: + def __init__(self, recorder): + self._recorder = recorder + + def contains_program(self, program_id): + return False + + def add_program(self, program): + self._recorder.registered_programs.append(str(program.id)) + + +class _NetworkClient: + def get_latest_height(self): + return 1000 + + +class _Network: + def __init__(self, recorder): + self._recorder = recorder + + def submit_transaction(self, raw): + self._recorder.submitted.append(raw) + return "at1stubtx" + + def wait_for_transaction(self, tx_id, **kw): + self._recorder.waited.append(tx_id) + return {"status": "confirmed"} + + def get_transaction_object(self, tx_id): + return _Tx(self._recorder.delegated_fn) + + +class _Provider: + def __init__(self, records): + self._records = records + + def find(self, account=None, *, program=None, unspent=True, **_): + return self._records + + +class StubAleo: + """Stubbed facade Aleo: mappings, functions, records, network, process.""" + + network_name = "testnet" + + def __init__(self, mappings=None, records=None): + self.last_call = None + self.delegated_fn = None + self.submitted = [] + self.waited = [] + self.fetched_programs = [] + self.registered_programs = [] + self.programs = _Programs(self, mappings or {}) + self.record_provider = _Provider(records if records is not None + else [{"record_plaintext": RECORD_TEXT}]) + self.network = _Network(self) + self.network_client = _NetworkClient() + self.process = _Process(self) + self.default_account = StubAccount() + + +@pytest.fixture +def stub_aleo(): + return StubAleo(mappings={ + "pools": {"5field": POOL_TEXT}, + "slots": {"5field": SLOT_TEXT}, + "swap_outputs": {}, + "used_blinded_addresses": {}, + "initialized_pools": {"5field": "true"}, + }) diff --git a/shield-swap-sdk/tests/fixtures/pools_response.json b/shield-swap-sdk/tests/fixtures/pools_response.json new file mode 100644 index 00000000..e9350cb3 --- /dev/null +++ b/shield-swap-sdk/tests/fixtures/pools_response.json @@ -0,0 +1,41 @@ +{ + "_source": "GET https://amm-api.dev.provable.com/pools (live capture, 2026-07-13)", + "data": [ + { + "id": "b23af9f7-cd72-4d52-928e-637b9748354c", + "key": "1981234481256911848949989598432010959786505150793860245840256594800529816749field", + "token0": "40965999173564918995621006824189398836596field", + "token1": "185528603099650286599904399730556391637784315808306865395426676field", + "enabled": true, + "creator": "aleo1z3zwzgpgakk89xpknync5rtklkjkyv33g7cvaqe0gku64zs3lv9qyux0qc", + "fee": "5.0000000000000000", + "created_at": "2026-07-10T11:28:09", + "init_tx": "1f025079-439e-48f3-85fa-80751ef82ef9", + "scale0": "1", + "scale1": "1", + "token0_info": { + "id": "2c73efd2-3c96-43d9-9ae0-f319e4fbe8d5", + "address": "40965999173564918995621006824189398836596field", + "name": "Wrapped_USDCx", + "symbol": "wUSDCx", + "decimals": 6, + "image": null, + "wrapper_program": "test_arc20_wusdcx.aleo" + }, + "token1_info": { + "id": "39420ec1-cea5-42e3-b93f-1065ed47fda6", + "address": "185528603099650286599904399730556391637784315808306865395426676field", + "name": "Wrapped_ALEO", + "symbol": "wALEO", + "decimals": 6, + "image": null, + "wrapper_program": "test_arc20_wrapped_credits.aleo" + } + } + ], + "pagination": { + "total": 1, + "limit": 20, + "offset": 0 + } +} \ No newline at end of file diff --git a/shield-swap-sdk/tests/fixtures/programs/shield_swap_v3.aleo b/shield-swap-sdk/tests/fixtures/programs/shield_swap_v3.aleo new file mode 100644 index 00000000..b9340846 --- /dev/null +++ b/shield-swap-sdk/tests/fixtures/programs/shield_swap_v3.aleo @@ -0,0 +1,6439 @@ +// _source: aleo-viem@4a63636 packages/shield-swap/test/fixtures/programs/shield_swap_v3.aleo +import test_shield_swap_multisig_core.aleo; + +program shield_swap_v3.aleo; + +record PositionNFT: + owner as address.private; + token_id as field.private; + token0_id as field.private; + token1_id as field.private; + pool as field.private; + tick_lower as i32.private; + tick_upper as i32.private; + +struct SwapRequest: + pool as field; + zero_for_one as boolean; + amount_in as u128; + amount_out_min as u128; + sqrt_price_limit as u128; + recipient as address; + nonce as u64; + deadline as u32; + +record SwapComplianceRecord: + owner as address.private; + swap_id as field.private; + token_in as field.private; + token_out as field.private; + request as SwapRequest.private; + caller as address.private; + blinded_address as address.private; + +struct SwapHop: + pool as field; + zero_for_one as boolean; + sqrt_price_limit as u128; + +struct SwapMultiHopRequest: + token_in as field; + token_out as field; + amount_in as u128; + amount_out_min as u128; + recipient as address; + hop0 as SwapHop; + hop1 as SwapHop; + hop2 as SwapHop; + hop_count as u8; + nonce as u64; + deadline as u32; + caller as address; + +record MultiHopSwapComplianceRecord: + owner as address.private; + swap_id as field.private; + request as SwapMultiHopRequest.private; + caller as address.private; + blinded_address as address.private; + +struct MintPositionRequest: + pool as field; + tick_lower as i32; + tick_upper as i32; + amount0_desired as u128; + amount1_desired as u128; + amount0_min as u128; + amount1_min as u128; + tick_lower_hint as i32; + tick_upper_hint as i32; + +record MintComplianceRecord: + owner as address.private; + token_id as field.private; + token0_id as field.private; + token1_id as field.private; + request as MintPositionRequest.private; + caller as address.private; + recipient as address.private; + +struct ChecksumEdition: + checksum as [u8; 32u32]; + edition as u16; + +struct PoolState: + token0 as field; + token1 as field; + fee as u16; + enabled as boolean; + scale0 as u128; + scale1 as u128; + +struct Slot: + tick as i32; + tick_spacing as u32; + sqrt_price as u128; + fee_protocol as u8; + liquidity as u128; + fee_growth_global0_x_64 as u128; + fee_growth_global1_x_64 as u128; + fee_residual0_x_64 as u128; + fee_residual1_x_64 as u128; + max_liquidity_per_tick as u128; + protocol_fees0 as u128; + protocol_fees1 as u128; + next_init_below as i32; + next_init_above as i32; + +struct Tick: + pool as field; + liquidity_net as i128; + liquidity_gross as u128; + tick as i32; + fee_growth_outside0_64 as u128; + fee_growth_outside1_64 as u128; + prev as i32; + next as i32; + +struct Position: + token_id as field; + pool as field; + tick_lower as i32; + tick_upper as i32; + liquidity as u128; + fee_growth_inside0_last_64 as u128; + fee_growth_inside1_last_64 as u128; + tokens_owed0 as u128; + tokens_owed1 as u128; + +struct PoolKey: + token0 as field; + token1 as field; + fee as u16; + +struct PairKey: + token0 as field; + token1 as field; + +struct TickKey: + pool as field; + tick as i32; + +struct SwapKey: + pool as field; + zero_for_one as boolean; + amount_in as u128; + sqrt_price_limit as u128; + recipient as address; + nonce as u64; + caller as address; + +struct TokenIDPreimage: + request as MintPositionRequest; + recipient as address; + nonce as field; + +struct SwapIterCfg: + z as boolean; + lim as u128; + fee_pips as u32; + fee_protocol as u8; + slot_fg0 as u128; + slot_fg1 as u128; + +struct SwapIterState: + sp as u128; + rem as u128; + out as u128; + fg as u128; + liq as u128; + tk as i32; + crossed as boolean; + pf as u128; + nb as i32; + na as i32; + resid as u128; + +struct SwapOutput: + recipient as address; + caller as address; + token_in as field; + token_out as field; + amount_out as u128; + amount_remaining as u128; + token_in_1 as field; + amount_remaining_1 as u128; + token_in_2 as field; + amount_remaining_2 as u128; + +mapping pools: + key as field.public; + value as PoolState.public; + +mapping slots: + key as field.public; + value as Slot.public; + +mapping ticks: + key as field.public; + value as Tick.public; + +mapping initialized_pools: + key as field.public; + value as boolean.public; + +mapping tick_spacings: + key as u32.public; + value as boolean.public; + +mapping fee_tiers: + key as u16.public; + value as boolean.public; + +mapping fee_to_tick_spacing: + key as u16.public; + value as u32.public; + +mapping positions: + key as field.public; + value as Position.public; + +mapping swap_outputs: + key as field.public; + value as SwapOutput.public; + +mapping admin: + key as boolean.public; + value as address.public; + +mapping pending_admin: + key as boolean.public; + value as address.public; + +mapping used_blinded_addresses: + key as address.public; + value as boolean.public; + +mapping token_decimals: + key as field.public; + value as u8.public; + +mapping pool_creation_is_open: + key as boolean.public; + value as boolean.public; + +mapping global_paused: + key as boolean.public; + value as boolean.public; + +mapping token_allowed: + key as field.public; + value as boolean.public; + +mapping token_paused: + key as field.public; + value as boolean.public; + +mapping pair_paused: + key as PairKey.public; + value as boolean.public; + +mapping frozen_position: + key as field.public; + value as u32.public; + +function transfer_admin: + input r0 as address.public; + async transfer_admin self.caller r0 into r1; + output r1 as shield_swap_v3.aleo/transfer_admin.future; + +finalize transfer_admin: + input r0 as address.public; + input r1 as address.public; + get admin[true] into r2; + is.eq r0 r2 into r3; + assert.eq r3 true; + set r1 into pending_admin[true]; + +function accept_admin: + async accept_admin self.caller into r0; + output r0 as shield_swap_v3.aleo/accept_admin.future; + +finalize accept_admin: + input r0 as address.public; + get pending_admin[true] into r1; + is.eq r0 r1 into r2; + assert.eq r2 true; + set r0 into admin[true]; + remove pending_admin[true]; + +function add_tick_spacing: + input r0 as u32.public; + async add_tick_spacing self.caller r0 into r1; + output r1 as shield_swap_v3.aleo/add_tick_spacing.future; + +finalize add_tick_spacing: + input r0 as address.public; + input r1 as u32.public; + get admin[true] into r2; + is.eq r0 r2 into r3; + assert.eq r3 true; + gt r1 0u32 into r4; + assert.eq r4 true; + lte r1 400000u32 into r5; + assert.eq r5 true; + set true into tick_spacings[r1]; + +function add_fee_tier: + input r0 as u16.public; + async add_fee_tier self.caller r0 into r1; + output r1 as shield_swap_v3.aleo/add_fee_tier.future; + +finalize add_fee_tier: + input r0 as address.public; + input r1 as u16.public; + get admin[true] into r2; + is.eq r0 r2 into r3; + assert.eq r3 true; + set true into fee_tiers[r1]; + +function bind_fee_to_tick_spacing: + input r0 as u16.public; + input r1 as u32.public; + async bind_fee_to_tick_spacing self.caller r0 r1 into r2; + output r2 as shield_swap_v3.aleo/bind_fee_to_tick_spacing.future; + +finalize bind_fee_to_tick_spacing: + input r0 as address.public; + input r1 as u16.public; + input r2 as u32.public; + get admin[true] into r3; + is.eq r0 r3 into r4; + assert.eq r4 true; + get.or_use fee_tiers[r1] false into r5; + assert.eq r5 true; + get.or_use tick_spacings[r2] false into r6; + assert.eq r6 true; + set r2 into fee_to_tick_spacing[r1]; + +function set_token_decimals: + input r0 as field.public; + input r1 as u8.public; + async set_token_decimals self.caller r1 r0 into r2; + output r2 as shield_swap_v3.aleo/set_token_decimals.future; + +finalize set_token_decimals: + input r0 as address.public; + input r1 as u8.public; + input r2 as field.public; + get admin[true] into r3; + is.eq r0 r3 into r4; + assert.eq r4 true; + lte r1 18u8 into r5; + assert.eq r5 true; + contains token_decimals[r2] into r6; + not r6 into r7; + assert.eq r7 true; + set r1 into token_decimals[r2]; + +function set_pool_enabled: + input r0 as field.public; + input r1 as boolean.public; + async set_pool_enabled self.caller r0 r1 into r2; + output r2 as shield_swap_v3.aleo/set_pool_enabled.future; + +finalize set_pool_enabled: + input r0 as address.public; + input r1 as field.public; + input r2 as boolean.public; + get admin[true] into r3; + is.eq r0 r3 into r4; + assert.eq r4 true; + get pools[r1] into r5; + cast r5.token0 r5.token1 r5.fee r2 r5.scale0 r5.scale1 into r6 as PoolState; + set r6 into pools[r1]; + +function set_pool_creation_is_open: + input r0 as boolean.public; + async set_pool_creation_is_open self.caller r0 into r1; + output r1 as shield_swap_v3.aleo/set_pool_creation_is_open.future; + +finalize set_pool_creation_is_open: + input r0 as address.public; + input r1 as boolean.public; + get admin[true] into r2; + is.eq r0 r2 into r3; + assert.eq r3 true; + set r1 into pool_creation_is_open[true]; + +function set_global_paused: + input r0 as boolean.public; + async set_global_paused self.caller r0 into r1; + output r1 as shield_swap_v3.aleo/set_global_paused.future; + +finalize set_global_paused: + input r0 as address.public; + input r1 as boolean.public; + get admin[true] into r2; + is.eq r0 r2 into r3; + assert.eq r3 true; + set r1 into global_paused[true]; + +function allow_token: + input r0 as field.public; + async allow_token self.caller r0 into r1; + output r1 as shield_swap_v3.aleo/allow_token.future; + +finalize allow_token: + input r0 as address.public; + input r1 as field.public; + get admin[true] into r2; + is.eq r0 r2 into r3; + assert.eq r3 true; + set true into token_allowed[r1]; + +function set_token_paused: + input r0 as field.public; + input r1 as boolean.public; + async set_token_paused self.caller r0 r1 into r2; + output r2 as shield_swap_v3.aleo/set_token_paused.future; + +finalize set_token_paused: + input r0 as address.public; + input r1 as field.public; + input r2 as boolean.public; + get admin[true] into r3; + is.eq r0 r3 into r4; + assert.eq r4 true; + set r2 into token_paused[r1]; + +function set_pair_paused: + input r0 as field.public; + input r1 as field.public; + input r2 as boolean.public; + lt r0 r1 into r3; + ternary r3 r0 r1 into r4; + ternary r3 r1 r0 into r5; + cast r4 r5 into r6 as PairKey; + async set_pair_paused self.caller r6 r2 into r7; + output r7 as shield_swap_v3.aleo/set_pair_paused.future; + +finalize set_pair_paused: + input r0 as address.public; + input r1 as PairKey.public; + input r2 as boolean.public; + get admin[true] into r3; + is.eq r0 r3 into r4; + assert.eq r4 true; + set r2 into pair_paused[r1]; + +view view_sqrt_price_at_tick: + input r0 as i32.public; + gte r0 -873409i32 into r1; + lte r0 873409i32 into r2; + and r1 r2 into r3; + assert.eq r3 true; + lt r0 0i32 into r4; + sub 0i32 r0 into r5; + ternary r4 r5 r0 into r6; + gte r6 0i32 into r7; + assert.eq r7 true; + cast r6 into r8 as u32; + and r8 3u32 into r9; + is.eq r9 0u32 into r10; + is.eq r9 1u32 into r11; + is.eq r9 2u32 into r12; + ternary r12 9222449791875588096u128 9221988703967300608u128 into r13; + ternary r11 9222910902837697536u128 r13 into r14; + ternary r10 9223372036854775808u128 r14 into r15; + and r8 4u32 into r16; + is.neq r16 0u32 into r17; + mul r15 9221527639111677952u128 into r18; + shr r18 63u8 into r19; + ternary r17 r19 r15 into r20; + and r8 8u32 into r21; + is.neq r21 0u32 into r22; + mul r20 9219683610192801792u128 into r23; + shr r23 63u8 into r24; + ternary r22 r24 r20 into r25; + and r8 16u32 into r26; + is.neq r26 0u32 into r27; + mul r25 9215996658532725760u128 into r28; + shr r28 63u8 into r29; + ternary r27 r29 r25 into r30; + and r8 32u32 into r31; + is.neq r31 0u32 into r32; + mul r30 9208627177859081216u128 into r33; + shr r33 63u8 into r34; + ternary r32 r34 r30 into r35; + and r8 64u32 into r36; + is.neq r36 0u32 into r37; + mul r35 9193905890596798464u128 into r38; + shr r38 63u8 into r39; + ternary r37 r39 r35 into r40; + and r8 128u32 into r41; + is.neq r41 0u32 into r42; + mul r40 9164533880601766912u128 into r43; + shr r43 63u8 into r44; + ternary r42 r44 r40 into r45; + and r8 256u32 into r46; + is.neq r46 0u32 into r47; + mul r45 9106071067403056128u128 into r48; + shr r48 63u8 into r49; + ternary r47 r49 r45 into r50; + and r8 512u32 into r51; + is.neq r51 0u32 into r52; + mul r50 8990261907820801024u128 into r53; + shr r53 63u8 into r54; + ternary r52 r54 r50 into r55; + and r8 1024u32 into r56; + is.neq r56 0u32 into r57; + mul r55 8763043369415622656u128 into r58; + shr r58 63u8 into r59; + ternary r57 r59 r55 into r60; + and r8 2048u32 into r61; + is.neq r61 0u32 into r62; + mul r60 8325689215117605888u128 into r63; + shr r63 63u8 into r64; + ternary r62 r64 r60 into r65; + and r8 4096u32 into r66; + is.neq r66 0u32 into r67; + mul r65 7515375139346884608u128 into r68; + shr r68 63u8 into r69; + ternary r67 r69 r65 into r70; + and r8 8192u32 into r71; + is.neq r71 0u32 into r72; + mul r70 6123667489441693696u128 into r73; + shr r73 63u8 into r74; + ternary r72 r74 r70 into r75; + and r8 16384u32 into r76; + is.neq r76 0u32 into r77; + mul r75 4065682634442729984u128 into r78; + shr r78 63u8 into r79; + ternary r77 r79 r75 into r80; + and r8 32768u32 into r81; + is.neq r81 0u32 into r82; + mul r80 1792161827361994496u128 into r83; + shr r83 63u8 into r84; + ternary r82 r84 r80 into r85; + and r8 65536u32 into r86; + is.neq r86 0u32 into r87; + mul r85 348228825923923264u128 into r88; + shr r88 63u8 into r89; + ternary r87 r89 r85 into r90; + and r8 131072u32 into r91; + is.neq r91 0u32 into r92; + mul r90 13147394978735516u128 into r93; + shr r93 63u8 into r94; + ternary r92 r94 r90 into r95; + and r8 262144u32 into r96; + is.neq r96 0u32 into r97; + mul r95 18740867660568u128 into r98; + shr r98 63u8 into r99; + ternary r97 r99 r95 into r100; + and r8 524288u32 into r101; + is.neq r101 0u32 into r102; + mul r100 38079361u128 into r103; + shr r103 63u8 into r104; + ternary r102 r104 r100 into r105; + gt r0 0i32 into r106; + div 85070591730234615865843651857942052864u128 r105 into r107; + ternary r106 r107 r105 into r108; + output r108 as u128.public; + +view view_amounts_for_liquidity: + input r0 as u128.public; + input r1 as u128.public; + input r2 as u128.public; + input r3 as u128.public; + input r4 as boolean.public; + gt r1 r2 into r5; + ternary r5 r2 r1 into r6; + ternary r5 r1 r2 into r7; + lte r0 r6 into r8; + gt r6 r7 into r9; + ternary r9 r7 r6 into r10; + ternary r9 r6 r7 into r11; + and r3 18446744073709551615u128 into r12; + shr r3 64u8 into r13; + mul r12 9223372036854775808u128 into r14; + mul r13 9223372036854775808u128 into r15; + and r14 18446744073709551615u128 into r16; + shr r14 64u8 into r17; + and r15 18446744073709551615u128 into r18; + add r17 r18 into r19; + and r19 18446744073709551615u128 into r20; + shr r19 64u8 into r21; + shr r15 64u8 into r22; + add r22 r21 into r23; + and r23 18446744073709551615u128 into r24; + shr r23 64u8 into r25; + shl r20 64u8 into r26; + add r26 r16 into r27; + shl r25 64u8 into r28; + add r28 r24 into r29; + lt r29 r10 into r30; + assert.eq r30 true; + shr r27 96u8 into r31; + and r31 4294967295u128 into r32; + shl r29 32u8 into r33; + add r33 r32 into r34; + div r34 r10 into r35; + rem r34 r10 into r36; + shr r27 64u8 into r37; + and r37 4294967295u128 into r38; + shl r36 32u8 into r39; + add r39 r38 into r40; + shl r35 32u8 into r41; + div r40 r10 into r42; + add r41 r42 into r43; + rem r40 r10 into r44; + shr r27 32u8 into r45; + and r45 4294967295u128 into r46; + shl r44 32u8 into r47; + add r47 r46 into r48; + shl r43 32u8 into r49; + div r48 r10 into r50; + add r49 r50 into r51; + rem r48 r10 into r52; + shr r27 0u8 into r53; + and r53 4294967295u128 into r54; + shl r52 32u8 into r55; + add r55 r54 into r56; + shl r51 32u8 into r57; + div r56 r10 into r58; + add r57 r58 into r59; + rem r56 r10 into r60; + gt r60 0u128 into r61; + and r4 r61 into r62; + add r59 1u128 into r63; + ternary r62 r63 r59 into r64; + not r4 into r65; + add r17 r18 into r66; + and r66 18446744073709551615u128 into r67; + shr r66 64u8 into r68; + add r22 r68 into r69; + and r69 18446744073709551615u128 into r70; + shr r69 64u8 into r71; + shl r67 64u8 into r72; + add r72 r16 into r73; + shl r71 64u8 into r74; + add r74 r70 into r75; + lt r75 r11 into r76; + assert.eq r76 true; + shr r73 96u8 into r77; + and r77 4294967295u128 into r78; + shl r75 32u8 into r79; + add r79 r78 into r80; + div r80 r11 into r81; + rem r80 r11 into r82; + shr r73 64u8 into r83; + and r83 4294967295u128 into r84; + shl r82 32u8 into r85; + add r85 r84 into r86; + shl r81 32u8 into r87; + div r86 r11 into r88; + add r87 r88 into r89; + rem r86 r11 into r90; + shr r73 32u8 into r91; + and r91 4294967295u128 into r92; + shl r90 32u8 into r93; + add r93 r92 into r94; + shl r89 32u8 into r95; + div r94 r11 into r96; + add r95 r96 into r97; + rem r94 r11 into r98; + shr r73 0u8 into r99; + and r99 4294967295u128 into r100; + shl r98 32u8 into r101; + add r101 r100 into r102; + shl r97 32u8 into r103; + div r102 r11 into r104; + add r103 r104 into r105; + rem r102 r11 into r106; + gt r106 0u128 into r107; + and r65 r107 into r108; + add r105 1u128 into r109; + ternary r108 r109 r105 into r110; + gte r64 r110 into r111; + ternary r111 r64 r110 into r112; + ternary r111 r110 r64 into r113; + sub r112 r113 into r114; + ternary r111 r114 0u128 into r115; + lt r0 r7 into r116; + gt r0 r7 into r117; + ternary r117 r7 r0 into r118; + ternary r117 r0 r7 into r119; + shl r71 64u8 into r120; + add r120 r70 into r121; + lt r121 r118 into r122; + assert.eq r122 true; + shl r121 32u8 into r123; + add r123 r78 into r124; + div r124 r118 into r125; + rem r124 r118 into r126; + shl r126 32u8 into r127; + add r127 r84 into r128; + shl r125 32u8 into r129; + div r128 r118 into r130; + add r129 r130 into r131; + rem r128 r118 into r132; + shl r132 32u8 into r133; + add r133 r92 into r134; + shl r131 32u8 into r135; + div r134 r118 into r136; + add r135 r136 into r137; + rem r134 r118 into r138; + shl r138 32u8 into r139; + add r139 r100 into r140; + shl r137 32u8 into r141; + div r140 r118 into r142; + add r141 r142 into r143; + rem r140 r118 into r144; + gt r144 0u128 into r145; + and r4 r145 into r146; + add r143 1u128 into r147; + ternary r146 r147 r143 into r148; + lt r121 r119 into r149; + assert.eq r149 true; + shl r121 32u8 into r150; + add r150 r78 into r151; + div r151 r119 into r152; + rem r151 r119 into r153; + shl r153 32u8 into r154; + add r154 r84 into r155; + shl r152 32u8 into r156; + div r155 r119 into r157; + add r156 r157 into r158; + rem r155 r119 into r159; + shl r159 32u8 into r160; + add r160 r92 into r161; + shl r158 32u8 into r162; + div r161 r119 into r163; + add r162 r163 into r164; + rem r161 r119 into r165; + shl r165 32u8 into r166; + add r166 r100 into r167; + shl r164 32u8 into r168; + div r167 r119 into r169; + add r168 r169 into r170; + rem r167 r119 into r171; + gt r171 0u128 into r172; + and r65 r172 into r173; + add r170 1u128 into r174; + ternary r173 r174 r170 into r175; + gte r148 r175 into r176; + ternary r176 r148 r175 into r177; + ternary r176 r175 r148 into r178; + sub r177 r178 into r179; + ternary r176 r179 0u128 into r180; + gt r6 r0 into r181; + ternary r181 r0 r6 into r182; + ternary r181 r6 r0 into r183; + sub r183 r182 into r184; + and r184 18446744073709551615u128 into r185; + shr r184 64u8 into r186; + mul r12 r185 into r187; + mul r12 r186 into r188; + mul r13 r185 into r189; + mul r13 r186 into r190; + and r187 18446744073709551615u128 into r191; + shr r187 64u8 into r192; + and r188 18446744073709551615u128 into r193; + add r192 r193 into r194; + and r189 18446744073709551615u128 into r195; + add r194 r195 into r196; + and r196 18446744073709551615u128 into r197; + shr r196 64u8 into r198; + shr r188 64u8 into r199; + shr r189 64u8 into r200; + add r199 r200 into r201; + and r190 18446744073709551615u128 into r202; + add r201 r202 into r203; + add r203 r198 into r204; + and r204 18446744073709551615u128 into r205; + shr r204 64u8 into r206; + shr r190 64u8 into r207; + add r207 r206 into r208; + shl r197 64u8 into r209; + add r209 r191 into r210; + shl r208 64u8 into r211; + add r211 r205 into r212; + shl r212 65u8 into r213; + shr r210 63u8 into r214; + add r213 r214 into r215; + and r210 9223372036854775807u128 into r216; + gt r216 0u128 into r217; + and r4 r217 into r218; + add r215 1u128 into r219; + ternary r218 r219 r215 into r220; + gt r6 r7 into r221; + ternary r221 r7 r6 into r222; + ternary r221 r6 r7 into r223; + sub r223 r222 into r224; + and r224 18446744073709551615u128 into r225; + shr r224 64u8 into r226; + mul r12 r225 into r227; + mul r12 r226 into r228; + mul r13 r225 into r229; + mul r13 r226 into r230; + and r227 18446744073709551615u128 into r231; + shr r227 64u8 into r232; + and r228 18446744073709551615u128 into r233; + add r232 r233 into r234; + and r229 18446744073709551615u128 into r235; + add r234 r235 into r236; + and r236 18446744073709551615u128 into r237; + shr r236 64u8 into r238; + shr r228 64u8 into r239; + shr r229 64u8 into r240; + add r239 r240 into r241; + and r230 18446744073709551615u128 into r242; + add r241 r242 into r243; + add r243 r238 into r244; + and r244 18446744073709551615u128 into r245; + shr r244 64u8 into r246; + shr r230 64u8 into r247; + add r247 r246 into r248; + shl r237 64u8 into r249; + add r249 r231 into r250; + shl r248 64u8 into r251; + add r251 r245 into r252; + shl r252 65u8 into r253; + shr r250 63u8 into r254; + add r253 r254 into r255; + and r250 9223372036854775807u128 into r256; + gt r256 0u128 into r257; + and r4 r257 into r258; + add r255 1u128 into r259; + ternary r258 r259 r255 into r260; + ternary r116 r180 0u128 into r261; + ternary r116 r220 r260 into r262; + ternary r8 r115 r261 into r263; + ternary r8 0u128 r262 into r264; + output r263 as u128.public; + output r264 as u128.public; + +function freeze_position: + input r0 as field.public; + async freeze_position self.caller r0 into r1; + output r1 as shield_swap_v3.aleo/freeze_position.future; + +finalize freeze_position: + input r0 as address.public; + input r1 as field.public; + get admin[true] into r2; + is.eq r0 r2 into r3; + assert.eq r3 true; + contains positions[r1] into r4; + assert.eq r4 true; + contains frozen_position[r1] into r5; + not r5 into r6; + assert.eq r6 true; + get positions[r1] into r7; + gt r7.liquidity 0u128 into r8; + branch.eq r8 false to end_then_0_0; + get positions[r1] into r9; + get slots[r9.pool] into r10; + call view_sqrt_price_at_tick r9.tick_lower into r11; + call view_sqrt_price_at_tick r9.tick_upper into r12; + call view_amounts_for_liquidity r10.sqrt_price r11 r12 r7.liquidity false into r13 r14; + cast r9.pool r9.tick_lower into r15 as TickKey; + hash.bhp256 r15 into r16 as field; + cast r9.pool r9.tick_upper into r17 as TickKey; + hash.bhp256 r17 into r18 as field; + get ticks[r16] into r19; + get ticks[r18] into r20; + gt r19.liquidity_gross 0u128 into r21; + gt r20.liquidity_gross 0u128 into r22; + sub r19.liquidity_gross r7.liquidity into r23; + sub r20.liquidity_gross r7.liquidity into r24; + is.eq r23 0u128 into r25; + and r21 r25 into r26; + is.eq r24 0u128 into r27; + and r22 r27 into r28; + cast r7.liquidity into r29 as i128; + sub r19.liquidity_net r29 into r30; + cast r19.pool r30 r23 r19.tick r19.fee_growth_outside0_64 r19.fee_growth_outside1_64 r19.prev r19.next into r31 as Tick; + set r31 into ticks[r16]; + branch.eq r26 false to end_then_1_2; + cast r9.pool r19.prev into r32 as TickKey; + hash.bhp256 r32 into r33 as field; + get ticks[r33] into r34; + cast r34.pool r34.liquidity_net r34.liquidity_gross r34.tick r34.fee_growth_outside0_64 r34.fee_growth_outside1_64 r34.prev r19.next into r35 as Tick; + set r35 into ticks[r33]; + cast r9.pool r19.next into r36 as TickKey; + hash.bhp256 r36 into r37 as field; + get ticks[r37] into r38; + cast r38.pool r38.liquidity_net r38.liquidity_gross r38.tick r38.fee_growth_outside0_64 r38.fee_growth_outside1_64 r19.prev r38.next into r39 as Tick; + set r39 into ticks[r37]; + branch.eq true true to end_otherwise_1_3; + position end_then_1_2; + position end_otherwise_1_3; + get ticks[r18] into r40; + cast r7.liquidity into r41 as i128; + add r40.liquidity_net r41 into r42; + cast r40.pool r42 r24 r40.tick r40.fee_growth_outside0_64 r40.fee_growth_outside1_64 r40.prev r40.next into r43 as Tick; + set r43 into ticks[r18]; + branch.eq r28 false to end_then_1_4; + cast r9.pool r40.prev into r44 as TickKey; + hash.bhp256 r44 into r45 as field; + get ticks[r45] into r46; + cast r46.pool r46.liquidity_net r46.liquidity_gross r46.tick r46.fee_growth_outside0_64 r46.fee_growth_outside1_64 r46.prev r40.next into r47 as Tick; + set r47 into ticks[r45]; + cast r9.pool r40.next into r48 as TickKey; + hash.bhp256 r48 into r49 as field; + get ticks[r49] into r50; + cast r50.pool r50.liquidity_net r50.liquidity_gross r50.tick r50.fee_growth_outside0_64 r50.fee_growth_outside1_64 r40.prev r50.next into r51 as Tick; + set r51 into ticks[r49]; + branch.eq true true to end_otherwise_1_5; + position end_then_1_4; + position end_otherwise_1_5; + get ticks[r16] into r52; + get ticks[r18] into r53; + gte r10.tick r52.tick into r54; + gte r10.fee_growth_global0_x_64 r52.fee_growth_outside0_64 into r55; + ternary r55 r10.fee_growth_global0_x_64 r52.fee_growth_outside0_64 into r56; + ternary r55 r52.fee_growth_outside0_64 r10.fee_growth_global0_x_64 into r57; + sub r56 r57 into r58; + gt r58 0u128 into r59; + ternary r59 r58 1u128 into r60; + sub 340282366920938463463374607431768211455u128 r60 into r61; + add r61 1u128 into r62; + ternary r55 r58 r62 into r63; + gte r10.fee_growth_global1_x_64 r52.fee_growth_outside1_64 into r64; + ternary r64 r10.fee_growth_global1_x_64 r52.fee_growth_outside1_64 into r65; + ternary r64 r52.fee_growth_outside1_64 r10.fee_growth_global1_x_64 into r66; + sub r65 r66 into r67; + gt r67 0u128 into r68; + ternary r68 r67 1u128 into r69; + sub 340282366920938463463374607431768211455u128 r69 into r70; + add r70 1u128 into r71; + ternary r64 r67 r71 into r72; + ternary r54 r52.fee_growth_outside0_64 r63 into r73; + ternary r54 r52.fee_growth_outside1_64 r72 into r74; + lt r10.tick r53.tick into r75; + gte r10.fee_growth_global0_x_64 r53.fee_growth_outside0_64 into r76; + ternary r76 r10.fee_growth_global0_x_64 r53.fee_growth_outside0_64 into r77; + ternary r76 r53.fee_growth_outside0_64 r10.fee_growth_global0_x_64 into r78; + sub r77 r78 into r79; + gt r79 0u128 into r80; + ternary r80 r79 1u128 into r81; + sub 340282366920938463463374607431768211455u128 r81 into r82; + add r82 1u128 into r83; + ternary r76 r79 r83 into r84; + gte r10.fee_growth_global1_x_64 r53.fee_growth_outside1_64 into r85; + ternary r85 r10.fee_growth_global1_x_64 r53.fee_growth_outside1_64 into r86; + ternary r85 r53.fee_growth_outside1_64 r10.fee_growth_global1_x_64 into r87; + sub r86 r87 into r88; + gt r88 0u128 into r89; + ternary r89 r88 1u128 into r90; + sub 340282366920938463463374607431768211455u128 r90 into r91; + add r91 1u128 into r92; + ternary r85 r88 r92 into r93; + ternary r75 r53.fee_growth_outside0_64 r84 into r94; + ternary r75 r53.fee_growth_outside1_64 r93 into r95; + gte r10.fee_growth_global0_x_64 r73 into r96; + ternary r96 r10.fee_growth_global0_x_64 r73 into r97; + ternary r96 r73 r10.fee_growth_global0_x_64 into r98; + sub r97 r98 into r99; + gt r99 0u128 into r100; + ternary r100 r99 1u128 into r101; + sub 340282366920938463463374607431768211455u128 r101 into r102; + add r102 1u128 into r103; + ternary r96 r99 r103 into r104; + gte r104 r94 into r105; + ternary r105 r104 r94 into r106; + ternary r105 r94 r104 into r107; + sub r106 r107 into r108; + gt r108 0u128 into r109; + ternary r109 r108 1u128 into r110; + sub 340282366920938463463374607431768211455u128 r110 into r111; + add r111 1u128 into r112; + ternary r105 r108 r112 into r113; + gte r10.fee_growth_global1_x_64 r74 into r114; + ternary r114 r10.fee_growth_global1_x_64 r74 into r115; + ternary r114 r74 r10.fee_growth_global1_x_64 into r116; + sub r115 r116 into r117; + gt r117 0u128 into r118; + ternary r118 r117 1u128 into r119; + sub 340282366920938463463374607431768211455u128 r119 into r120; + add r120 1u128 into r121; + ternary r114 r117 r121 into r122; + gte r122 r95 into r123; + ternary r123 r122 r95 into r124; + ternary r123 r95 r122 into r125; + sub r124 r125 into r126; + gt r126 0u128 into r127; + ternary r127 r126 1u128 into r128; + sub 340282366920938463463374607431768211455u128 r128 into r129; + add r129 1u128 into r130; + ternary r123 r126 r130 into r131; + gte r113 r9.fee_growth_inside0_last_64 into r132; + ternary r132 r113 r9.fee_growth_inside0_last_64 into r133; + ternary r132 r9.fee_growth_inside0_last_64 r113 into r134; + sub r133 r134 into r135; + gt r135 0u128 into r136; + ternary r136 r135 1u128 into r137; + sub 340282366920938463463374607431768211455u128 r137 into r138; + add r138 1u128 into r139; + ternary r132 r135 r139 into r140; + and r140 18446744073709551615u128 into r141; + shr r140 64u8 into r142; + and r9.liquidity 18446744073709551615u128 into r143; + shr r9.liquidity 64u8 into r144; + mul r141 r143 into r145; + mul r141 r144 into r146; + mul r142 r143 into r147; + mul r142 r144 into r148; + and r145 18446744073709551615u128 into r149; + shr r145 64u8 into r150; + and r146 18446744073709551615u128 into r151; + add r150 r151 into r152; + and r147 18446744073709551615u128 into r153; + add r152 r153 into r154; + and r154 18446744073709551615u128 into r155; + shr r154 64u8 into r156; + shr r146 64u8 into r157; + shr r147 64u8 into r158; + add r157 r158 into r159; + and r148 18446744073709551615u128 into r160; + add r159 r160 into r161; + add r161 r156 into r162; + and r162 18446744073709551615u128 into r163; + shr r162 64u8 into r164; + shr r148 64u8 into r165; + add r165 r164 into r166; + shl r155 64u8 into r167; + add r167 r149 into r168; + shl r166 64u8 into r169; + add r169 r163 into r170; + shl r170 65u8 into r171; + shr r168 63u8 into r172; + add r171 r172 into r173; + add r9.tokens_owed0 r173 into r174; + add r174 r13 into r175; + gte r131 r9.fee_growth_inside1_last_64 into r176; + ternary r176 r131 r9.fee_growth_inside1_last_64 into r177; + ternary r176 r9.fee_growth_inside1_last_64 r131 into r178; + sub r177 r178 into r179; + gt r179 0u128 into r180; + ternary r180 r179 1u128 into r181; + sub 340282366920938463463374607431768211455u128 r181 into r182; + add r182 1u128 into r183; + ternary r176 r179 r183 into r184; + and r184 18446744073709551615u128 into r185; + shr r184 64u8 into r186; + and r9.liquidity 18446744073709551615u128 into r187; + shr r9.liquidity 64u8 into r188; + mul r185 r187 into r189; + mul r185 r188 into r190; + mul r186 r187 into r191; + mul r186 r188 into r192; + and r189 18446744073709551615u128 into r193; + shr r189 64u8 into r194; + and r190 18446744073709551615u128 into r195; + add r194 r195 into r196; + and r191 18446744073709551615u128 into r197; + add r196 r197 into r198; + and r198 18446744073709551615u128 into r199; + shr r198 64u8 into r200; + shr r190 64u8 into r201; + shr r191 64u8 into r202; + add r201 r202 into r203; + and r192 18446744073709551615u128 into r204; + add r203 r204 into r205; + add r205 r200 into r206; + and r206 18446744073709551615u128 into r207; + shr r206 64u8 into r208; + shr r192 64u8 into r209; + add r209 r208 into r210; + shl r199 64u8 into r211; + add r211 r193 into r212; + shl r210 64u8 into r213; + add r213 r207 into r214; + shl r214 65u8 into r215; + shr r212 63u8 into r216; + add r215 r216 into r217; + add r9.tokens_owed1 r217 into r218; + add r218 r14 into r219; + sub r9.liquidity r7.liquidity into r220; + cast r1 r9.pool r9.tick_lower r9.tick_upper r220 r113 r131 r175 r219 into r221 as Position; + set r221 into positions[r1]; + is.eq r10.next_init_below r9.tick_lower into r222; + and r26 r222 into r223; + ternary r223 r19.prev r10.next_init_below into r224; + is.eq r10.next_init_above r9.tick_lower into r225; + and r26 r225 into r226; + ternary r226 r19.next r10.next_init_above into r227; + is.eq r224 r9.tick_upper into r228; + and r28 r228 into r229; + ternary r229 r40.prev r224 into r230; + is.eq r227 r9.tick_upper into r231; + and r28 r231 into r232; + ternary r232 r40.next r227 into r233; + gte r10.tick r9.tick_lower into r234; + lt r10.tick r9.tick_upper into r235; + and r234 r235 into r236; + ternary r236 r7.liquidity 0u128 into r237; + sub r10.liquidity r237 into r238; + cast r10.tick r10.tick_spacing r10.sqrt_price r10.fee_protocol r238 r10.fee_growth_global0_x_64 r10.fee_growth_global1_x_64 r10.fee_residual0_x_64 r10.fee_residual1_x_64 r10.max_liquidity_per_tick r10.protocol_fees0 r10.protocol_fees1 r230 r233 into r239 as Slot; + set r239 into slots[r9.pool]; + branch.eq r26 false to end_then_1_6; + remove ticks[r16]; + branch.eq true true to end_otherwise_1_7; + position end_then_1_6; + position end_otherwise_1_7; + branch.eq r28 false to end_then_1_8; + remove ticks[r18]; + branch.eq true true to end_otherwise_1_9; + position end_then_1_8; + position end_otherwise_1_9; + branch.eq true true to end_otherwise_0_1; + position end_then_0_0; + position end_otherwise_0_1; + set block.height into frozen_position[r1]; + +function unfreeze_position: + input r0 as field.public; + async unfreeze_position self.caller r0 into r1; + output r1 as shield_swap_v3.aleo/unfreeze_position.future; + +finalize unfreeze_position: + input r0 as address.public; + input r1 as field.public; + get admin[true] into r2; + is.eq r0 r2 into r3; + assert.eq r3 true; + contains frozen_position[r1] into r4; + assert.eq r4 true; + remove frozen_position[r1]; + +function set_fee_protocol: + input r0 as field.public; + input r1 as u8.public; + async set_fee_protocol self.caller r0 r1 into r2; + output r2 as shield_swap_v3.aleo/set_fee_protocol.future; + +finalize set_fee_protocol: + input r0 as address.public; + input r1 as field.public; + input r2 as u8.public; + get admin[true] into r3; + is.eq r0 r3 into r4; + assert.eq r4 true; + is.eq r2 0u8 into r5; + gte r2 4u8 into r6; + lte r2 10u8 into r7; + and r6 r7 into r8; + or r5 r8 into r9; + assert.eq r9 true; + get slots[r1] into r10; + cast r10.tick r10.tick_spacing r10.sqrt_price r2 r10.liquidity r10.fee_growth_global0_x_64 r10.fee_growth_global1_x_64 r10.fee_residual0_x_64 r10.fee_residual1_x_64 r10.max_liquidity_per_tick r10.protocol_fees0 r10.protocol_fees1 r10.next_init_below r10.next_init_above into r11 as Slot; + set r11 into slots[r1]; + +function collect_protocol: + input r0 as field.public; + input r1 as u128.public; + input r2 as u128.public; + input r3 as field.public; + input r4 as field.public; + input r5 as address.public; + assert.neq r5 shield_swap_v3.aleo; + call.dynamic r3 'aleo' 'transfer_public' with r5 r1 (as address.public u128.public) into r6 (as dynamic.future); + call.dynamic r4 'aleo' 'transfer_public' with r5 r2 (as address.public u128.public) into r7 (as dynamic.future); + async collect_protocol r6 r7 self.caller r0 r1 r2 r3 r4 into r8; + output r8 as shield_swap_v3.aleo/collect_protocol.future; + +finalize collect_protocol: + input r0 as dynamic.future; + input r1 as dynamic.future; + input r2 as address.public; + input r3 as field.public; + input r4 as u128.public; + input r5 as u128.public; + input r6 as field.public; + input r7 as field.public; + get admin[true] into r8; + is.eq r2 r8 into r9; + assert.eq r9 true; + get pools[r3] into r10; + is.eq r10.token0 r6 into r11; + is.eq r10.token1 r7 into r12; + and r11 r12 into r13; + assert.eq r13 true; + get slots[r3] into r14; + rem r4 r10.scale0 into r15; + is.eq r15 0u128 into r16; + rem r5 r10.scale1 into r17; + is.eq r17 0u128 into r18; + and r16 r18 into r19; + assert.eq r19 true; + div r4 r10.scale0 into r20; + div r5 r10.scale1 into r21; + lte r20 r14.protocol_fees0 into r22; + assert.eq r22 true; + lte r21 r14.protocol_fees1 into r23; + assert.eq r23 true; + await r0; + await r1; + sub r14.protocol_fees0 r20 into r24; + sub r14.protocol_fees1 r21 into r25; + cast r14.tick r14.tick_spacing r14.sqrt_price r14.fee_protocol r14.liquidity r14.fee_growth_global0_x_64 r14.fee_growth_global1_x_64 r14.fee_residual0_x_64 r14.fee_residual1_x_64 r14.max_liquidity_per_tick r24 r25 r14.next_init_below r14.next_init_above into r26 as Slot; + set r26 into slots[r3]; + +function create_pool: + input r0 as field.public; + input r1 as field.public; + input r2 as u16.public; + input r3 as u128.public; + input r4 as u32.public; + input r5 as i32.public; + lt r0 r1 into r6; + ternary r6 r0 r1 into r7; + ternary r6 r1 r0 into r8; + cast r7 r8 r2 into r9 as PoolKey; + hash.bhp256 r9 into r10 as field; + async create_pool self.caller r0 r1 r2 r3 r4 r5 into r11; + output r10 as field.public; + output self.signer as address.public; + output r11 as shield_swap_v3.aleo/create_pool.future; + +finalize create_pool: + input r0 as address.public; + input r1 as field.public; + input r2 as field.public; + input r3 as u16.public; + input r4 as u128.public; + input r5 as u32.public; + input r6 as i32.public; + get.or_use pool_creation_is_open[true] false into r7; + get admin[true] into r8; + is.eq r0 r8 into r9; + or r7 r9 into r10; + assert.eq r10 true; + get.or_use token_allowed[r1] false into r11; + assert.eq r11 true; + get.or_use token_allowed[r2] false into r12; + assert.eq r12 true; + get.or_use global_paused[true] false into r13; + not r13 into r14; + assert.eq r14 true; + get token_decimals[r1] into r15; + get token_decimals[r2] into r16; + lt r1 r2 into r17; + ternary r17 r1 r2 into r18; + ternary r17 r2 r1 into r19; + lt r1 r2 into r20; + ternary r20 r15 r16 into r21; + ternary r20 r16 r15 into r22; + gt r21 9u8 into r23; + ternary r23 r21 9u8 into r24; + sub r24 9u8 into r25; + lte r25 29u8 into r26; + assert.eq r26 true; + lt 0u8 r25 into r27; + ternary r27 10u128 1u128 into r28; + lt 1u8 r25 into r29; + mul r28 10u128 into r30; + ternary r29 r30 r28 into r31; + lt 2u8 r25 into r32; + mul r31 10u128 into r33; + ternary r32 r33 r31 into r34; + lt 3u8 r25 into r35; + mul r34 10u128 into r36; + ternary r35 r36 r34 into r37; + lt 4u8 r25 into r38; + mul r37 10u128 into r39; + ternary r38 r39 r37 into r40; + lt 5u8 r25 into r41; + mul r40 10u128 into r42; + ternary r41 r42 r40 into r43; + lt 6u8 r25 into r44; + mul r43 10u128 into r45; + ternary r44 r45 r43 into r46; + lt 7u8 r25 into r47; + mul r46 10u128 into r48; + ternary r47 r48 r46 into r49; + lt 8u8 r25 into r50; + mul r49 10u128 into r51; + ternary r50 r51 r49 into r52; + lt 9u8 r25 into r53; + mul r52 10u128 into r54; + ternary r53 r54 r52 into r55; + lt 10u8 r25 into r56; + mul r55 10u128 into r57; + ternary r56 r57 r55 into r58; + lt 11u8 r25 into r59; + mul r58 10u128 into r60; + ternary r59 r60 r58 into r61; + lt 12u8 r25 into r62; + mul r61 10u128 into r63; + ternary r62 r63 r61 into r64; + lt 13u8 r25 into r65; + mul r64 10u128 into r66; + ternary r65 r66 r64 into r67; + lt 14u8 r25 into r68; + mul r67 10u128 into r69; + ternary r68 r69 r67 into r70; + lt 15u8 r25 into r71; + mul r70 10u128 into r72; + ternary r71 r72 r70 into r73; + lt 16u8 r25 into r74; + mul r73 10u128 into r75; + ternary r74 r75 r73 into r76; + lt 17u8 r25 into r77; + mul r76 10u128 into r78; + ternary r77 r78 r76 into r79; + lt 18u8 r25 into r80; + mul r79 10u128 into r81; + ternary r80 r81 r79 into r82; + lt 19u8 r25 into r83; + mul r82 10u128 into r84; + ternary r83 r84 r82 into r85; + lt 20u8 r25 into r86; + mul r85 10u128 into r87; + ternary r86 r87 r85 into r88; + lt 21u8 r25 into r89; + mul r88 10u128 into r90; + ternary r89 r90 r88 into r91; + lt 22u8 r25 into r92; + mul r91 10u128 into r93; + ternary r92 r93 r91 into r94; + lt 23u8 r25 into r95; + mul r94 10u128 into r96; + ternary r95 r96 r94 into r97; + lt 24u8 r25 into r98; + mul r97 10u128 into r99; + ternary r98 r99 r97 into r100; + lt 25u8 r25 into r101; + mul r100 10u128 into r102; + ternary r101 r102 r100 into r103; + lt 26u8 r25 into r104; + mul r103 10u128 into r105; + ternary r104 r105 r103 into r106; + lt 27u8 r25 into r107; + mul r106 10u128 into r108; + ternary r107 r108 r106 into r109; + lt 28u8 r25 into r110; + mul r109 10u128 into r111; + ternary r110 r111 r109 into r112; + gt r22 9u8 into r113; + ternary r113 r22 9u8 into r114; + sub r114 9u8 into r115; + lte r115 29u8 into r116; + assert.eq r116 true; + lt 0u8 r115 into r117; + ternary r117 10u128 1u128 into r118; + lt 1u8 r115 into r119; + mul r118 10u128 into r120; + ternary r119 r120 r118 into r121; + lt 2u8 r115 into r122; + mul r121 10u128 into r123; + ternary r122 r123 r121 into r124; + lt 3u8 r115 into r125; + mul r124 10u128 into r126; + ternary r125 r126 r124 into r127; + lt 4u8 r115 into r128; + mul r127 10u128 into r129; + ternary r128 r129 r127 into r130; + lt 5u8 r115 into r131; + mul r130 10u128 into r132; + ternary r131 r132 r130 into r133; + lt 6u8 r115 into r134; + mul r133 10u128 into r135; + ternary r134 r135 r133 into r136; + lt 7u8 r115 into r137; + mul r136 10u128 into r138; + ternary r137 r138 r136 into r139; + lt 8u8 r115 into r140; + mul r139 10u128 into r141; + ternary r140 r141 r139 into r142; + lt 9u8 r115 into r143; + mul r142 10u128 into r144; + ternary r143 r144 r142 into r145; + lt 10u8 r115 into r146; + mul r145 10u128 into r147; + ternary r146 r147 r145 into r148; + lt 11u8 r115 into r149; + mul r148 10u128 into r150; + ternary r149 r150 r148 into r151; + lt 12u8 r115 into r152; + mul r151 10u128 into r153; + ternary r152 r153 r151 into r154; + lt 13u8 r115 into r155; + mul r154 10u128 into r156; + ternary r155 r156 r154 into r157; + lt 14u8 r115 into r158; + mul r157 10u128 into r159; + ternary r158 r159 r157 into r160; + lt 15u8 r115 into r161; + mul r160 10u128 into r162; + ternary r161 r162 r160 into r163; + lt 16u8 r115 into r164; + mul r163 10u128 into r165; + ternary r164 r165 r163 into r166; + lt 17u8 r115 into r167; + mul r166 10u128 into r168; + ternary r167 r168 r166 into r169; + lt 18u8 r115 into r170; + mul r169 10u128 into r171; + ternary r170 r171 r169 into r172; + lt 19u8 r115 into r173; + mul r172 10u128 into r174; + ternary r173 r174 r172 into r175; + lt 20u8 r115 into r176; + mul r175 10u128 into r177; + ternary r176 r177 r175 into r178; + lt 21u8 r115 into r179; + mul r178 10u128 into r180; + ternary r179 r180 r178 into r181; + lt 22u8 r115 into r182; + mul r181 10u128 into r183; + ternary r182 r183 r181 into r184; + lt 23u8 r115 into r185; + mul r184 10u128 into r186; + ternary r185 r186 r184 into r187; + lt 24u8 r115 into r188; + mul r187 10u128 into r189; + ternary r188 r189 r187 into r190; + lt 25u8 r115 into r191; + mul r190 10u128 into r192; + ternary r191 r192 r190 into r193; + lt 26u8 r115 into r194; + mul r193 10u128 into r195; + ternary r194 r195 r193 into r196; + lt 27u8 r115 into r197; + mul r196 10u128 into r198; + ternary r197 r198 r196 into r199; + lt 28u8 r115 into r200; + mul r199 10u128 into r201; + ternary r200 r201 r199 into r202; + cast r18 r19 r3 into r203 as PoolKey; + hash.bhp256 r203 into r204 as field; + cast r18 r19 r3 true r112 r202 into r205 as PoolState; + get.or_use token_paused[r18] false into r206; + not r206 into r207; + assert.eq r207 true; + get.or_use token_paused[r19] false into r208; + not r208 into r209; + assert.eq r209 true; + cast r18 r19 into r210 as PairKey; + get.or_use pair_paused[r210] false into r211; + not r211 into r212; + assert.eq r212 true; + assert.neq r1 r2; + get.or_use initialized_pools[r204] false into r213; + not r213 into r214; + assert.eq r214 true; + get.or_use tick_spacings[r5] false into r215; + assert.eq r215 true; + get.or_use fee_tiers[r3] false into r216; + assert.eq r216 true; + get fee_to_tick_spacing[r3] into r217; + is.eq r217 r5 into r218; + assert.eq r218 true; + cast r5 into r219 as i32; + rem r6 r219 into r220; + is.eq r220 0i32 into r221; + assert.eq r221 true; + gte r6 -400000i32 into r222; + lt r6 400000i32 into r223; + and r222 r223 into r224; + assert.eq r224 true; + call view_sqrt_price_at_tick r6 into r225; + add r6 1i32 into r226; + call view_sqrt_price_at_tick r226 into r227; + gte r4 r225 into r228; + lt r4 r227 into r229; + and r228 r229 into r230; + assert.eq r230 true; + cast r5 into r231 as u128; + div 800000u128 r231 into r232; + div 340282366920938463463374607431768211455u128 r232 into r233; + lt r233 9223372036854775808u128 into r234; + ternary r234 r233 9223372036854775808u128 into r235; + set true into initialized_pools[r204]; + set r205 into pools[r204]; + cast r204 -400001i32 into r236 as TickKey; + hash.bhp256 r236 into r237 as field; + cast r204 400001i32 into r238 as TickKey; + hash.bhp256 r238 into r239 as field; + cast r204 0i128 0u128 -400001i32 0u128 0u128 -400001i32 400001i32 into r240 as Tick; + set r240 into ticks[r237]; + cast r204 0i128 0u128 400001i32 0u128 0u128 -400001i32 400001i32 into r241 as Tick; + set r241 into ticks[r239]; + cast r6 r5 r4 0u8 0u128 0u128 0u128 0u128 0u128 r235 0u128 0u128 -400001i32 400001i32 into r242 as Slot; + set r242 into slots[r204]; + +view view_liquidity_for_amounts: + input r0 as u128.public; + input r1 as u128.public; + input r2 as u128.public; + input r3 as u128.public; + input r4 as u128.public; + gt r1 r2 into r5; + ternary r5 r2 r1 into r6; + ternary r5 r1 r2 into r7; + lte r0 r6 into r8; + gt r6 r7 into r9; + ternary r9 r7 r6 into r10; + ternary r9 r6 r7 into r11; + and r10 18446744073709551615u128 into r12; + shr r10 64u8 into r13; + and r11 18446744073709551615u128 into r14; + shr r11 64u8 into r15; + mul r12 r14 into r16; + mul r12 r15 into r17; + mul r13 r14 into r18; + mul r13 r15 into r19; + and r16 18446744073709551615u128 into r20; + shr r16 64u8 into r21; + and r17 18446744073709551615u128 into r22; + add r21 r22 into r23; + and r18 18446744073709551615u128 into r24; + add r23 r24 into r25; + and r25 18446744073709551615u128 into r26; + shr r25 64u8 into r27; + shr r17 64u8 into r28; + shr r18 64u8 into r29; + add r28 r29 into r30; + and r19 18446744073709551615u128 into r31; + add r30 r31 into r32; + add r32 r27 into r33; + and r33 18446744073709551615u128 into r34; + shr r33 64u8 into r35; + shr r19 64u8 into r36; + add r36 r35 into r37; + shl r26 64u8 into r38; + add r38 r20 into r39; + shl r37 64u8 into r40; + add r40 r34 into r41; + shl r41 65u8 into r42; + shr r39 63u8 into r43; + add r42 r43 into r44; + sub r11 r10 into r45; + gt r45 0u128 into r46; + ternary r46 r45 1u128 into r47; + ternary r46 r3 0u128 into r48; + and r48 18446744073709551615u128 into r49; + shr r48 64u8 into r50; + and r44 18446744073709551615u128 into r51; + shr r44 64u8 into r52; + mul r49 r51 into r53; + mul r49 r52 into r54; + mul r50 r51 into r55; + mul r50 r52 into r56; + and r53 18446744073709551615u128 into r57; + shr r53 64u8 into r58; + and r54 18446744073709551615u128 into r59; + add r58 r59 into r60; + and r55 18446744073709551615u128 into r61; + add r60 r61 into r62; + and r62 18446744073709551615u128 into r63; + shr r62 64u8 into r64; + shr r54 64u8 into r65; + shr r55 64u8 into r66; + add r65 r66 into r67; + and r56 18446744073709551615u128 into r68; + add r67 r68 into r69; + add r69 r64 into r70; + and r70 18446744073709551615u128 into r71; + shr r70 64u8 into r72; + shr r56 64u8 into r73; + add r73 r72 into r74; + shl r63 64u8 into r75; + add r75 r57 into r76; + shl r74 64u8 into r77; + add r77 r71 into r78; + lt r78 r47 into r79; + assert.eq r79 true; + shr r76 96u8 into r80; + and r80 4294967295u128 into r81; + shl r78 32u8 into r82; + add r82 r81 into r83; + div r83 r47 into r84; + rem r83 r47 into r85; + shr r76 64u8 into r86; + and r86 4294967295u128 into r87; + shl r85 32u8 into r88; + add r88 r87 into r89; + shl r84 32u8 into r90; + div r89 r47 into r91; + add r90 r91 into r92; + rem r89 r47 into r93; + shr r76 32u8 into r94; + and r94 4294967295u128 into r95; + shl r93 32u8 into r96; + add r96 r95 into r97; + shl r92 32u8 into r98; + div r97 r47 into r99; + add r98 r99 into r100; + rem r97 r47 into r101; + shr r76 0u8 into r102; + and r102 4294967295u128 into r103; + shl r101 32u8 into r104; + add r104 r103 into r105; + shl r100 32u8 into r106; + div r105 r47 into r107; + add r106 r107 into r108; + rem r105 r47 into r109; + add r108 1u128 into r110; + lt r0 r7 into r111; + gt r0 r7 into r112; + ternary r112 r7 r0 into r113; + ternary r112 r0 r7 into r114; + and r113 18446744073709551615u128 into r115; + shr r113 64u8 into r116; + and r114 18446744073709551615u128 into r117; + shr r114 64u8 into r118; + mul r115 r117 into r119; + mul r115 r118 into r120; + mul r116 r117 into r121; + mul r116 r118 into r122; + and r119 18446744073709551615u128 into r123; + shr r119 64u8 into r124; + and r120 18446744073709551615u128 into r125; + add r124 r125 into r126; + and r121 18446744073709551615u128 into r127; + add r126 r127 into r128; + and r128 18446744073709551615u128 into r129; + shr r128 64u8 into r130; + shr r120 64u8 into r131; + shr r121 64u8 into r132; + add r131 r132 into r133; + and r122 18446744073709551615u128 into r134; + add r133 r134 into r135; + add r135 r130 into r136; + and r136 18446744073709551615u128 into r137; + shr r136 64u8 into r138; + shr r122 64u8 into r139; + add r139 r138 into r140; + shl r129 64u8 into r141; + add r141 r123 into r142; + shl r140 64u8 into r143; + add r143 r137 into r144; + shl r144 65u8 into r145; + shr r142 63u8 into r146; + add r145 r146 into r147; + sub r114 r113 into r148; + gt r148 0u128 into r149; + ternary r149 r148 1u128 into r150; + ternary r149 r3 0u128 into r151; + and r151 18446744073709551615u128 into r152; + shr r151 64u8 into r153; + and r147 18446744073709551615u128 into r154; + shr r147 64u8 into r155; + mul r152 r154 into r156; + mul r152 r155 into r157; + mul r153 r154 into r158; + mul r153 r155 into r159; + and r156 18446744073709551615u128 into r160; + shr r156 64u8 into r161; + and r157 18446744073709551615u128 into r162; + add r161 r162 into r163; + and r158 18446744073709551615u128 into r164; + add r163 r164 into r165; + and r165 18446744073709551615u128 into r166; + shr r165 64u8 into r167; + shr r157 64u8 into r168; + shr r158 64u8 into r169; + add r168 r169 into r170; + and r159 18446744073709551615u128 into r171; + add r170 r171 into r172; + add r172 r167 into r173; + and r173 18446744073709551615u128 into r174; + shr r173 64u8 into r175; + shr r159 64u8 into r176; + add r176 r175 into r177; + shl r166 64u8 into r178; + add r178 r160 into r179; + shl r177 64u8 into r180; + add r180 r174 into r181; + lt r181 r150 into r182; + assert.eq r182 true; + shr r179 96u8 into r183; + and r183 4294967295u128 into r184; + shl r181 32u8 into r185; + add r185 r184 into r186; + div r186 r150 into r187; + rem r186 r150 into r188; + shr r179 64u8 into r189; + and r189 4294967295u128 into r190; + shl r188 32u8 into r191; + add r191 r190 into r192; + shl r187 32u8 into r193; + div r192 r150 into r194; + add r193 r194 into r195; + rem r192 r150 into r196; + shr r179 32u8 into r197; + and r197 4294967295u128 into r198; + shl r196 32u8 into r199; + add r199 r198 into r200; + shl r195 32u8 into r201; + div r200 r150 into r202; + add r201 r202 into r203; + rem r200 r150 into r204; + shr r179 0u8 into r205; + and r205 4294967295u128 into r206; + shl r204 32u8 into r207; + add r207 r206 into r208; + shl r203 32u8 into r209; + div r208 r150 into r210; + add r209 r210 into r211; + rem r208 r150 into r212; + add r211 1u128 into r213; + gt r6 r0 into r214; + ternary r214 r0 r6 into r215; + ternary r214 r6 r0 into r216; + sub r216 r215 into r217; + gt r217 0u128 into r218; + ternary r218 r217 1u128 into r219; + ternary r218 r4 0u128 into r220; + and r220 18446744073709551615u128 into r221; + shr r220 64u8 into r222; + mul r221 9223372036854775808u128 into r223; + mul r222 9223372036854775808u128 into r224; + and r223 18446744073709551615u128 into r225; + shr r223 64u8 into r226; + and r224 18446744073709551615u128 into r227; + add r226 r227 into r228; + and r228 18446744073709551615u128 into r229; + shr r228 64u8 into r230; + shr r224 64u8 into r231; + add r231 r230 into r232; + and r232 18446744073709551615u128 into r233; + shr r232 64u8 into r234; + shl r229 64u8 into r235; + add r235 r225 into r236; + shl r234 64u8 into r237; + add r237 r233 into r238; + lt r238 r219 into r239; + assert.eq r239 true; + shr r236 96u8 into r240; + and r240 4294967295u128 into r241; + shl r238 32u8 into r242; + add r242 r241 into r243; + div r243 r219 into r244; + rem r243 r219 into r245; + shr r236 64u8 into r246; + and r246 4294967295u128 into r247; + shl r245 32u8 into r248; + add r248 r247 into r249; + shl r244 32u8 into r250; + div r249 r219 into r251; + add r250 r251 into r252; + rem r249 r219 into r253; + shr r236 32u8 into r254; + and r254 4294967295u128 into r255; + shl r253 32u8 into r256; + add r256 r255 into r257; + shl r252 32u8 into r258; + div r257 r219 into r259; + add r258 r259 into r260; + rem r257 r219 into r261; + shr r236 0u8 into r262; + and r262 4294967295u128 into r263; + shl r261 32u8 into r264; + add r264 r263 into r265; + shl r260 32u8 into r266; + div r265 r219 into r267; + add r266 r267 into r268; + rem r265 r219 into r269; + add r268 1u128 into r270; + lt r211 r268 into r271; + ternary r271 r211 r268 into r272; + gt r6 r7 into r273; + ternary r273 r7 r6 into r274; + ternary r273 r6 r7 into r275; + sub r275 r274 into r276; + gt r276 0u128 into r277; + ternary r277 r276 1u128 into r278; + ternary r277 r4 0u128 into r279; + and r279 18446744073709551615u128 into r280; + shr r279 64u8 into r281; + mul r280 9223372036854775808u128 into r282; + mul r281 9223372036854775808u128 into r283; + and r282 18446744073709551615u128 into r284; + shr r282 64u8 into r285; + and r283 18446744073709551615u128 into r286; + add r285 r286 into r287; + and r287 18446744073709551615u128 into r288; + shr r287 64u8 into r289; + shr r283 64u8 into r290; + add r290 r289 into r291; + and r291 18446744073709551615u128 into r292; + shr r291 64u8 into r293; + shl r288 64u8 into r294; + add r294 r284 into r295; + shl r293 64u8 into r296; + add r296 r292 into r297; + lt r297 r278 into r298; + assert.eq r298 true; + shr r295 96u8 into r299; + and r299 4294967295u128 into r300; + shl r297 32u8 into r301; + add r301 r300 into r302; + div r302 r278 into r303; + rem r302 r278 into r304; + shr r295 64u8 into r305; + and r305 4294967295u128 into r306; + shl r304 32u8 into r307; + add r307 r306 into r308; + shl r303 32u8 into r309; + div r308 r278 into r310; + add r309 r310 into r311; + rem r308 r278 into r312; + shr r295 32u8 into r313; + and r313 4294967295u128 into r314; + shl r312 32u8 into r315; + add r315 r314 into r316; + shl r311 32u8 into r317; + div r316 r278 into r318; + add r317 r318 into r319; + rem r316 r278 into r320; + shr r295 0u8 into r321; + and r321 4294967295u128 into r322; + shl r320 32u8 into r323; + add r323 r322 into r324; + shl r319 32u8 into r325; + div r324 r278 into r326; + add r325 r326 into r327; + rem r324 r278 into r328; + add r327 1u128 into r329; + ternary r111 r272 r327 into r330; + ternary r8 r108 r330 into r331; + output r331 as u128.public; + +function mint: + input r0 as field.private; + input r1 as dynamic.record; + input r2 as dynamic.record; + input r3 as address.private; + input r4 as MintPositionRequest.public; + input r5 as field.public; + input r6 as field.public; + assert.neq r3 shield_swap_v3.aleo; + cast r4 r3 r0 into r7 as TokenIDPreimage; + hash.bhp256 r7 into r8 as field; + cast aleo1t08epjqqv8h7jpuy2m2cxm80zy2pcy5c4f3m82hnac4sjmdrjyysvx3s2h r8 r5 r6 r4 self.caller r3 into r9 as MintComplianceRecord.record; + cast r3 r8 r5 r6 r4.pool r4.tick_lower r4.tick_upper into r10 as PositionNFT.record; + call.dynamic r5 'aleo' 'transfer_private_to_public' with r1 shield_swap_v3.aleo r4.amount0_desired (as dynamic.record address.public u128.public) into r11 r12 (as dynamic.record dynamic.future); + call.dynamic r6 'aleo' 'transfer_private_to_public' with r2 shield_swap_v3.aleo r4.amount1_desired (as dynamic.record address.public u128.public) into r13 r14 (as dynamic.record dynamic.future); + async mint r12 r14 r4 r8 r5 r6 into r15; + output r8 as field.public; + output r10 as PositionNFT.record; + output r11 as dynamic.record; + output r13 as dynamic.record; + output r9 as MintComplianceRecord.record; + output r15 as shield_swap_v3.aleo/mint.future; + +finalize mint: + input r0 as dynamic.future; + input r1 as dynamic.future; + input r2 as MintPositionRequest.public; + input r3 as field.public; + input r4 as field.public; + input r5 as field.public; + await r0; + await r1; + get.or_use global_paused[true] false into r6; + not r6 into r7; + assert.eq r7 true; + get pools[r2.pool] into r8; + assert.eq r8.enabled true; + get.or_use token_paused[r8.token0] false into r9; + not r9 into r10; + assert.eq r10 true; + get.or_use token_paused[r8.token1] false into r11; + not r11 into r12; + assert.eq r12 true; + cast r8.token0 r8.token1 into r13 as PairKey; + get.or_use pair_paused[r13] false into r14; + not r14 into r15; + assert.eq r15 true; + is.eq r8.token0 r4 into r16; + assert.eq r16 true; + is.eq r8.token1 r5 into r17; + assert.eq r17 true; + get slots[r2.pool] into r18; + cast r18.tick_spacing into r19 as i32; + rem r2.tick_lower r19 into r20; + is.eq r20 0i32 into r21; + assert.eq r21 true; + cast r18.tick_spacing into r22 as i32; + rem r2.tick_upper r22 into r23; + is.eq r23 0i32 into r24; + assert.eq r24 true; + lt r2.tick_lower r2.tick_upper into r25; + assert.eq r25 true; + gte r2.tick_lower -400000i32 into r26; + assert.eq r26 true; + lte r2.tick_upper 400000i32 into r27; + assert.eq r27 true; + call view_sqrt_price_at_tick r2.tick_lower into r28; + call view_sqrt_price_at_tick r2.tick_upper into r29; + rem r2.amount0_desired r8.scale0 into r30; + is.eq r30 0u128 into r31; + assert.eq r31 true; + rem r2.amount1_desired r8.scale1 into r32; + is.eq r32 0u128 into r33; + assert.eq r33 true; + div r2.amount0_desired r8.scale0 into r34; + div r2.amount1_desired r8.scale1 into r35; + call view_liquidity_for_amounts r18.sqrt_price r28 r29 r34 r35 into r36; + gt r36 0u128 into r37; + assert.eq r37 true; + call view_amounts_for_liquidity r18.sqrt_price r28 r29 r36 false into r38 r39; + lte r38 r34 into r40; + lte r39 r35 into r41; + and r40 r41 into r42; + assert.eq r42 true; + mul r38 r8.scale0 into r43; + gte r43 r2.amount0_min into r44; + mul r39 r8.scale1 into r45; + gte r45 r2.amount1_min into r46; + and r44 r46 into r47; + assert.eq r47 true; + lt r18.sqrt_price r29 into r48; + branch.eq r48 false to end_then_0_0; + gt r38 0u128 into r49; + assert.eq r49 true; + branch.eq true true to end_otherwise_0_1; + position end_then_0_0; + position end_otherwise_0_1; + gt r18.sqrt_price r28 into r50; + branch.eq r50 false to end_then_0_2; + gt r39 0u128 into r51; + assert.eq r51 true; + branch.eq true true to end_otherwise_0_3; + position end_then_0_2; + position end_otherwise_0_3; + cast r2.pool r2.tick_lower into r52 as TickKey; + hash.bhp256 r52 into r53 as field; + cast r2.pool r2.tick_upper into r54 as TickKey; + hash.bhp256 r54 into r55 as field; + cast r2.pool 0i128 0u128 r2.tick_lower 0u128 0u128 0i32 0i32 into r56 as Tick; + cast r2.pool 0i128 0u128 r2.tick_upper 0u128 0u128 0i32 0i32 into r57 as Tick; + get.or_use ticks[r53] r56 into r58; + get.or_use ticks[r55] r57 into r59; + gt r58.liquidity_gross 0u128 into r60; + gt r59.liquidity_gross 0u128 into r61; + not r60 into r62; + lte r2.tick_lower r18.tick into r63; + and r62 r63 into r64; + ternary r64 r18.fee_growth_global0_x_64 r58.fee_growth_outside0_64 into r65; + lte r2.tick_lower r18.tick into r66; + and r62 r66 into r67; + ternary r67 r18.fee_growth_global1_x_64 r58.fee_growth_outside1_64 into r68; + not r61 into r69; + lte r2.tick_upper r18.tick into r70; + and r69 r70 into r71; + ternary r71 r18.fee_growth_global0_x_64 r59.fee_growth_outside0_64 into r72; + lte r2.tick_upper r18.tick into r73; + and r69 r73 into r74; + ternary r74 r18.fee_growth_global1_x_64 r59.fee_growth_outside1_64 into r75; + add r58.liquidity_gross r36 into r76; + add r59.liquidity_gross r36 into r77; + lte r76 r18.max_liquidity_per_tick into r78; + assert.eq r78 true; + lte r77 r18.max_liquidity_per_tick into r79; + assert.eq r79 true; + ternary r60 -400001i32 r2.tick_lower_hint into r80; + cast r2.pool r80 into r81 as TickKey; + hash.bhp256 r81 into r82 as field; + get ticks[r82] into r83; + branch.eq r62 false to end_then_0_4; + is.eq r83.pool r2.pool into r84; + assert.eq r84 true; + is.eq r83.tick r2.tick_lower_hint into r85; + assert.eq r85 true; + is.eq r2.tick_lower_hint -400001i32 into r86; + gt r83.liquidity_gross 0u128 into r87; + or r86 r87 into r88; + assert.eq r88 true; + lt r83.tick r2.tick_lower into r89; + assert.eq r89 true; + gt r83.next r2.tick_lower into r90; + assert.eq r90 true; + branch.eq true true to end_otherwise_0_5; + position end_then_0_4; + position end_otherwise_0_5; + ternary r60 r58.prev r2.tick_lower_hint into r91; + ternary r60 r58.next r83.next into r92; + cast r36 into r93 as i128; + add r58.liquidity_net r93 into r94; + cast r2.pool r94 r76 r2.tick_lower r65 r68 r91 r92 into r95 as Tick; + set r95 into ticks[r53]; + branch.eq r62 false to end_then_0_6; + cast r83.pool r83.liquidity_net r83.liquidity_gross r83.tick r83.fee_growth_outside0_64 r83.fee_growth_outside1_64 r83.prev r2.tick_lower into r96 as Tick; + set r96 into ticks[r82]; + cast r2.pool r92 into r97 as TickKey; + hash.bhp256 r97 into r98 as field; + get ticks[r98] into r99; + cast r99.pool r99.liquidity_net r99.liquidity_gross r99.tick r99.fee_growth_outside0_64 r99.fee_growth_outside1_64 r2.tick_lower r99.next into r100 as Tick; + set r100 into ticks[r98]; + branch.eq true true to end_otherwise_0_7; + position end_then_0_6; + position end_otherwise_0_7; + get.or_use ticks[r55] r57 into r101; + ternary r61 -400001i32 r2.tick_upper_hint into r102; + cast r2.pool r102 into r103 as TickKey; + hash.bhp256 r103 into r104 as field; + get ticks[r104] into r105; + branch.eq r69 false to end_then_0_8; + is.eq r105.pool r2.pool into r106; + assert.eq r106 true; + is.eq r105.tick r2.tick_upper_hint into r107; + assert.eq r107 true; + is.eq r2.tick_upper_hint -400001i32 into r108; + gt r105.liquidity_gross 0u128 into r109; + or r108 r109 into r110; + assert.eq r110 true; + lt r105.tick r2.tick_upper into r111; + assert.eq r111 true; + gt r105.next r2.tick_upper into r112; + assert.eq r112 true; + branch.eq true true to end_otherwise_0_9; + position end_then_0_8; + position end_otherwise_0_9; + ternary r61 r101.prev r2.tick_upper_hint into r113; + ternary r61 r101.next r105.next into r114; + cast r36 into r115 as i128; + sub r101.liquidity_net r115 into r116; + cast r2.pool r116 r77 r2.tick_upper r72 r75 r113 r114 into r117 as Tick; + set r117 into ticks[r55]; + branch.eq r69 false to end_then_0_10; + get ticks[r104] into r118; + cast r118.pool r118.liquidity_net r118.liquidity_gross r118.tick r118.fee_growth_outside0_64 r118.fee_growth_outside1_64 r118.prev r2.tick_upper into r119 as Tick; + set r119 into ticks[r104]; + cast r2.pool r114 into r120 as TickKey; + hash.bhp256 r120 into r121 as field; + get ticks[r121] into r122; + cast r122.pool r122.liquidity_net r122.liquidity_gross r122.tick r122.fee_growth_outside0_64 r122.fee_growth_outside1_64 r2.tick_upper r122.next into r123 as Tick; + set r123 into ticks[r121]; + branch.eq true true to end_otherwise_0_11; + position end_then_0_10; + position end_otherwise_0_11; + get ticks[r53] into r124; + get ticks[r55] into r125; + gte r18.tick r124.tick into r126; + gte r18.fee_growth_global0_x_64 r124.fee_growth_outside0_64 into r127; + ternary r127 r18.fee_growth_global0_x_64 r124.fee_growth_outside0_64 into r128; + ternary r127 r124.fee_growth_outside0_64 r18.fee_growth_global0_x_64 into r129; + sub r128 r129 into r130; + gt r130 0u128 into r131; + ternary r131 r130 1u128 into r132; + sub 340282366920938463463374607431768211455u128 r132 into r133; + add r133 1u128 into r134; + ternary r127 r130 r134 into r135; + gte r18.fee_growth_global1_x_64 r124.fee_growth_outside1_64 into r136; + ternary r136 r18.fee_growth_global1_x_64 r124.fee_growth_outside1_64 into r137; + ternary r136 r124.fee_growth_outside1_64 r18.fee_growth_global1_x_64 into r138; + sub r137 r138 into r139; + gt r139 0u128 into r140; + ternary r140 r139 1u128 into r141; + sub 340282366920938463463374607431768211455u128 r141 into r142; + add r142 1u128 into r143; + ternary r136 r139 r143 into r144; + ternary r126 r124.fee_growth_outside0_64 r135 into r145; + ternary r126 r124.fee_growth_outside1_64 r144 into r146; + lt r18.tick r125.tick into r147; + gte r18.fee_growth_global0_x_64 r125.fee_growth_outside0_64 into r148; + ternary r148 r18.fee_growth_global0_x_64 r125.fee_growth_outside0_64 into r149; + ternary r148 r125.fee_growth_outside0_64 r18.fee_growth_global0_x_64 into r150; + sub r149 r150 into r151; + gt r151 0u128 into r152; + ternary r152 r151 1u128 into r153; + sub 340282366920938463463374607431768211455u128 r153 into r154; + add r154 1u128 into r155; + ternary r148 r151 r155 into r156; + gte r18.fee_growth_global1_x_64 r125.fee_growth_outside1_64 into r157; + ternary r157 r18.fee_growth_global1_x_64 r125.fee_growth_outside1_64 into r158; + ternary r157 r125.fee_growth_outside1_64 r18.fee_growth_global1_x_64 into r159; + sub r158 r159 into r160; + gt r160 0u128 into r161; + ternary r161 r160 1u128 into r162; + sub 340282366920938463463374607431768211455u128 r162 into r163; + add r163 1u128 into r164; + ternary r157 r160 r164 into r165; + ternary r147 r125.fee_growth_outside0_64 r156 into r166; + ternary r147 r125.fee_growth_outside1_64 r165 into r167; + gte r18.fee_growth_global0_x_64 r145 into r168; + ternary r168 r18.fee_growth_global0_x_64 r145 into r169; + ternary r168 r145 r18.fee_growth_global0_x_64 into r170; + sub r169 r170 into r171; + gt r171 0u128 into r172; + ternary r172 r171 1u128 into r173; + sub 340282366920938463463374607431768211455u128 r173 into r174; + add r174 1u128 into r175; + ternary r168 r171 r175 into r176; + gte r176 r166 into r177; + ternary r177 r176 r166 into r178; + ternary r177 r166 r176 into r179; + sub r178 r179 into r180; + gt r180 0u128 into r181; + ternary r181 r180 1u128 into r182; + sub 340282366920938463463374607431768211455u128 r182 into r183; + add r183 1u128 into r184; + ternary r177 r180 r184 into r185; + gte r18.fee_growth_global1_x_64 r146 into r186; + ternary r186 r18.fee_growth_global1_x_64 r146 into r187; + ternary r186 r146 r18.fee_growth_global1_x_64 into r188; + sub r187 r188 into r189; + gt r189 0u128 into r190; + ternary r190 r189 1u128 into r191; + sub 340282366920938463463374607431768211455u128 r191 into r192; + add r192 1u128 into r193; + ternary r186 r189 r193 into r194; + gte r194 r167 into r195; + ternary r195 r194 r167 into r196; + ternary r195 r167 r194 into r197; + sub r196 r197 into r198; + gt r198 0u128 into r199; + ternary r199 r198 1u128 into r200; + sub 340282366920938463463374607431768211455u128 r200 into r201; + add r201 1u128 into r202; + ternary r195 r198 r202 into r203; + contains positions[r3] into r204; + not r204 into r205; + assert.eq r205 true; + sub r34 r38 into r206; + sub r35 r39 into r207; + cast r3 r2.pool r2.tick_lower r2.tick_upper r36 r185 r203 r206 r207 into r208 as Position; + set r208 into positions[r3]; + lte r2.tick_lower r18.tick into r209; + and r62 r209 into r210; + gt r2.tick_lower r18.next_init_below into r211; + and r210 r211 into r212; + ternary r212 r2.tick_lower r18.next_init_below into r213; + gt r2.tick_lower r18.tick into r214; + and r62 r214 into r215; + lt r2.tick_lower r18.next_init_above into r216; + and r215 r216 into r217; + ternary r217 r2.tick_lower r18.next_init_above into r218; + lte r2.tick_upper r18.tick into r219; + and r69 r219 into r220; + gt r2.tick_upper r213 into r221; + and r220 r221 into r222; + ternary r222 r2.tick_upper r213 into r223; + gt r2.tick_upper r18.tick into r224; + and r69 r224 into r225; + lt r2.tick_upper r218 into r226; + and r225 r226 into r227; + ternary r227 r2.tick_upper r218 into r228; + gte r18.tick r2.tick_lower into r229; + lt r18.tick r2.tick_upper into r230; + and r229 r230 into r231; + add r18.liquidity r36 into r232; + ternary r231 r232 r18.liquidity into r233; + cast r18.tick r18.tick_spacing r18.sqrt_price r18.fee_protocol r233 r18.fee_growth_global0_x_64 r18.fee_growth_global1_x_64 r18.fee_residual0_x_64 r18.fee_residual1_x_64 r18.max_liquidity_per_tick r18.protocol_fees0 r18.protocol_fees1 r223 r228 into r234 as Slot; + set r234 into slots[r2.pool]; + +function decrease_liquidity: + input r0 as PositionNFT.record; + input r1 as u128.public; + input r2 as u128.public; + input r3 as u128.public; + cast r0.owner r0.token_id r0.token0_id r0.token1_id r0.pool r0.tick_lower r0.tick_upper into r4 as PositionNFT.record; + async decrease_liquidity r0.token_id r0.pool r0.tick_lower r0.tick_upper r1 r2 r3 into r5; + output r0.token_id as field.public; + output r4 as PositionNFT.record; + output r5 as shield_swap_v3.aleo/decrease_liquidity.future; + +finalize decrease_liquidity: + input r0 as field.public; + input r1 as field.public; + input r2 as i32.public; + input r3 as i32.public; + input r4 as u128.public; + input r5 as u128.public; + input r6 as u128.public; + get positions[r0] into r7; + contains frozen_position[r0] into r8; + not r8 into r9; + assert.eq r9 true; + is.eq r7.pool r1 into r10; + is.eq r7.tick_lower r2 into r11; + and r10 r11 into r12; + is.eq r7.tick_upper r3 into r13; + and r12 r13 into r14; + assert.eq r14 true; + lte r4 r7.liquidity into r15; + assert.eq r15 true; + get positions[r0] into r16; + get slots[r16.pool] into r17; + call view_sqrt_price_at_tick r16.tick_lower into r18; + call view_sqrt_price_at_tick r16.tick_upper into r19; + call view_amounts_for_liquidity r17.sqrt_price r18 r19 r4 false into r20 r21; + cast r16.pool r16.tick_lower into r22 as TickKey; + hash.bhp256 r22 into r23 as field; + cast r16.pool r16.tick_upper into r24 as TickKey; + hash.bhp256 r24 into r25 as field; + get ticks[r23] into r26; + get ticks[r25] into r27; + gt r26.liquidity_gross 0u128 into r28; + gt r27.liquidity_gross 0u128 into r29; + sub r26.liquidity_gross r4 into r30; + sub r27.liquidity_gross r4 into r31; + is.eq r30 0u128 into r32; + and r28 r32 into r33; + is.eq r31 0u128 into r34; + and r29 r34 into r35; + cast r4 into r36 as i128; + sub r26.liquidity_net r36 into r37; + cast r26.pool r37 r30 r26.tick r26.fee_growth_outside0_64 r26.fee_growth_outside1_64 r26.prev r26.next into r38 as Tick; + set r38 into ticks[r23]; + branch.eq r33 false to end_then_0_0; + cast r16.pool r26.prev into r39 as TickKey; + hash.bhp256 r39 into r40 as field; + get ticks[r40] into r41; + cast r41.pool r41.liquidity_net r41.liquidity_gross r41.tick r41.fee_growth_outside0_64 r41.fee_growth_outside1_64 r41.prev r26.next into r42 as Tick; + set r42 into ticks[r40]; + cast r16.pool r26.next into r43 as TickKey; + hash.bhp256 r43 into r44 as field; + get ticks[r44] into r45; + cast r45.pool r45.liquidity_net r45.liquidity_gross r45.tick r45.fee_growth_outside0_64 r45.fee_growth_outside1_64 r26.prev r45.next into r46 as Tick; + set r46 into ticks[r44]; + branch.eq true true to end_otherwise_0_1; + position end_then_0_0; + position end_otherwise_0_1; + get ticks[r25] into r47; + cast r4 into r48 as i128; + add r47.liquidity_net r48 into r49; + cast r47.pool r49 r31 r47.tick r47.fee_growth_outside0_64 r47.fee_growth_outside1_64 r47.prev r47.next into r50 as Tick; + set r50 into ticks[r25]; + branch.eq r35 false to end_then_0_2; + cast r16.pool r47.prev into r51 as TickKey; + hash.bhp256 r51 into r52 as field; + get ticks[r52] into r53; + cast r53.pool r53.liquidity_net r53.liquidity_gross r53.tick r53.fee_growth_outside0_64 r53.fee_growth_outside1_64 r53.prev r47.next into r54 as Tick; + set r54 into ticks[r52]; + cast r16.pool r47.next into r55 as TickKey; + hash.bhp256 r55 into r56 as field; + get ticks[r56] into r57; + cast r57.pool r57.liquidity_net r57.liquidity_gross r57.tick r57.fee_growth_outside0_64 r57.fee_growth_outside1_64 r47.prev r57.next into r58 as Tick; + set r58 into ticks[r56]; + branch.eq true true to end_otherwise_0_3; + position end_then_0_2; + position end_otherwise_0_3; + get ticks[r23] into r59; + get ticks[r25] into r60; + gte r17.tick r59.tick into r61; + gte r17.fee_growth_global0_x_64 r59.fee_growth_outside0_64 into r62; + ternary r62 r17.fee_growth_global0_x_64 r59.fee_growth_outside0_64 into r63; + ternary r62 r59.fee_growth_outside0_64 r17.fee_growth_global0_x_64 into r64; + sub r63 r64 into r65; + gt r65 0u128 into r66; + ternary r66 r65 1u128 into r67; + sub 340282366920938463463374607431768211455u128 r67 into r68; + add r68 1u128 into r69; + ternary r62 r65 r69 into r70; + gte r17.fee_growth_global1_x_64 r59.fee_growth_outside1_64 into r71; + ternary r71 r17.fee_growth_global1_x_64 r59.fee_growth_outside1_64 into r72; + ternary r71 r59.fee_growth_outside1_64 r17.fee_growth_global1_x_64 into r73; + sub r72 r73 into r74; + gt r74 0u128 into r75; + ternary r75 r74 1u128 into r76; + sub 340282366920938463463374607431768211455u128 r76 into r77; + add r77 1u128 into r78; + ternary r71 r74 r78 into r79; + ternary r61 r59.fee_growth_outside0_64 r70 into r80; + ternary r61 r59.fee_growth_outside1_64 r79 into r81; + lt r17.tick r60.tick into r82; + gte r17.fee_growth_global0_x_64 r60.fee_growth_outside0_64 into r83; + ternary r83 r17.fee_growth_global0_x_64 r60.fee_growth_outside0_64 into r84; + ternary r83 r60.fee_growth_outside0_64 r17.fee_growth_global0_x_64 into r85; + sub r84 r85 into r86; + gt r86 0u128 into r87; + ternary r87 r86 1u128 into r88; + sub 340282366920938463463374607431768211455u128 r88 into r89; + add r89 1u128 into r90; + ternary r83 r86 r90 into r91; + gte r17.fee_growth_global1_x_64 r60.fee_growth_outside1_64 into r92; + ternary r92 r17.fee_growth_global1_x_64 r60.fee_growth_outside1_64 into r93; + ternary r92 r60.fee_growth_outside1_64 r17.fee_growth_global1_x_64 into r94; + sub r93 r94 into r95; + gt r95 0u128 into r96; + ternary r96 r95 1u128 into r97; + sub 340282366920938463463374607431768211455u128 r97 into r98; + add r98 1u128 into r99; + ternary r92 r95 r99 into r100; + ternary r82 r60.fee_growth_outside0_64 r91 into r101; + ternary r82 r60.fee_growth_outside1_64 r100 into r102; + gte r17.fee_growth_global0_x_64 r80 into r103; + ternary r103 r17.fee_growth_global0_x_64 r80 into r104; + ternary r103 r80 r17.fee_growth_global0_x_64 into r105; + sub r104 r105 into r106; + gt r106 0u128 into r107; + ternary r107 r106 1u128 into r108; + sub 340282366920938463463374607431768211455u128 r108 into r109; + add r109 1u128 into r110; + ternary r103 r106 r110 into r111; + gte r111 r101 into r112; + ternary r112 r111 r101 into r113; + ternary r112 r101 r111 into r114; + sub r113 r114 into r115; + gt r115 0u128 into r116; + ternary r116 r115 1u128 into r117; + sub 340282366920938463463374607431768211455u128 r117 into r118; + add r118 1u128 into r119; + ternary r112 r115 r119 into r120; + gte r17.fee_growth_global1_x_64 r81 into r121; + ternary r121 r17.fee_growth_global1_x_64 r81 into r122; + ternary r121 r81 r17.fee_growth_global1_x_64 into r123; + sub r122 r123 into r124; + gt r124 0u128 into r125; + ternary r125 r124 1u128 into r126; + sub 340282366920938463463374607431768211455u128 r126 into r127; + add r127 1u128 into r128; + ternary r121 r124 r128 into r129; + gte r129 r102 into r130; + ternary r130 r129 r102 into r131; + ternary r130 r102 r129 into r132; + sub r131 r132 into r133; + gt r133 0u128 into r134; + ternary r134 r133 1u128 into r135; + sub 340282366920938463463374607431768211455u128 r135 into r136; + add r136 1u128 into r137; + ternary r130 r133 r137 into r138; + gte r120 r16.fee_growth_inside0_last_64 into r139; + ternary r139 r120 r16.fee_growth_inside0_last_64 into r140; + ternary r139 r16.fee_growth_inside0_last_64 r120 into r141; + sub r140 r141 into r142; + gt r142 0u128 into r143; + ternary r143 r142 1u128 into r144; + sub 340282366920938463463374607431768211455u128 r144 into r145; + add r145 1u128 into r146; + ternary r139 r142 r146 into r147; + and r147 18446744073709551615u128 into r148; + shr r147 64u8 into r149; + and r16.liquidity 18446744073709551615u128 into r150; + shr r16.liquidity 64u8 into r151; + mul r148 r150 into r152; + mul r148 r151 into r153; + mul r149 r150 into r154; + mul r149 r151 into r155; + and r152 18446744073709551615u128 into r156; + shr r152 64u8 into r157; + and r153 18446744073709551615u128 into r158; + add r157 r158 into r159; + and r154 18446744073709551615u128 into r160; + add r159 r160 into r161; + and r161 18446744073709551615u128 into r162; + shr r161 64u8 into r163; + shr r153 64u8 into r164; + shr r154 64u8 into r165; + add r164 r165 into r166; + and r155 18446744073709551615u128 into r167; + add r166 r167 into r168; + add r168 r163 into r169; + and r169 18446744073709551615u128 into r170; + shr r169 64u8 into r171; + shr r155 64u8 into r172; + add r172 r171 into r173; + shl r162 64u8 into r174; + add r174 r156 into r175; + shl r173 64u8 into r176; + add r176 r170 into r177; + shl r177 65u8 into r178; + shr r175 63u8 into r179; + add r178 r179 into r180; + add r16.tokens_owed0 r180 into r181; + add r181 r20 into r182; + gte r138 r16.fee_growth_inside1_last_64 into r183; + ternary r183 r138 r16.fee_growth_inside1_last_64 into r184; + ternary r183 r16.fee_growth_inside1_last_64 r138 into r185; + sub r184 r185 into r186; + gt r186 0u128 into r187; + ternary r187 r186 1u128 into r188; + sub 340282366920938463463374607431768211455u128 r188 into r189; + add r189 1u128 into r190; + ternary r183 r186 r190 into r191; + and r191 18446744073709551615u128 into r192; + shr r191 64u8 into r193; + and r16.liquidity 18446744073709551615u128 into r194; + shr r16.liquidity 64u8 into r195; + mul r192 r194 into r196; + mul r192 r195 into r197; + mul r193 r194 into r198; + mul r193 r195 into r199; + and r196 18446744073709551615u128 into r200; + shr r196 64u8 into r201; + and r197 18446744073709551615u128 into r202; + add r201 r202 into r203; + and r198 18446744073709551615u128 into r204; + add r203 r204 into r205; + and r205 18446744073709551615u128 into r206; + shr r205 64u8 into r207; + shr r197 64u8 into r208; + shr r198 64u8 into r209; + add r208 r209 into r210; + and r199 18446744073709551615u128 into r211; + add r210 r211 into r212; + add r212 r207 into r213; + and r213 18446744073709551615u128 into r214; + shr r213 64u8 into r215; + shr r199 64u8 into r216; + add r216 r215 into r217; + shl r206 64u8 into r218; + add r218 r200 into r219; + shl r217 64u8 into r220; + add r220 r214 into r221; + shl r221 65u8 into r222; + shr r219 63u8 into r223; + add r222 r223 into r224; + add r16.tokens_owed1 r224 into r225; + add r225 r21 into r226; + sub r16.liquidity r4 into r227; + cast r0 r16.pool r16.tick_lower r16.tick_upper r227 r120 r138 r182 r226 into r228 as Position; + set r228 into positions[r0]; + is.eq r17.next_init_below r16.tick_lower into r229; + and r33 r229 into r230; + ternary r230 r26.prev r17.next_init_below into r231; + is.eq r17.next_init_above r16.tick_lower into r232; + and r33 r232 into r233; + ternary r233 r26.next r17.next_init_above into r234; + is.eq r231 r16.tick_upper into r235; + and r35 r235 into r236; + ternary r236 r47.prev r231 into r237; + is.eq r234 r16.tick_upper into r238; + and r35 r238 into r239; + ternary r239 r47.next r234 into r240; + gte r17.tick r16.tick_lower into r241; + lt r17.tick r16.tick_upper into r242; + and r241 r242 into r243; + ternary r243 r4 0u128 into r244; + sub r17.liquidity r244 into r245; + cast r17.tick r17.tick_spacing r17.sqrt_price r17.fee_protocol r245 r17.fee_growth_global0_x_64 r17.fee_growth_global1_x_64 r17.fee_residual0_x_64 r17.fee_residual1_x_64 r17.max_liquidity_per_tick r17.protocol_fees0 r17.protocol_fees1 r237 r240 into r246 as Slot; + set r246 into slots[r16.pool]; + branch.eq r33 false to end_then_0_4; + remove ticks[r23]; + branch.eq true true to end_otherwise_0_5; + position end_then_0_4; + position end_otherwise_0_5; + branch.eq r35 false to end_then_0_6; + remove ticks[r25]; + branch.eq true true to end_otherwise_0_7; + position end_then_0_6; + position end_otherwise_0_7; + get pools[r1] into r247; + mul r20 r247.scale0 into r248; + gte r248 r5 into r249; + mul r21 r247.scale1 into r250; + gte r250 r6 into r251; + and r249 r251 into r252; + assert.eq r252 true; + +function increase_liquidity: + input r0 as PositionNFT.record; + input r1 as dynamic.record; + input r2 as dynamic.record; + input r3 as u128.public; + input r4 as u128.public; + input r5 as u128.public; + input r6 as u128.public; + input r7 as field.public; + input r8 as field.public; + input r9 as i32.public; + input r10 as i32.public; + cast r0.owner r0.token_id r0.token0_id r0.token1_id r0.pool r0.tick_lower r0.tick_upper into r11 as PositionNFT.record; + call.dynamic r7 'aleo' 'transfer_private_to_public' with r1 shield_swap_v3.aleo r3 (as dynamic.record address.public u128.public) into r12 r13 (as dynamic.record dynamic.future); + call.dynamic r8 'aleo' 'transfer_private_to_public' with r2 shield_swap_v3.aleo r4 (as dynamic.record address.public u128.public) into r14 r15 (as dynamic.record dynamic.future); + async increase_liquidity r13 r15 r0.token_id r0.pool r0.tick_lower r0.tick_upper r3 r4 r5 r6 r7 r8 r9 r10 into r16; + output r0.token_id as field.public; + output r11 as PositionNFT.record; + output r12 as dynamic.record; + output r14 as dynamic.record; + output r16 as shield_swap_v3.aleo/increase_liquidity.future; + +finalize increase_liquidity: + input r0 as dynamic.future; + input r1 as dynamic.future; + input r2 as field.public; + input r3 as field.public; + input r4 as i32.public; + input r5 as i32.public; + input r6 as u128.public; + input r7 as u128.public; + input r8 as u128.public; + input r9 as u128.public; + input r10 as field.public; + input r11 as field.public; + input r12 as i32.public; + input r13 as i32.public; + await r0; + await r1; + get.or_use global_paused[true] false into r14; + not r14 into r15; + assert.eq r15 true; + get pools[r3] into r16; + assert.eq r16.enabled true; + get.or_use token_paused[r16.token0] false into r17; + not r17 into r18; + assert.eq r18 true; + get.or_use token_paused[r16.token1] false into r19; + not r19 into r20; + assert.eq r20 true; + cast r16.token0 r16.token1 into r21 as PairKey; + get.or_use pair_paused[r21] false into r22; + not r22 into r23; + assert.eq r23 true; + is.eq r16.token0 r10 into r24; + assert.eq r24 true; + is.eq r16.token1 r11 into r25; + assert.eq r25 true; + get slots[r3] into r26; + get positions[r2] into r27; + contains frozen_position[r2] into r28; + not r28 into r29; + assert.eq r29 true; + is.eq r27.pool r3 into r30; + is.eq r27.tick_lower r4 into r31; + and r30 r31 into r32; + is.eq r27.tick_upper r5 into r33; + and r32 r33 into r34; + assert.eq r34 true; + call view_sqrt_price_at_tick r4 into r35; + call view_sqrt_price_at_tick r5 into r36; + rem r6 r16.scale0 into r37; + is.eq r37 0u128 into r38; + assert.eq r38 true; + rem r7 r16.scale1 into r39; + is.eq r39 0u128 into r40; + assert.eq r40 true; + div r6 r16.scale0 into r41; + div r7 r16.scale1 into r42; + call view_liquidity_for_amounts r26.sqrt_price r35 r36 r41 r42 into r43; + gt r43 0u128 into r44; + assert.eq r44 true; + call view_amounts_for_liquidity r26.sqrt_price r35 r36 r43 false into r45 r46; + lte r45 r41 into r47; + lte r46 r42 into r48; + and r47 r48 into r49; + assert.eq r49 true; + mul r45 r16.scale0 into r50; + gte r50 r8 into r51; + mul r46 r16.scale1 into r52; + gte r52 r9 into r53; + and r51 r53 into r54; + assert.eq r54 true; + lt r26.sqrt_price r36 into r55; + branch.eq r55 false to end_then_0_0; + gt r45 0u128 into r56; + assert.eq r56 true; + branch.eq true true to end_otherwise_0_1; + position end_then_0_0; + position end_otherwise_0_1; + gt r26.sqrt_price r35 into r57; + branch.eq r57 false to end_then_0_2; + gt r46 0u128 into r58; + assert.eq r58 true; + branch.eq true true to end_otherwise_0_3; + position end_then_0_2; + position end_otherwise_0_3; + cast r3 r4 into r59 as TickKey; + hash.bhp256 r59 into r60 as field; + cast r3 r5 into r61 as TickKey; + hash.bhp256 r61 into r62 as field; + cast r3 0i128 0u128 r4 0u128 0u128 0i32 0i32 into r63 as Tick; + cast r3 0i128 0u128 r5 0u128 0u128 0i32 0i32 into r64 as Tick; + get.or_use ticks[r60] r63 into r65; + get.or_use ticks[r62] r64 into r66; + gt r65.liquidity_gross 0u128 into r67; + gt r66.liquidity_gross 0u128 into r68; + add r65.liquidity_gross r43 into r69; + add r66.liquidity_gross r43 into r70; + lte r69 r26.max_liquidity_per_tick into r71; + assert.eq r71 true; + lte r70 r26.max_liquidity_per_tick into r72; + assert.eq r72 true; + not r67 into r73; + lte r4 r26.tick into r74; + and r73 r74 into r75; + ternary r75 r26.fee_growth_global0_x_64 r65.fee_growth_outside0_64 into r76; + lte r4 r26.tick into r77; + and r73 r77 into r78; + ternary r78 r26.fee_growth_global1_x_64 r65.fee_growth_outside1_64 into r79; + not r68 into r80; + lte r5 r26.tick into r81; + and r80 r81 into r82; + ternary r82 r26.fee_growth_global0_x_64 r66.fee_growth_outside0_64 into r83; + lte r5 r26.tick into r84; + and r80 r84 into r85; + ternary r85 r26.fee_growth_global1_x_64 r66.fee_growth_outside1_64 into r86; + ternary r67 -400001i32 r12 into r87; + cast r3 r87 into r88 as TickKey; + hash.bhp256 r88 into r89 as field; + get ticks[r89] into r90; + branch.eq r73 false to end_then_0_4; + is.eq r90.pool r3 into r91; + assert.eq r91 true; + is.eq r90.tick r12 into r92; + assert.eq r92 true; + is.eq r12 -400001i32 into r93; + gt r90.liquidity_gross 0u128 into r94; + or r93 r94 into r95; + assert.eq r95 true; + lt r90.tick r4 into r96; + assert.eq r96 true; + gt r90.next r4 into r97; + assert.eq r97 true; + branch.eq true true to end_otherwise_0_5; + position end_then_0_4; + position end_otherwise_0_5; + ternary r67 r65.prev r12 into r98; + ternary r67 r65.next r90.next into r99; + cast r43 into r100 as i128; + add r65.liquidity_net r100 into r101; + cast r3 r101 r69 r4 r76 r79 r98 r99 into r102 as Tick; + set r102 into ticks[r60]; + branch.eq r73 false to end_then_0_6; + cast r90.pool r90.liquidity_net r90.liquidity_gross r90.tick r90.fee_growth_outside0_64 r90.fee_growth_outside1_64 r90.prev r4 into r103 as Tick; + set r103 into ticks[r89]; + cast r3 r99 into r104 as TickKey; + hash.bhp256 r104 into r105 as field; + get ticks[r105] into r106; + cast r106.pool r106.liquidity_net r106.liquidity_gross r106.tick r106.fee_growth_outside0_64 r106.fee_growth_outside1_64 r4 r106.next into r107 as Tick; + set r107 into ticks[r105]; + branch.eq true true to end_otherwise_0_7; + position end_then_0_6; + position end_otherwise_0_7; + get.or_use ticks[r62] r64 into r108; + ternary r68 -400001i32 r13 into r109; + cast r3 r109 into r110 as TickKey; + hash.bhp256 r110 into r111 as field; + get ticks[r111] into r112; + branch.eq r80 false to end_then_0_8; + is.eq r112.pool r3 into r113; + assert.eq r113 true; + is.eq r112.tick r13 into r114; + assert.eq r114 true; + is.eq r13 -400001i32 into r115; + gt r112.liquidity_gross 0u128 into r116; + or r115 r116 into r117; + assert.eq r117 true; + lt r112.tick r5 into r118; + assert.eq r118 true; + gt r112.next r5 into r119; + assert.eq r119 true; + branch.eq true true to end_otherwise_0_9; + position end_then_0_8; + position end_otherwise_0_9; + ternary r68 r108.prev r13 into r120; + ternary r68 r108.next r112.next into r121; + cast r43 into r122 as i128; + sub r108.liquidity_net r122 into r123; + cast r3 r123 r70 r5 r83 r86 r120 r121 into r124 as Tick; + set r124 into ticks[r62]; + branch.eq r80 false to end_then_0_10; + get ticks[r111] into r125; + cast r125.pool r125.liquidity_net r125.liquidity_gross r125.tick r125.fee_growth_outside0_64 r125.fee_growth_outside1_64 r125.prev r5 into r126 as Tick; + set r126 into ticks[r111]; + cast r3 r121 into r127 as TickKey; + hash.bhp256 r127 into r128 as field; + get ticks[r128] into r129; + cast r129.pool r129.liquidity_net r129.liquidity_gross r129.tick r129.fee_growth_outside0_64 r129.fee_growth_outside1_64 r5 r129.next into r130 as Tick; + set r130 into ticks[r128]; + branch.eq true true to end_otherwise_0_11; + position end_then_0_10; + position end_otherwise_0_11; + get ticks[r60] into r131; + get ticks[r62] into r132; + gte r26.tick r131.tick into r133; + gte r26.fee_growth_global0_x_64 r131.fee_growth_outside0_64 into r134; + ternary r134 r26.fee_growth_global0_x_64 r131.fee_growth_outside0_64 into r135; + ternary r134 r131.fee_growth_outside0_64 r26.fee_growth_global0_x_64 into r136; + sub r135 r136 into r137; + gt r137 0u128 into r138; + ternary r138 r137 1u128 into r139; + sub 340282366920938463463374607431768211455u128 r139 into r140; + add r140 1u128 into r141; + ternary r134 r137 r141 into r142; + gte r26.fee_growth_global1_x_64 r131.fee_growth_outside1_64 into r143; + ternary r143 r26.fee_growth_global1_x_64 r131.fee_growth_outside1_64 into r144; + ternary r143 r131.fee_growth_outside1_64 r26.fee_growth_global1_x_64 into r145; + sub r144 r145 into r146; + gt r146 0u128 into r147; + ternary r147 r146 1u128 into r148; + sub 340282366920938463463374607431768211455u128 r148 into r149; + add r149 1u128 into r150; + ternary r143 r146 r150 into r151; + ternary r133 r131.fee_growth_outside0_64 r142 into r152; + ternary r133 r131.fee_growth_outside1_64 r151 into r153; + lt r26.tick r132.tick into r154; + gte r26.fee_growth_global0_x_64 r132.fee_growth_outside0_64 into r155; + ternary r155 r26.fee_growth_global0_x_64 r132.fee_growth_outside0_64 into r156; + ternary r155 r132.fee_growth_outside0_64 r26.fee_growth_global0_x_64 into r157; + sub r156 r157 into r158; + gt r158 0u128 into r159; + ternary r159 r158 1u128 into r160; + sub 340282366920938463463374607431768211455u128 r160 into r161; + add r161 1u128 into r162; + ternary r155 r158 r162 into r163; + gte r26.fee_growth_global1_x_64 r132.fee_growth_outside1_64 into r164; + ternary r164 r26.fee_growth_global1_x_64 r132.fee_growth_outside1_64 into r165; + ternary r164 r132.fee_growth_outside1_64 r26.fee_growth_global1_x_64 into r166; + sub r165 r166 into r167; + gt r167 0u128 into r168; + ternary r168 r167 1u128 into r169; + sub 340282366920938463463374607431768211455u128 r169 into r170; + add r170 1u128 into r171; + ternary r164 r167 r171 into r172; + ternary r154 r132.fee_growth_outside0_64 r163 into r173; + ternary r154 r132.fee_growth_outside1_64 r172 into r174; + gte r26.fee_growth_global0_x_64 r152 into r175; + ternary r175 r26.fee_growth_global0_x_64 r152 into r176; + ternary r175 r152 r26.fee_growth_global0_x_64 into r177; + sub r176 r177 into r178; + gt r178 0u128 into r179; + ternary r179 r178 1u128 into r180; + sub 340282366920938463463374607431768211455u128 r180 into r181; + add r181 1u128 into r182; + ternary r175 r178 r182 into r183; + gte r183 r173 into r184; + ternary r184 r183 r173 into r185; + ternary r184 r173 r183 into r186; + sub r185 r186 into r187; + gt r187 0u128 into r188; + ternary r188 r187 1u128 into r189; + sub 340282366920938463463374607431768211455u128 r189 into r190; + add r190 1u128 into r191; + ternary r184 r187 r191 into r192; + gte r26.fee_growth_global1_x_64 r153 into r193; + ternary r193 r26.fee_growth_global1_x_64 r153 into r194; + ternary r193 r153 r26.fee_growth_global1_x_64 into r195; + sub r194 r195 into r196; + gt r196 0u128 into r197; + ternary r197 r196 1u128 into r198; + sub 340282366920938463463374607431768211455u128 r198 into r199; + add r199 1u128 into r200; + ternary r193 r196 r200 into r201; + gte r201 r174 into r202; + ternary r202 r201 r174 into r203; + ternary r202 r174 r201 into r204; + sub r203 r204 into r205; + gt r205 0u128 into r206; + ternary r206 r205 1u128 into r207; + sub 340282366920938463463374607431768211455u128 r207 into r208; + add r208 1u128 into r209; + ternary r202 r205 r209 into r210; + gte r192 r27.fee_growth_inside0_last_64 into r211; + ternary r211 r192 r27.fee_growth_inside0_last_64 into r212; + ternary r211 r27.fee_growth_inside0_last_64 r192 into r213; + sub r212 r213 into r214; + gt r214 0u128 into r215; + ternary r215 r214 1u128 into r216; + sub 340282366920938463463374607431768211455u128 r216 into r217; + add r217 1u128 into r218; + ternary r211 r214 r218 into r219; + and r219 18446744073709551615u128 into r220; + shr r219 64u8 into r221; + and r27.liquidity 18446744073709551615u128 into r222; + shr r27.liquidity 64u8 into r223; + mul r220 r222 into r224; + mul r220 r223 into r225; + mul r221 r222 into r226; + mul r221 r223 into r227; + and r224 18446744073709551615u128 into r228; + shr r224 64u8 into r229; + and r225 18446744073709551615u128 into r230; + add r229 r230 into r231; + and r226 18446744073709551615u128 into r232; + add r231 r232 into r233; + and r233 18446744073709551615u128 into r234; + shr r233 64u8 into r235; + shr r225 64u8 into r236; + shr r226 64u8 into r237; + add r236 r237 into r238; + and r227 18446744073709551615u128 into r239; + add r238 r239 into r240; + add r240 r235 into r241; + and r241 18446744073709551615u128 into r242; + shr r241 64u8 into r243; + shr r227 64u8 into r244; + add r244 r243 into r245; + shl r234 64u8 into r246; + add r246 r228 into r247; + shl r245 64u8 into r248; + add r248 r242 into r249; + shl r249 65u8 into r250; + shr r247 63u8 into r251; + add r250 r251 into r252; + gte r210 r27.fee_growth_inside1_last_64 into r253; + ternary r253 r210 r27.fee_growth_inside1_last_64 into r254; + ternary r253 r27.fee_growth_inside1_last_64 r210 into r255; + sub r254 r255 into r256; + gt r256 0u128 into r257; + ternary r257 r256 1u128 into r258; + sub 340282366920938463463374607431768211455u128 r258 into r259; + add r259 1u128 into r260; + ternary r253 r256 r260 into r261; + and r261 18446744073709551615u128 into r262; + shr r261 64u8 into r263; + and r27.liquidity 18446744073709551615u128 into r264; + shr r27.liquidity 64u8 into r265; + mul r262 r264 into r266; + mul r262 r265 into r267; + mul r263 r264 into r268; + mul r263 r265 into r269; + and r266 18446744073709551615u128 into r270; + shr r266 64u8 into r271; + and r267 18446744073709551615u128 into r272; + add r271 r272 into r273; + and r268 18446744073709551615u128 into r274; + add r273 r274 into r275; + and r275 18446744073709551615u128 into r276; + shr r275 64u8 into r277; + shr r267 64u8 into r278; + shr r268 64u8 into r279; + add r278 r279 into r280; + and r269 18446744073709551615u128 into r281; + add r280 r281 into r282; + add r282 r277 into r283; + and r283 18446744073709551615u128 into r284; + shr r283 64u8 into r285; + shr r269 64u8 into r286; + add r286 r285 into r287; + shl r276 64u8 into r288; + add r288 r270 into r289; + shl r287 64u8 into r290; + add r290 r284 into r291; + shl r291 65u8 into r292; + shr r289 63u8 into r293; + add r292 r293 into r294; + sub r41 r45 into r295; + sub r42 r46 into r296; + add r27.liquidity r43 into r297; + add r27.tokens_owed0 r252 into r298; + add r298 r295 into r299; + add r27.tokens_owed1 r294 into r300; + add r300 r296 into r301; + cast r2 r3 r4 r5 r297 r192 r210 r299 r301 into r302 as Position; + set r302 into positions[r2]; + lte r4 r26.tick into r303; + and r73 r303 into r304; + gt r4 r26.next_init_below into r305; + and r304 r305 into r306; + ternary r306 r4 r26.next_init_below into r307; + gt r4 r26.tick into r308; + and r73 r308 into r309; + lt r4 r26.next_init_above into r310; + and r309 r310 into r311; + ternary r311 r4 r26.next_init_above into r312; + lte r5 r26.tick into r313; + and r80 r313 into r314; + gt r5 r307 into r315; + and r314 r315 into r316; + ternary r316 r5 r307 into r317; + gt r5 r26.tick into r318; + and r80 r318 into r319; + lt r5 r312 into r320; + and r319 r320 into r321; + ternary r321 r5 r312 into r322; + gte r26.tick r4 into r323; + lt r26.tick r5 into r324; + and r323 r324 into r325; + add r26.liquidity r43 into r326; + ternary r325 r326 r26.liquidity into r327; + cast r26.tick r26.tick_spacing r26.sqrt_price r26.fee_protocol r327 r26.fee_growth_global0_x_64 r26.fee_growth_global1_x_64 r26.fee_residual0_x_64 r26.fee_residual1_x_64 r26.max_liquidity_per_tick r26.protocol_fees0 r26.protocol_fees1 r317 r322 into r328 as Slot; + set r328 into slots[r3]; + +function collect: + input r0 as PositionNFT.record; + input r1 as u128.public; + input r2 as u128.public; + input r3 as field.public; + input r4 as field.public; + input r5 as address.private; + assert.neq r5 shield_swap_v3.aleo; + cast r0.owner r0.token_id r0.token0_id r0.token1_id r0.pool r0.tick_lower r0.tick_upper into r6 as PositionNFT.record; + call.dynamic r3 'aleo' 'transfer_public_to_private' with r5 r1 (as address.private u128.public) into r7 r8 (as dynamic.record dynamic.future); + call.dynamic r4 'aleo' 'transfer_public_to_private' with r5 r2 (as address.private u128.public) into r9 r10 (as dynamic.record dynamic.future); + async collect r8 r10 r0.token_id r0.pool r0.tick_lower r0.tick_upper r1 r2 r3 r4 into r11; + output r6 as PositionNFT.record; + output r7 as dynamic.record; + output r9 as dynamic.record; + output r11 as shield_swap_v3.aleo/collect.future; + +finalize collect: + input r0 as dynamic.future; + input r1 as dynamic.future; + input r2 as field.public; + input r3 as field.public; + input r4 as i32.public; + input r5 as i32.public; + input r6 as u128.public; + input r7 as u128.public; + input r8 as field.public; + input r9 as field.public; + await r0; + await r1; + get pools[r3] into r10; + is.eq r10.token0 r8 into r11; + is.eq r10.token1 r9 into r12; + and r11 r12 into r13; + assert.eq r13 true; + get slots[r3] into r14; + get positions[r2] into r15; + contains frozen_position[r2] into r16; + not r16 into r17; + assert.eq r17 true; + is.eq r15.pool r3 into r18; + is.eq r15.tick_lower r4 into r19; + and r18 r19 into r20; + is.eq r15.tick_upper r5 into r21; + and r20 r21 into r22; + assert.eq r22 true; + cast r3 0i128 0u128 r4 0u128 0u128 0i32 0i32 into r23 as Tick; + cast r3 0i128 0u128 r5 0u128 0u128 0i32 0i32 into r24 as Tick; + cast r3 r4 into r25 as TickKey; + hash.bhp256 r25 into r26 as field; + get.or_use ticks[r26] r23 into r27; + cast r3 r5 into r28 as TickKey; + hash.bhp256 r28 into r29 as field; + get.or_use ticks[r29] r24 into r30; + gte r14.tick r27.tick into r31; + gte r14.fee_growth_global0_x_64 r27.fee_growth_outside0_64 into r32; + ternary r32 r14.fee_growth_global0_x_64 r27.fee_growth_outside0_64 into r33; + ternary r32 r27.fee_growth_outside0_64 r14.fee_growth_global0_x_64 into r34; + sub r33 r34 into r35; + gt r35 0u128 into r36; + ternary r36 r35 1u128 into r37; + sub 340282366920938463463374607431768211455u128 r37 into r38; + add r38 1u128 into r39; + ternary r32 r35 r39 into r40; + gte r14.fee_growth_global1_x_64 r27.fee_growth_outside1_64 into r41; + ternary r41 r14.fee_growth_global1_x_64 r27.fee_growth_outside1_64 into r42; + ternary r41 r27.fee_growth_outside1_64 r14.fee_growth_global1_x_64 into r43; + sub r42 r43 into r44; + gt r44 0u128 into r45; + ternary r45 r44 1u128 into r46; + sub 340282366920938463463374607431768211455u128 r46 into r47; + add r47 1u128 into r48; + ternary r41 r44 r48 into r49; + ternary r31 r27.fee_growth_outside0_64 r40 into r50; + ternary r31 r27.fee_growth_outside1_64 r49 into r51; + lt r14.tick r30.tick into r52; + gte r14.fee_growth_global0_x_64 r30.fee_growth_outside0_64 into r53; + ternary r53 r14.fee_growth_global0_x_64 r30.fee_growth_outside0_64 into r54; + ternary r53 r30.fee_growth_outside0_64 r14.fee_growth_global0_x_64 into r55; + sub r54 r55 into r56; + gt r56 0u128 into r57; + ternary r57 r56 1u128 into r58; + sub 340282366920938463463374607431768211455u128 r58 into r59; + add r59 1u128 into r60; + ternary r53 r56 r60 into r61; + gte r14.fee_growth_global1_x_64 r30.fee_growth_outside1_64 into r62; + ternary r62 r14.fee_growth_global1_x_64 r30.fee_growth_outside1_64 into r63; + ternary r62 r30.fee_growth_outside1_64 r14.fee_growth_global1_x_64 into r64; + sub r63 r64 into r65; + gt r65 0u128 into r66; + ternary r66 r65 1u128 into r67; + sub 340282366920938463463374607431768211455u128 r67 into r68; + add r68 1u128 into r69; + ternary r62 r65 r69 into r70; + ternary r52 r30.fee_growth_outside0_64 r61 into r71; + ternary r52 r30.fee_growth_outside1_64 r70 into r72; + gte r14.fee_growth_global0_x_64 r50 into r73; + ternary r73 r14.fee_growth_global0_x_64 r50 into r74; + ternary r73 r50 r14.fee_growth_global0_x_64 into r75; + sub r74 r75 into r76; + gt r76 0u128 into r77; + ternary r77 r76 1u128 into r78; + sub 340282366920938463463374607431768211455u128 r78 into r79; + add r79 1u128 into r80; + ternary r73 r76 r80 into r81; + gte r81 r71 into r82; + ternary r82 r81 r71 into r83; + ternary r82 r71 r81 into r84; + sub r83 r84 into r85; + gt r85 0u128 into r86; + ternary r86 r85 1u128 into r87; + sub 340282366920938463463374607431768211455u128 r87 into r88; + add r88 1u128 into r89; + ternary r82 r85 r89 into r90; + gte r14.fee_growth_global1_x_64 r51 into r91; + ternary r91 r14.fee_growth_global1_x_64 r51 into r92; + ternary r91 r51 r14.fee_growth_global1_x_64 into r93; + sub r92 r93 into r94; + gt r94 0u128 into r95; + ternary r95 r94 1u128 into r96; + sub 340282366920938463463374607431768211455u128 r96 into r97; + add r97 1u128 into r98; + ternary r91 r94 r98 into r99; + gte r99 r72 into r100; + ternary r100 r99 r72 into r101; + ternary r100 r72 r99 into r102; + sub r101 r102 into r103; + gt r103 0u128 into r104; + ternary r104 r103 1u128 into r105; + sub 340282366920938463463374607431768211455u128 r105 into r106; + add r106 1u128 into r107; + ternary r100 r103 r107 into r108; + rem r6 r10.scale0 into r109; + is.eq r109 0u128 into r110; + rem r7 r10.scale1 into r111; + is.eq r111 0u128 into r112; + and r110 r112 into r113; + assert.eq r113 true; + div r6 r10.scale0 into r114; + div r7 r10.scale1 into r115; + gte r90 r15.fee_growth_inside0_last_64 into r116; + ternary r116 r90 r15.fee_growth_inside0_last_64 into r117; + ternary r116 r15.fee_growth_inside0_last_64 r90 into r118; + sub r117 r118 into r119; + gt r119 0u128 into r120; + ternary r120 r119 1u128 into r121; + sub 340282366920938463463374607431768211455u128 r121 into r122; + add r122 1u128 into r123; + ternary r116 r119 r123 into r124; + and r124 18446744073709551615u128 into r125; + shr r124 64u8 into r126; + and r15.liquidity 18446744073709551615u128 into r127; + shr r15.liquidity 64u8 into r128; + mul r125 r127 into r129; + mul r125 r128 into r130; + mul r126 r127 into r131; + mul r126 r128 into r132; + and r129 18446744073709551615u128 into r133; + shr r129 64u8 into r134; + and r130 18446744073709551615u128 into r135; + add r134 r135 into r136; + and r131 18446744073709551615u128 into r137; + add r136 r137 into r138; + and r138 18446744073709551615u128 into r139; + shr r138 64u8 into r140; + shr r130 64u8 into r141; + shr r131 64u8 into r142; + add r141 r142 into r143; + and r132 18446744073709551615u128 into r144; + add r143 r144 into r145; + add r145 r140 into r146; + and r146 18446744073709551615u128 into r147; + shr r146 64u8 into r148; + shr r132 64u8 into r149; + add r149 r148 into r150; + shl r139 64u8 into r151; + add r151 r133 into r152; + shl r150 64u8 into r153; + add r153 r147 into r154; + shl r154 65u8 into r155; + shr r152 63u8 into r156; + add r155 r156 into r157; + add r15.tokens_owed0 r157 into r158; + gte r108 r15.fee_growth_inside1_last_64 into r159; + ternary r159 r108 r15.fee_growth_inside1_last_64 into r160; + ternary r159 r15.fee_growth_inside1_last_64 r108 into r161; + sub r160 r161 into r162; + gt r162 0u128 into r163; + ternary r163 r162 1u128 into r164; + sub 340282366920938463463374607431768211455u128 r164 into r165; + add r165 1u128 into r166; + ternary r159 r162 r166 into r167; + and r167 18446744073709551615u128 into r168; + shr r167 64u8 into r169; + and r15.liquidity 18446744073709551615u128 into r170; + shr r15.liquidity 64u8 into r171; + mul r168 r170 into r172; + mul r168 r171 into r173; + mul r169 r170 into r174; + mul r169 r171 into r175; + and r172 18446744073709551615u128 into r176; + shr r172 64u8 into r177; + and r173 18446744073709551615u128 into r178; + add r177 r178 into r179; + and r174 18446744073709551615u128 into r180; + add r179 r180 into r181; + and r181 18446744073709551615u128 into r182; + shr r181 64u8 into r183; + shr r173 64u8 into r184; + shr r174 64u8 into r185; + add r184 r185 into r186; + and r175 18446744073709551615u128 into r187; + add r186 r187 into r188; + add r188 r183 into r189; + and r189 18446744073709551615u128 into r190; + shr r189 64u8 into r191; + shr r175 64u8 into r192; + add r192 r191 into r193; + shl r182 64u8 into r194; + add r194 r176 into r195; + shl r193 64u8 into r196; + add r196 r190 into r197; + shl r197 65u8 into r198; + shr r195 63u8 into r199; + add r198 r199 into r200; + add r15.tokens_owed1 r200 into r201; + lte r114 r158 into r202; + lte r115 r201 into r203; + and r202 r203 into r204; + assert.eq r204 true; + sub r158 r114 into r205; + sub r201 r115 into r206; + cast r2 r3 r4 r5 r15.liquidity r90 r108 r205 r206 into r207 as Position; + set r207 into positions[r2]; + +function burn: + input r0 as PositionNFT.record; + async burn r0.token_id into r1; + output r0.token_id as field.public; + output self.signer as address.public; + output r1 as shield_swap_v3.aleo/burn.future; + +finalize burn: + input r0 as field.public; + contains frozen_position[r0] into r1; + not r1 into r2; + assert.eq r2 true; + get positions[r0] into r3; + is.eq r3.liquidity 0u128 into r4; + assert.eq r4 true; + is.eq r3.tokens_owed0 0u128 into r5; + assert.eq r5 true; + is.eq r3.tokens_owed1 0u128 into r6; + assert.eq r6 true; + remove positions[r0]; + +closure verify_blinded_address: + input r0 as address; + input r1 as address; + input r2 as field; + input r3 as address; + cast r0 into r4 as field; + cast r1 into r5 as field; + cast r4 11835072102227764468342786961086432175093421716844963782363567713633field r5 r2 into r6 as [field; 4u32]; + hash.psd8.raw r6 into r7 as address; + assert.eq r7 r3; + +view view_swap_iteration: + input r0 as SwapIterCfg.public; + input r1 as i32.public; + input r2 as Tick.public; + input r3 as SwapIterState.public; + gte r1 -873409i32 into r4; + lte r1 873409i32 into r5; + and r4 r5 into r6; + assert.eq r6 true; + lt r1 0i32 into r7; + sub 0i32 r1 into r8; + ternary r7 r8 r1 into r9; + gte r9 0i32 into r10; + assert.eq r10 true; + cast r9 into r11 as u32; + and r11 3u32 into r12; + is.eq r12 0u32 into r13; + is.eq r12 1u32 into r14; + is.eq r12 2u32 into r15; + ternary r15 9222449791875588096u128 9221988703967300608u128 into r16; + ternary r14 9222910902837697536u128 r16 into r17; + ternary r13 9223372036854775808u128 r17 into r18; + and r11 4u32 into r19; + is.neq r19 0u32 into r20; + mul r18 9221527639111677952u128 into r21; + shr r21 63u8 into r22; + ternary r20 r22 r18 into r23; + and r11 8u32 into r24; + is.neq r24 0u32 into r25; + mul r23 9219683610192801792u128 into r26; + shr r26 63u8 into r27; + ternary r25 r27 r23 into r28; + and r11 16u32 into r29; + is.neq r29 0u32 into r30; + mul r28 9215996658532725760u128 into r31; + shr r31 63u8 into r32; + ternary r30 r32 r28 into r33; + and r11 32u32 into r34; + is.neq r34 0u32 into r35; + mul r33 9208627177859081216u128 into r36; + shr r36 63u8 into r37; + ternary r35 r37 r33 into r38; + and r11 64u32 into r39; + is.neq r39 0u32 into r40; + mul r38 9193905890596798464u128 into r41; + shr r41 63u8 into r42; + ternary r40 r42 r38 into r43; + and r11 128u32 into r44; + is.neq r44 0u32 into r45; + mul r43 9164533880601766912u128 into r46; + shr r46 63u8 into r47; + ternary r45 r47 r43 into r48; + and r11 256u32 into r49; + is.neq r49 0u32 into r50; + mul r48 9106071067403056128u128 into r51; + shr r51 63u8 into r52; + ternary r50 r52 r48 into r53; + and r11 512u32 into r54; + is.neq r54 0u32 into r55; + mul r53 8990261907820801024u128 into r56; + shr r56 63u8 into r57; + ternary r55 r57 r53 into r58; + and r11 1024u32 into r59; + is.neq r59 0u32 into r60; + mul r58 8763043369415622656u128 into r61; + shr r61 63u8 into r62; + ternary r60 r62 r58 into r63; + and r11 2048u32 into r64; + is.neq r64 0u32 into r65; + mul r63 8325689215117605888u128 into r66; + shr r66 63u8 into r67; + ternary r65 r67 r63 into r68; + and r11 4096u32 into r69; + is.neq r69 0u32 into r70; + mul r68 7515375139346884608u128 into r71; + shr r71 63u8 into r72; + ternary r70 r72 r68 into r73; + and r11 8192u32 into r74; + is.neq r74 0u32 into r75; + mul r73 6123667489441693696u128 into r76; + shr r76 63u8 into r77; + ternary r75 r77 r73 into r78; + and r11 16384u32 into r79; + is.neq r79 0u32 into r80; + mul r78 4065682634442729984u128 into r81; + shr r81 63u8 into r82; + ternary r80 r82 r78 into r83; + and r11 32768u32 into r84; + is.neq r84 0u32 into r85; + mul r83 1792161827361994496u128 into r86; + shr r86 63u8 into r87; + ternary r85 r87 r83 into r88; + and r11 65536u32 into r89; + is.neq r89 0u32 into r90; + mul r88 348228825923923264u128 into r91; + shr r91 63u8 into r92; + ternary r90 r92 r88 into r93; + and r11 131072u32 into r94; + is.neq r94 0u32 into r95; + mul r93 13147394978735516u128 into r96; + shr r96 63u8 into r97; + ternary r95 r97 r93 into r98; + and r11 262144u32 into r99; + is.neq r99 0u32 into r100; + mul r98 18740867660568u128 into r101; + shr r101 63u8 into r102; + ternary r100 r102 r98 into r103; + and r11 524288u32 into r104; + is.neq r104 0u32 into r105; + mul r103 38079361u128 into r106; + shr r106 63u8 into r107; + ternary r105 r107 r103 into r108; + gt r1 0i32 into r109; + div 85070591730234615865843651857942052864u128 r108 into r110; + ternary r109 r110 r108 into r111; + lt r111 r0.lim into r112; + ternary r112 r0.lim r111 into r113; + gt r111 r0.lim into r114; + ternary r114 r0.lim r111 into r115; + ternary r0.z r113 r115 into r116; + gt r3.rem 0u128 into r117; + and r3.crossed r117 into r118; + is.eq r3.liq 0u128 into r119; + and r118 r119 into r120; + gt r3.liq 0u128 into r121; + and r117 r121 into r122; + and r122 r3.crossed into r123; + gt r116 r3.sp into r124; + ternary r124 r3.sp r116 into r125; + ternary r124 r116 r3.sp into r126; + gt r125 0u128 into r127; + gt r126 0u128 into r128; + and r127 r128 into r129; + ternary r128 r126 1u128 into r130; + ternary r127 r125 1u128 into r131; + and r3.liq 18446744073709551615u128 into r132; + shr r3.liq 64u8 into r133; + mul r132 9223372036854775808u128 into r134; + mul r133 9223372036854775808u128 into r135; + and r134 18446744073709551615u128 into r136; + shr r134 64u8 into r137; + and r135 18446744073709551615u128 into r138; + add r137 r138 into r139; + and r139 18446744073709551615u128 into r140; + shr r139 64u8 into r141; + shr r135 64u8 into r142; + add r142 r141 into r143; + and r143 18446744073709551615u128 into r144; + shr r143 64u8 into r145; + shl r140 64u8 into r146; + add r146 r136 into r147; + shl r145 64u8 into r148; + add r148 r144 into r149; + lt r149 r131 into r150; + assert.eq r150 true; + shr r147 96u8 into r151; + and r151 4294967295u128 into r152; + shl r149 32u8 into r153; + add r153 r152 into r154; + div r154 r131 into r155; + rem r154 r131 into r156; + shr r147 64u8 into r157; + and r157 4294967295u128 into r158; + shl r156 32u8 into r159; + add r159 r158 into r160; + shl r155 32u8 into r161; + div r160 r131 into r162; + add r161 r162 into r163; + rem r160 r131 into r164; + shr r147 32u8 into r165; + and r165 4294967295u128 into r166; + shl r164 32u8 into r167; + add r167 r166 into r168; + shl r163 32u8 into r169; + div r168 r131 into r170; + add r169 r170 into r171; + rem r168 r131 into r172; + shr r147 0u8 into r173; + and r173 4294967295u128 into r174; + shl r172 32u8 into r175; + add r175 r174 into r176; + shl r171 32u8 into r177; + div r176 r131 into r178; + add r177 r178 into r179; + rem r176 r131 into r180; + gt r180 0u128 into r181; + add r179 1u128 into r182; + ternary r181 r182 r179 into r183; + add r137 r138 into r184; + and r184 18446744073709551615u128 into r185; + shr r184 64u8 into r186; + add r142 r186 into r187; + and r187 18446744073709551615u128 into r188; + shr r187 64u8 into r189; + shl r185 64u8 into r190; + add r190 r136 into r191; + shl r189 64u8 into r192; + add r192 r188 into r193; + lt r193 r130 into r194; + assert.eq r194 true; + shr r191 96u8 into r195; + and r195 4294967295u128 into r196; + shl r193 32u8 into r197; + add r197 r196 into r198; + div r198 r130 into r199; + rem r198 r130 into r200; + shr r191 64u8 into r201; + and r201 4294967295u128 into r202; + shl r200 32u8 into r203; + add r203 r202 into r204; + shl r199 32u8 into r205; + div r204 r130 into r206; + add r205 r206 into r207; + rem r204 r130 into r208; + shr r191 32u8 into r209; + and r209 4294967295u128 into r210; + shl r208 32u8 into r211; + add r211 r210 into r212; + shl r207 32u8 into r213; + div r212 r130 into r214; + add r213 r214 into r215; + rem r212 r130 into r216; + shr r191 0u8 into r217; + and r217 4294967295u128 into r218; + shl r216 32u8 into r219; + add r219 r218 into r220; + shl r215 32u8 into r221; + div r220 r130 into r222; + add r221 r222 into r223; + rem r220 r130 into r224; + add r223 1u128 into r225; + gte r183 r223 into r226; + ternary r226 r183 r223 into r227; + ternary r226 r223 r183 into r228; + sub r227 r228 into r229; + ternary r226 r229 0u128 into r230; + lt r125 r126 into r231; + and r129 r231 into r232; + ternary r232 r230 0u128 into r233; + gt r3.sp r116 into r234; + ternary r234 r116 r3.sp into r235; + ternary r234 r3.sp r116 into r236; + sub r236 r235 into r237; + and r237 18446744073709551615u128 into r238; + shr r237 64u8 into r239; + mul r132 r238 into r240; + mul r132 r239 into r241; + mul r133 r238 into r242; + mul r133 r239 into r243; + and r240 18446744073709551615u128 into r244; + shr r240 64u8 into r245; + and r241 18446744073709551615u128 into r246; + add r245 r246 into r247; + and r242 18446744073709551615u128 into r248; + add r247 r248 into r249; + and r249 18446744073709551615u128 into r250; + shr r249 64u8 into r251; + shr r241 64u8 into r252; + shr r242 64u8 into r253; + add r252 r253 into r254; + and r243 18446744073709551615u128 into r255; + add r254 r255 into r256; + add r256 r251 into r257; + and r257 18446744073709551615u128 into r258; + shr r257 64u8 into r259; + shr r243 64u8 into r260; + add r260 r259 into r261; + shl r250 64u8 into r262; + add r262 r244 into r263; + shl r261 64u8 into r264; + add r264 r258 into r265; + lt r265 9223372036854775808u128 into r266; + assert.eq r266 true; + shr r263 96u8 into r267; + and r267 4294967295u128 into r268; + shl r265 32u8 into r269; + add r269 r268 into r270; + div r270 9223372036854775808u128 into r271; + rem r270 9223372036854775808u128 into r272; + shr r263 64u8 into r273; + and r273 4294967295u128 into r274; + shl r272 32u8 into r275; + add r275 r274 into r276; + shl r271 32u8 into r277; + div r276 9223372036854775808u128 into r278; + add r277 r278 into r279; + rem r276 9223372036854775808u128 into r280; + shr r263 32u8 into r281; + and r281 4294967295u128 into r282; + shl r280 32u8 into r283; + add r283 r282 into r284; + shl r279 32u8 into r285; + div r284 9223372036854775808u128 into r286; + add r285 r286 into r287; + rem r284 9223372036854775808u128 into r288; + shr r263 0u8 into r289; + and r289 4294967295u128 into r290; + shl r288 32u8 into r291; + add r291 r290 into r292; + shl r287 32u8 into r293; + div r292 9223372036854775808u128 into r294; + add r293 r294 into r295; + rem r292 9223372036854775808u128 into r296; + gt r296 0u128 into r297; + add r295 1u128 into r298; + ternary r297 r298 r295 into r299; + ternary r0.z r233 r299 into r300; + cast r0.fee_pips into r301 as u128; + sub 1000000u128 r301 into r302; + and r3.rem 18446744073709551615u128 into r303; + shr r3.rem 64u8 into r304; + and r302 18446744073709551615u128 into r305; + shr r302 64u8 into r306; + mul r303 r305 into r307; + mul r303 r306 into r308; + mul r304 r305 into r309; + mul r304 r306 into r310; + and r307 18446744073709551615u128 into r311; + shr r307 64u8 into r312; + and r308 18446744073709551615u128 into r313; + add r312 r313 into r314; + and r309 18446744073709551615u128 into r315; + add r314 r315 into r316; + and r316 18446744073709551615u128 into r317; + shr r316 64u8 into r318; + shr r308 64u8 into r319; + shr r309 64u8 into r320; + add r319 r320 into r321; + and r310 18446744073709551615u128 into r322; + add r321 r322 into r323; + add r323 r318 into r324; + and r324 18446744073709551615u128 into r325; + shr r324 64u8 into r326; + shr r310 64u8 into r327; + add r327 r326 into r328; + shl r317 64u8 into r329; + add r329 r311 into r330; + shl r328 64u8 into r331; + add r331 r325 into r332; + lt r332 1000000u128 into r333; + assert.eq r333 true; + shr r330 96u8 into r334; + and r334 4294967295u128 into r335; + shl r332 32u8 into r336; + add r336 r335 into r337; + div r337 1000000u128 into r338; + rem r337 1000000u128 into r339; + shr r330 64u8 into r340; + and r340 4294967295u128 into r341; + shl r339 32u8 into r342; + add r342 r341 into r343; + shl r338 32u8 into r344; + div r343 1000000u128 into r345; + add r344 r345 into r346; + rem r343 1000000u128 into r347; + shr r330 32u8 into r348; + and r348 4294967295u128 into r349; + shl r347 32u8 into r350; + add r350 r349 into r351; + shl r346 32u8 into r352; + div r351 1000000u128 into r353; + add r352 r353 into r354; + rem r351 1000000u128 into r355; + shr r330 0u8 into r356; + and r356 4294967295u128 into r357; + shl r355 32u8 into r358; + add r358 r357 into r359; + shl r354 32u8 into r360; + div r359 1000000u128 into r361; + add r360 r361 into r362; + rem r359 1000000u128 into r363; + add r362 1u128 into r364; + gte r362 r300 into r365; + is.eq r362 0u128 into r366; + shl r189 64u8 into r367; + add r367 r188 into r368; + lt r368 r3.sp into r369; + assert.eq r369 true; + shl r368 32u8 into r370; + add r370 r196 into r371; + div r371 r3.sp into r372; + rem r371 r3.sp into r373; + shl r373 32u8 into r374; + add r374 r202 into r375; + shl r372 32u8 into r376; + div r375 r3.sp into r377; + add r376 r377 into r378; + rem r375 r3.sp into r379; + shl r379 32u8 into r380; + add r380 r210 into r381; + shl r378 32u8 into r382; + div r381 r3.sp into r383; + add r382 r383 into r384; + rem r381 r3.sp into r385; + shl r385 32u8 into r386; + add r386 r218 into r387; + shl r384 32u8 into r388; + div r387 r3.sp into r389; + add r388 r389 into r390; + rem r387 r3.sp into r391; + add r390 1u128 into r392; + add r390 r362 into r393; + gt r362 r390 into r394; + ternary r394 r390 r362 into r395; + sub r390 r395 into r396; + lt r368 r393 into r397; + assert.eq r397 true; + gte r368 170141183460469231731687303715884105728u128 into r398; + add.w r368 r368 into r399; + shr r191 127u8 into r400; + and r400 1u128 into r401; + add r399 r401 into r402; + gte r402 r393 into r403; + or r398 r403 into r404; + sub.w r402 r393 into r405; + ternary r404 r405 r402 into r406; + ternary r404 170141183460469231731687303715884105728u128 0u128 into r407; + gte r406 170141183460469231731687303715884105728u128 into r408; + add.w r406 r406 into r409; + shr r191 126u8 into r410; + and r410 1u128 into r411; + add r409 r411 into r412; + gte r412 r393 into r413; + or r408 r413 into r414; + sub.w r412 r393 into r415; + ternary r414 r415 r412 into r416; + add r407 85070591730234615865843651857942052864u128 into r417; + ternary r414 r417 r407 into r418; + gte r416 170141183460469231731687303715884105728u128 into r419; + add.w r416 r416 into r420; + shr r191 125u8 into r421; + and r421 1u128 into r422; + add r420 r422 into r423; + gte r423 r393 into r424; + or r419 r424 into r425; + sub.w r423 r393 into r426; + ternary r425 r426 r423 into r427; + add r418 42535295865117307932921825928971026432u128 into r428; + ternary r425 r428 r418 into r429; + gte r427 170141183460469231731687303715884105728u128 into r430; + add.w r427 r427 into r431; + shr r191 124u8 into r432; + and r432 1u128 into r433; + add r431 r433 into r434; + gte r434 r393 into r435; + or r430 r435 into r436; + sub.w r434 r393 into r437; + ternary r436 r437 r434 into r438; + add r429 21267647932558653966460912964485513216u128 into r439; + ternary r436 r439 r429 into r440; + gte r438 170141183460469231731687303715884105728u128 into r441; + add.w r438 r438 into r442; + shr r191 123u8 into r443; + and r443 1u128 into r444; + add r442 r444 into r445; + gte r445 r393 into r446; + or r441 r446 into r447; + sub.w r445 r393 into r448; + ternary r447 r448 r445 into r449; + add r440 10633823966279326983230456482242756608u128 into r450; + ternary r447 r450 r440 into r451; + gte r449 170141183460469231731687303715884105728u128 into r452; + add.w r449 r449 into r453; + shr r191 122u8 into r454; + and r454 1u128 into r455; + add r453 r455 into r456; + gte r456 r393 into r457; + or r452 r457 into r458; + sub.w r456 r393 into r459; + ternary r458 r459 r456 into r460; + add r451 5316911983139663491615228241121378304u128 into r461; + ternary r458 r461 r451 into r462; + gte r460 170141183460469231731687303715884105728u128 into r463; + add.w r460 r460 into r464; + shr r191 121u8 into r465; + and r465 1u128 into r466; + add r464 r466 into r467; + gte r467 r393 into r468; + or r463 r468 into r469; + sub.w r467 r393 into r470; + ternary r469 r470 r467 into r471; + add r462 2658455991569831745807614120560689152u128 into r472; + ternary r469 r472 r462 into r473; + gte r471 170141183460469231731687303715884105728u128 into r474; + add.w r471 r471 into r475; + shr r191 120u8 into r476; + and r476 1u128 into r477; + add r475 r477 into r478; + gte r478 r393 into r479; + or r474 r479 into r480; + sub.w r478 r393 into r481; + ternary r480 r481 r478 into r482; + add r473 1329227995784915872903807060280344576u128 into r483; + ternary r480 r483 r473 into r484; + gte r482 170141183460469231731687303715884105728u128 into r485; + add.w r482 r482 into r486; + shr r191 119u8 into r487; + and r487 1u128 into r488; + add r486 r488 into r489; + gte r489 r393 into r490; + or r485 r490 into r491; + sub.w r489 r393 into r492; + ternary r491 r492 r489 into r493; + add r484 664613997892457936451903530140172288u128 into r494; + ternary r491 r494 r484 into r495; + gte r493 170141183460469231731687303715884105728u128 into r496; + add.w r493 r493 into r497; + shr r191 118u8 into r498; + and r498 1u128 into r499; + add r497 r499 into r500; + gte r500 r393 into r501; + or r496 r501 into r502; + sub.w r500 r393 into r503; + ternary r502 r503 r500 into r504; + add r495 332306998946228968225951765070086144u128 into r505; + ternary r502 r505 r495 into r506; + gte r504 170141183460469231731687303715884105728u128 into r507; + add.w r504 r504 into r508; + shr r191 117u8 into r509; + and r509 1u128 into r510; + add r508 r510 into r511; + gte r511 r393 into r512; + or r507 r512 into r513; + sub.w r511 r393 into r514; + ternary r513 r514 r511 into r515; + add r506 166153499473114484112975882535043072u128 into r516; + ternary r513 r516 r506 into r517; + gte r515 170141183460469231731687303715884105728u128 into r518; + add.w r515 r515 into r519; + shr r191 116u8 into r520; + and r520 1u128 into r521; + add r519 r521 into r522; + gte r522 r393 into r523; + or r518 r523 into r524; + sub.w r522 r393 into r525; + ternary r524 r525 r522 into r526; + add r517 83076749736557242056487941267521536u128 into r527; + ternary r524 r527 r517 into r528; + gte r526 170141183460469231731687303715884105728u128 into r529; + add.w r526 r526 into r530; + shr r191 115u8 into r531; + and r531 1u128 into r532; + add r530 r532 into r533; + gte r533 r393 into r534; + or r529 r534 into r535; + sub.w r533 r393 into r536; + ternary r535 r536 r533 into r537; + add r528 41538374868278621028243970633760768u128 into r538; + ternary r535 r538 r528 into r539; + gte r537 170141183460469231731687303715884105728u128 into r540; + add.w r537 r537 into r541; + shr r191 114u8 into r542; + and r542 1u128 into r543; + add r541 r543 into r544; + gte r544 r393 into r545; + or r540 r545 into r546; + sub.w r544 r393 into r547; + ternary r546 r547 r544 into r548; + add r539 20769187434139310514121985316880384u128 into r549; + ternary r546 r549 r539 into r550; + gte r548 170141183460469231731687303715884105728u128 into r551; + add.w r548 r548 into r552; + shr r191 113u8 into r553; + and r553 1u128 into r554; + add r552 r554 into r555; + gte r555 r393 into r556; + or r551 r556 into r557; + sub.w r555 r393 into r558; + ternary r557 r558 r555 into r559; + add r550 10384593717069655257060992658440192u128 into r560; + ternary r557 r560 r550 into r561; + gte r559 170141183460469231731687303715884105728u128 into r562; + add.w r559 r559 into r563; + shr r191 112u8 into r564; + and r564 1u128 into r565; + add r563 r565 into r566; + gte r566 r393 into r567; + or r562 r567 into r568; + sub.w r566 r393 into r569; + ternary r568 r569 r566 into r570; + add r561 5192296858534827628530496329220096u128 into r571; + ternary r568 r571 r561 into r572; + gte r570 170141183460469231731687303715884105728u128 into r573; + add.w r570 r570 into r574; + shr r191 111u8 into r575; + and r575 1u128 into r576; + add r574 r576 into r577; + gte r577 r393 into r578; + or r573 r578 into r579; + sub.w r577 r393 into r580; + ternary r579 r580 r577 into r581; + add r572 2596148429267413814265248164610048u128 into r582; + ternary r579 r582 r572 into r583; + gte r581 170141183460469231731687303715884105728u128 into r584; + add.w r581 r581 into r585; + shr r191 110u8 into r586; + and r586 1u128 into r587; + add r585 r587 into r588; + gte r588 r393 into r589; + or r584 r589 into r590; + sub.w r588 r393 into r591; + ternary r590 r591 r588 into r592; + add r583 1298074214633706907132624082305024u128 into r593; + ternary r590 r593 r583 into r594; + gte r592 170141183460469231731687303715884105728u128 into r595; + add.w r592 r592 into r596; + shr r191 109u8 into r597; + and r597 1u128 into r598; + add r596 r598 into r599; + gte r599 r393 into r600; + or r595 r600 into r601; + sub.w r599 r393 into r602; + ternary r601 r602 r599 into r603; + add r594 649037107316853453566312041152512u128 into r604; + ternary r601 r604 r594 into r605; + gte r603 170141183460469231731687303715884105728u128 into r606; + add.w r603 r603 into r607; + shr r191 108u8 into r608; + and r608 1u128 into r609; + add r607 r609 into r610; + gte r610 r393 into r611; + or r606 r611 into r612; + sub.w r610 r393 into r613; + ternary r612 r613 r610 into r614; + add r605 324518553658426726783156020576256u128 into r615; + ternary r612 r615 r605 into r616; + gte r614 170141183460469231731687303715884105728u128 into r617; + add.w r614 r614 into r618; + shr r191 107u8 into r619; + and r619 1u128 into r620; + add r618 r620 into r621; + gte r621 r393 into r622; + or r617 r622 into r623; + sub.w r621 r393 into r624; + ternary r623 r624 r621 into r625; + add r616 162259276829213363391578010288128u128 into r626; + ternary r623 r626 r616 into r627; + gte r625 170141183460469231731687303715884105728u128 into r628; + add.w r625 r625 into r629; + shr r191 106u8 into r630; + and r630 1u128 into r631; + add r629 r631 into r632; + gte r632 r393 into r633; + or r628 r633 into r634; + sub.w r632 r393 into r635; + ternary r634 r635 r632 into r636; + add r627 81129638414606681695789005144064u128 into r637; + ternary r634 r637 r627 into r638; + gte r636 170141183460469231731687303715884105728u128 into r639; + add.w r636 r636 into r640; + shr r191 105u8 into r641; + and r641 1u128 into r642; + add r640 r642 into r643; + gte r643 r393 into r644; + or r639 r644 into r645; + sub.w r643 r393 into r646; + ternary r645 r646 r643 into r647; + add r638 40564819207303340847894502572032u128 into r648; + ternary r645 r648 r638 into r649; + gte r647 170141183460469231731687303715884105728u128 into r650; + add.w r647 r647 into r651; + shr r191 104u8 into r652; + and r652 1u128 into r653; + add r651 r653 into r654; + gte r654 r393 into r655; + or r650 r655 into r656; + sub.w r654 r393 into r657; + ternary r656 r657 r654 into r658; + add r649 20282409603651670423947251286016u128 into r659; + ternary r656 r659 r649 into r660; + gte r658 170141183460469231731687303715884105728u128 into r661; + add.w r658 r658 into r662; + shr r191 103u8 into r663; + and r663 1u128 into r664; + add r662 r664 into r665; + gte r665 r393 into r666; + or r661 r666 into r667; + sub.w r665 r393 into r668; + ternary r667 r668 r665 into r669; + add r660 10141204801825835211973625643008u128 into r670; + ternary r667 r670 r660 into r671; + gte r669 170141183460469231731687303715884105728u128 into r672; + add.w r669 r669 into r673; + shr r191 102u8 into r674; + and r674 1u128 into r675; + add r673 r675 into r676; + gte r676 r393 into r677; + or r672 r677 into r678; + sub.w r676 r393 into r679; + ternary r678 r679 r676 into r680; + add r671 5070602400912917605986812821504u128 into r681; + ternary r678 r681 r671 into r682; + gte r680 170141183460469231731687303715884105728u128 into r683; + add.w r680 r680 into r684; + shr r191 101u8 into r685; + and r685 1u128 into r686; + add r684 r686 into r687; + gte r687 r393 into r688; + or r683 r688 into r689; + sub.w r687 r393 into r690; + ternary r689 r690 r687 into r691; + add r682 2535301200456458802993406410752u128 into r692; + ternary r689 r692 r682 into r693; + gte r691 170141183460469231731687303715884105728u128 into r694; + add.w r691 r691 into r695; + shr r191 100u8 into r696; + and r696 1u128 into r697; + add r695 r697 into r698; + gte r698 r393 into r699; + or r694 r699 into r700; + sub.w r698 r393 into r701; + ternary r700 r701 r698 into r702; + add r693 1267650600228229401496703205376u128 into r703; + ternary r700 r703 r693 into r704; + gte r702 170141183460469231731687303715884105728u128 into r705; + add.w r702 r702 into r706; + shr r191 99u8 into r707; + and r707 1u128 into r708; + add r706 r708 into r709; + gte r709 r393 into r710; + or r705 r710 into r711; + sub.w r709 r393 into r712; + ternary r711 r712 r709 into r713; + add r704 633825300114114700748351602688u128 into r714; + ternary r711 r714 r704 into r715; + gte r713 170141183460469231731687303715884105728u128 into r716; + add.w r713 r713 into r717; + shr r191 98u8 into r718; + and r718 1u128 into r719; + add r717 r719 into r720; + gte r720 r393 into r721; + or r716 r721 into r722; + sub.w r720 r393 into r723; + ternary r722 r723 r720 into r724; + add r715 316912650057057350374175801344u128 into r725; + ternary r722 r725 r715 into r726; + gte r724 170141183460469231731687303715884105728u128 into r727; + add.w r724 r724 into r728; + shr r191 97u8 into r729; + and r729 1u128 into r730; + add r728 r730 into r731; + gte r731 r393 into r732; + or r727 r732 into r733; + sub.w r731 r393 into r734; + ternary r733 r734 r731 into r735; + add r726 158456325028528675187087900672u128 into r736; + ternary r733 r736 r726 into r737; + gte r735 170141183460469231731687303715884105728u128 into r738; + add.w r735 r735 into r739; + and r195 1u128 into r740; + add r739 r740 into r741; + gte r741 r393 into r742; + or r738 r742 into r743; + sub.w r741 r393 into r744; + ternary r743 r744 r741 into r745; + add r737 79228162514264337593543950336u128 into r746; + ternary r743 r746 r737 into r747; + gte r745 170141183460469231731687303715884105728u128 into r748; + add.w r745 r745 into r749; + shr r191 95u8 into r750; + and r750 1u128 into r751; + add r749 r751 into r752; + gte r752 r393 into r753; + or r748 r753 into r754; + sub.w r752 r393 into r755; + ternary r754 r755 r752 into r756; + add r747 39614081257132168796771975168u128 into r757; + ternary r754 r757 r747 into r758; + gte r756 170141183460469231731687303715884105728u128 into r759; + add.w r756 r756 into r760; + shr r191 94u8 into r761; + and r761 1u128 into r762; + add r760 r762 into r763; + gte r763 r393 into r764; + or r759 r764 into r765; + sub.w r763 r393 into r766; + ternary r765 r766 r763 into r767; + add r758 19807040628566084398385987584u128 into r768; + ternary r765 r768 r758 into r769; + gte r767 170141183460469231731687303715884105728u128 into r770; + add.w r767 r767 into r771; + shr r191 93u8 into r772; + and r772 1u128 into r773; + add r771 r773 into r774; + gte r774 r393 into r775; + or r770 r775 into r776; + sub.w r774 r393 into r777; + ternary r776 r777 r774 into r778; + add r769 9903520314283042199192993792u128 into r779; + ternary r776 r779 r769 into r780; + gte r778 170141183460469231731687303715884105728u128 into r781; + add.w r778 r778 into r782; + shr r191 92u8 into r783; + and r783 1u128 into r784; + add r782 r784 into r785; + gte r785 r393 into r786; + or r781 r786 into r787; + sub.w r785 r393 into r788; + ternary r787 r788 r785 into r789; + add r780 4951760157141521099596496896u128 into r790; + ternary r787 r790 r780 into r791; + gte r789 170141183460469231731687303715884105728u128 into r792; + add.w r789 r789 into r793; + shr r191 91u8 into r794; + and r794 1u128 into r795; + add r793 r795 into r796; + gte r796 r393 into r797; + or r792 r797 into r798; + sub.w r796 r393 into r799; + ternary r798 r799 r796 into r800; + add r791 2475880078570760549798248448u128 into r801; + ternary r798 r801 r791 into r802; + gte r800 170141183460469231731687303715884105728u128 into r803; + add.w r800 r800 into r804; + shr r191 90u8 into r805; + and r805 1u128 into r806; + add r804 r806 into r807; + gte r807 r393 into r808; + or r803 r808 into r809; + sub.w r807 r393 into r810; + ternary r809 r810 r807 into r811; + add r802 1237940039285380274899124224u128 into r812; + ternary r809 r812 r802 into r813; + gte r811 170141183460469231731687303715884105728u128 into r814; + add.w r811 r811 into r815; + shr r191 89u8 into r816; + and r816 1u128 into r817; + add r815 r817 into r818; + gte r818 r393 into r819; + or r814 r819 into r820; + sub.w r818 r393 into r821; + ternary r820 r821 r818 into r822; + add r813 618970019642690137449562112u128 into r823; + ternary r820 r823 r813 into r824; + gte r822 170141183460469231731687303715884105728u128 into r825; + add.w r822 r822 into r826; + shr r191 88u8 into r827; + and r827 1u128 into r828; + add r826 r828 into r829; + gte r829 r393 into r830; + or r825 r830 into r831; + sub.w r829 r393 into r832; + ternary r831 r832 r829 into r833; + add r824 309485009821345068724781056u128 into r834; + ternary r831 r834 r824 into r835; + gte r833 170141183460469231731687303715884105728u128 into r836; + add.w r833 r833 into r837; + shr r191 87u8 into r838; + and r838 1u128 into r839; + add r837 r839 into r840; + gte r840 r393 into r841; + or r836 r841 into r842; + sub.w r840 r393 into r843; + ternary r842 r843 r840 into r844; + add r835 154742504910672534362390528u128 into r845; + ternary r842 r845 r835 into r846; + gte r844 170141183460469231731687303715884105728u128 into r847; + add.w r844 r844 into r848; + shr r191 86u8 into r849; + and r849 1u128 into r850; + add r848 r850 into r851; + gte r851 r393 into r852; + or r847 r852 into r853; + sub.w r851 r393 into r854; + ternary r853 r854 r851 into r855; + add r846 77371252455336267181195264u128 into r856; + ternary r853 r856 r846 into r857; + gte r855 170141183460469231731687303715884105728u128 into r858; + add.w r855 r855 into r859; + shr r191 85u8 into r860; + and r860 1u128 into r861; + add r859 r861 into r862; + gte r862 r393 into r863; + or r858 r863 into r864; + sub.w r862 r393 into r865; + ternary r864 r865 r862 into r866; + add r857 38685626227668133590597632u128 into r867; + ternary r864 r867 r857 into r868; + gte r866 170141183460469231731687303715884105728u128 into r869; + add.w r866 r866 into r870; + shr r191 84u8 into r871; + and r871 1u128 into r872; + add r870 r872 into r873; + gte r873 r393 into r874; + or r869 r874 into r875; + sub.w r873 r393 into r876; + ternary r875 r876 r873 into r877; + add r868 19342813113834066795298816u128 into r878; + ternary r875 r878 r868 into r879; + gte r877 170141183460469231731687303715884105728u128 into r880; + add.w r877 r877 into r881; + shr r191 83u8 into r882; + and r882 1u128 into r883; + add r881 r883 into r884; + gte r884 r393 into r885; + or r880 r885 into r886; + sub.w r884 r393 into r887; + ternary r886 r887 r884 into r888; + add r879 9671406556917033397649408u128 into r889; + ternary r886 r889 r879 into r890; + gte r888 170141183460469231731687303715884105728u128 into r891; + add.w r888 r888 into r892; + shr r191 82u8 into r893; + and r893 1u128 into r894; + add r892 r894 into r895; + gte r895 r393 into r896; + or r891 r896 into r897; + sub.w r895 r393 into r898; + ternary r897 r898 r895 into r899; + add r890 4835703278458516698824704u128 into r900; + ternary r897 r900 r890 into r901; + gte r899 170141183460469231731687303715884105728u128 into r902; + add.w r899 r899 into r903; + shr r191 81u8 into r904; + and r904 1u128 into r905; + add r903 r905 into r906; + gte r906 r393 into r907; + or r902 r907 into r908; + sub.w r906 r393 into r909; + ternary r908 r909 r906 into r910; + add r901 2417851639229258349412352u128 into r911; + ternary r908 r911 r901 into r912; + gte r910 170141183460469231731687303715884105728u128 into r913; + add.w r910 r910 into r914; + shr r191 80u8 into r915; + and r915 1u128 into r916; + add r914 r916 into r917; + gte r917 r393 into r918; + or r913 r918 into r919; + sub.w r917 r393 into r920; + ternary r919 r920 r917 into r921; + add r912 1208925819614629174706176u128 into r922; + ternary r919 r922 r912 into r923; + gte r921 170141183460469231731687303715884105728u128 into r924; + add.w r921 r921 into r925; + shr r191 79u8 into r926; + and r926 1u128 into r927; + add r925 r927 into r928; + gte r928 r393 into r929; + or r924 r929 into r930; + sub.w r928 r393 into r931; + ternary r930 r931 r928 into r932; + add r923 604462909807314587353088u128 into r933; + ternary r930 r933 r923 into r934; + gte r932 170141183460469231731687303715884105728u128 into r935; + add.w r932 r932 into r936; + shr r191 78u8 into r937; + and r937 1u128 into r938; + add r936 r938 into r939; + gte r939 r393 into r940; + or r935 r940 into r941; + sub.w r939 r393 into r942; + ternary r941 r942 r939 into r943; + add r934 302231454903657293676544u128 into r944; + ternary r941 r944 r934 into r945; + gte r943 170141183460469231731687303715884105728u128 into r946; + add.w r943 r943 into r947; + shr r191 77u8 into r948; + and r948 1u128 into r949; + add r947 r949 into r950; + gte r950 r393 into r951; + or r946 r951 into r952; + sub.w r950 r393 into r953; + ternary r952 r953 r950 into r954; + add r945 151115727451828646838272u128 into r955; + ternary r952 r955 r945 into r956; + gte r954 170141183460469231731687303715884105728u128 into r957; + add.w r954 r954 into r958; + shr r191 76u8 into r959; + and r959 1u128 into r960; + add r958 r960 into r961; + gte r961 r393 into r962; + or r957 r962 into r963; + sub.w r961 r393 into r964; + ternary r963 r964 r961 into r965; + add r956 75557863725914323419136u128 into r966; + ternary r963 r966 r956 into r967; + gte r965 170141183460469231731687303715884105728u128 into r968; + add.w r965 r965 into r969; + shr r191 75u8 into r970; + and r970 1u128 into r971; + add r969 r971 into r972; + gte r972 r393 into r973; + or r968 r973 into r974; + sub.w r972 r393 into r975; + ternary r974 r975 r972 into r976; + add r967 37778931862957161709568u128 into r977; + ternary r974 r977 r967 into r978; + gte r976 170141183460469231731687303715884105728u128 into r979; + add.w r976 r976 into r980; + shr r191 74u8 into r981; + and r981 1u128 into r982; + add r980 r982 into r983; + gte r983 r393 into r984; + or r979 r984 into r985; + sub.w r983 r393 into r986; + ternary r985 r986 r983 into r987; + add r978 18889465931478580854784u128 into r988; + ternary r985 r988 r978 into r989; + gte r987 170141183460469231731687303715884105728u128 into r990; + add.w r987 r987 into r991; + shr r191 73u8 into r992; + and r992 1u128 into r993; + add r991 r993 into r994; + gte r994 r393 into r995; + or r990 r995 into r996; + sub.w r994 r393 into r997; + ternary r996 r997 r994 into r998; + add r989 9444732965739290427392u128 into r999; + ternary r996 r999 r989 into r1000; + gte r998 170141183460469231731687303715884105728u128 into r1001; + add.w r998 r998 into r1002; + shr r191 72u8 into r1003; + and r1003 1u128 into r1004; + add r1002 r1004 into r1005; + gte r1005 r393 into r1006; + or r1001 r1006 into r1007; + sub.w r1005 r393 into r1008; + ternary r1007 r1008 r1005 into r1009; + add r1000 4722366482869645213696u128 into r1010; + ternary r1007 r1010 r1000 into r1011; + gte r1009 170141183460469231731687303715884105728u128 into r1012; + add.w r1009 r1009 into r1013; + shr r191 71u8 into r1014; + and r1014 1u128 into r1015; + add r1013 r1015 into r1016; + gte r1016 r393 into r1017; + or r1012 r1017 into r1018; + sub.w r1016 r393 into r1019; + ternary r1018 r1019 r1016 into r1020; + add r1011 2361183241434822606848u128 into r1021; + ternary r1018 r1021 r1011 into r1022; + gte r1020 170141183460469231731687303715884105728u128 into r1023; + add.w r1020 r1020 into r1024; + shr r191 70u8 into r1025; + and r1025 1u128 into r1026; + add r1024 r1026 into r1027; + gte r1027 r393 into r1028; + or r1023 r1028 into r1029; + sub.w r1027 r393 into r1030; + ternary r1029 r1030 r1027 into r1031; + add r1022 1180591620717411303424u128 into r1032; + ternary r1029 r1032 r1022 into r1033; + gte r1031 170141183460469231731687303715884105728u128 into r1034; + add.w r1031 r1031 into r1035; + shr r191 69u8 into r1036; + and r1036 1u128 into r1037; + add r1035 r1037 into r1038; + gte r1038 r393 into r1039; + or r1034 r1039 into r1040; + sub.w r1038 r393 into r1041; + ternary r1040 r1041 r1038 into r1042; + add r1033 590295810358705651712u128 into r1043; + ternary r1040 r1043 r1033 into r1044; + gte r1042 170141183460469231731687303715884105728u128 into r1045; + add.w r1042 r1042 into r1046; + shr r191 68u8 into r1047; + and r1047 1u128 into r1048; + add r1046 r1048 into r1049; + gte r1049 r393 into r1050; + or r1045 r1050 into r1051; + sub.w r1049 r393 into r1052; + ternary r1051 r1052 r1049 into r1053; + add r1044 295147905179352825856u128 into r1054; + ternary r1051 r1054 r1044 into r1055; + gte r1053 170141183460469231731687303715884105728u128 into r1056; + add.w r1053 r1053 into r1057; + shr r191 67u8 into r1058; + and r1058 1u128 into r1059; + add r1057 r1059 into r1060; + gte r1060 r393 into r1061; + or r1056 r1061 into r1062; + sub.w r1060 r393 into r1063; + ternary r1062 r1063 r1060 into r1064; + add r1055 147573952589676412928u128 into r1065; + ternary r1062 r1065 r1055 into r1066; + gte r1064 170141183460469231731687303715884105728u128 into r1067; + add.w r1064 r1064 into r1068; + shr r191 66u8 into r1069; + and r1069 1u128 into r1070; + add r1068 r1070 into r1071; + gte r1071 r393 into r1072; + or r1067 r1072 into r1073; + sub.w r1071 r393 into r1074; + ternary r1073 r1074 r1071 into r1075; + add r1066 73786976294838206464u128 into r1076; + ternary r1073 r1076 r1066 into r1077; + gte r1075 170141183460469231731687303715884105728u128 into r1078; + add.w r1075 r1075 into r1079; + shr r191 65u8 into r1080; + and r1080 1u128 into r1081; + add r1079 r1081 into r1082; + gte r1082 r393 into r1083; + or r1078 r1083 into r1084; + sub.w r1082 r393 into r1085; + ternary r1084 r1085 r1082 into r1086; + add r1077 36893488147419103232u128 into r1087; + ternary r1084 r1087 r1077 into r1088; + gte r1086 170141183460469231731687303715884105728u128 into r1089; + add.w r1086 r1086 into r1090; + and r201 1u128 into r1091; + add r1090 r1091 into r1092; + gte r1092 r393 into r1093; + or r1089 r1093 into r1094; + sub.w r1092 r393 into r1095; + ternary r1094 r1095 r1092 into r1096; + add r1088 18446744073709551616u128 into r1097; + ternary r1094 r1097 r1088 into r1098; + gte r1096 170141183460469231731687303715884105728u128 into r1099; + add.w r1096 r1096 into r1100; + shr r191 63u8 into r1101; + and r1101 1u128 into r1102; + add r1100 r1102 into r1103; + gte r1103 r393 into r1104; + or r1099 r1104 into r1105; + sub.w r1103 r393 into r1106; + ternary r1105 r1106 r1103 into r1107; + add r1098 9223372036854775808u128 into r1108; + ternary r1105 r1108 r1098 into r1109; + gte r1107 170141183460469231731687303715884105728u128 into r1110; + add.w r1107 r1107 into r1111; + shr r191 62u8 into r1112; + and r1112 1u128 into r1113; + add r1111 r1113 into r1114; + gte r1114 r393 into r1115; + or r1110 r1115 into r1116; + sub.w r1114 r393 into r1117; + ternary r1116 r1117 r1114 into r1118; + add r1109 4611686018427387904u128 into r1119; + ternary r1116 r1119 r1109 into r1120; + gte r1118 170141183460469231731687303715884105728u128 into r1121; + add.w r1118 r1118 into r1122; + shr r191 61u8 into r1123; + and r1123 1u128 into r1124; + add r1122 r1124 into r1125; + gte r1125 r393 into r1126; + or r1121 r1126 into r1127; + sub.w r1125 r393 into r1128; + ternary r1127 r1128 r1125 into r1129; + add r1120 2305843009213693952u128 into r1130; + ternary r1127 r1130 r1120 into r1131; + gte r1129 170141183460469231731687303715884105728u128 into r1132; + add.w r1129 r1129 into r1133; + shr r191 60u8 into r1134; + and r1134 1u128 into r1135; + add r1133 r1135 into r1136; + gte r1136 r393 into r1137; + or r1132 r1137 into r1138; + sub.w r1136 r393 into r1139; + ternary r1138 r1139 r1136 into r1140; + add r1131 1152921504606846976u128 into r1141; + ternary r1138 r1141 r1131 into r1142; + gte r1140 170141183460469231731687303715884105728u128 into r1143; + add.w r1140 r1140 into r1144; + shr r191 59u8 into r1145; + and r1145 1u128 into r1146; + add r1144 r1146 into r1147; + gte r1147 r393 into r1148; + or r1143 r1148 into r1149; + sub.w r1147 r393 into r1150; + ternary r1149 r1150 r1147 into r1151; + add r1142 576460752303423488u128 into r1152; + ternary r1149 r1152 r1142 into r1153; + gte r1151 170141183460469231731687303715884105728u128 into r1154; + add.w r1151 r1151 into r1155; + shr r191 58u8 into r1156; + and r1156 1u128 into r1157; + add r1155 r1157 into r1158; + gte r1158 r393 into r1159; + or r1154 r1159 into r1160; + sub.w r1158 r393 into r1161; + ternary r1160 r1161 r1158 into r1162; + add r1153 288230376151711744u128 into r1163; + ternary r1160 r1163 r1153 into r1164; + gte r1162 170141183460469231731687303715884105728u128 into r1165; + add.w r1162 r1162 into r1166; + shr r191 57u8 into r1167; + and r1167 1u128 into r1168; + add r1166 r1168 into r1169; + gte r1169 r393 into r1170; + or r1165 r1170 into r1171; + sub.w r1169 r393 into r1172; + ternary r1171 r1172 r1169 into r1173; + add r1164 144115188075855872u128 into r1174; + ternary r1171 r1174 r1164 into r1175; + gte r1173 170141183460469231731687303715884105728u128 into r1176; + add.w r1173 r1173 into r1177; + shr r191 56u8 into r1178; + and r1178 1u128 into r1179; + add r1177 r1179 into r1180; + gte r1180 r393 into r1181; + or r1176 r1181 into r1182; + sub.w r1180 r393 into r1183; + ternary r1182 r1183 r1180 into r1184; + add r1175 72057594037927936u128 into r1185; + ternary r1182 r1185 r1175 into r1186; + gte r1184 170141183460469231731687303715884105728u128 into r1187; + add.w r1184 r1184 into r1188; + shr r191 55u8 into r1189; + and r1189 1u128 into r1190; + add r1188 r1190 into r1191; + gte r1191 r393 into r1192; + or r1187 r1192 into r1193; + sub.w r1191 r393 into r1194; + ternary r1193 r1194 r1191 into r1195; + add r1186 36028797018963968u128 into r1196; + ternary r1193 r1196 r1186 into r1197; + gte r1195 170141183460469231731687303715884105728u128 into r1198; + add.w r1195 r1195 into r1199; + shr r191 54u8 into r1200; + and r1200 1u128 into r1201; + add r1199 r1201 into r1202; + gte r1202 r393 into r1203; + or r1198 r1203 into r1204; + sub.w r1202 r393 into r1205; + ternary r1204 r1205 r1202 into r1206; + add r1197 18014398509481984u128 into r1207; + ternary r1204 r1207 r1197 into r1208; + gte r1206 170141183460469231731687303715884105728u128 into r1209; + add.w r1206 r1206 into r1210; + shr r191 53u8 into r1211; + and r1211 1u128 into r1212; + add r1210 r1212 into r1213; + gte r1213 r393 into r1214; + or r1209 r1214 into r1215; + sub.w r1213 r393 into r1216; + ternary r1215 r1216 r1213 into r1217; + add r1208 9007199254740992u128 into r1218; + ternary r1215 r1218 r1208 into r1219; + gte r1217 170141183460469231731687303715884105728u128 into r1220; + add.w r1217 r1217 into r1221; + shr r191 52u8 into r1222; + and r1222 1u128 into r1223; + add r1221 r1223 into r1224; + gte r1224 r393 into r1225; + or r1220 r1225 into r1226; + sub.w r1224 r393 into r1227; + ternary r1226 r1227 r1224 into r1228; + add r1219 4503599627370496u128 into r1229; + ternary r1226 r1229 r1219 into r1230; + gte r1228 170141183460469231731687303715884105728u128 into r1231; + add.w r1228 r1228 into r1232; + shr r191 51u8 into r1233; + and r1233 1u128 into r1234; + add r1232 r1234 into r1235; + gte r1235 r393 into r1236; + or r1231 r1236 into r1237; + sub.w r1235 r393 into r1238; + ternary r1237 r1238 r1235 into r1239; + add r1230 2251799813685248u128 into r1240; + ternary r1237 r1240 r1230 into r1241; + gte r1239 170141183460469231731687303715884105728u128 into r1242; + add.w r1239 r1239 into r1243; + shr r191 50u8 into r1244; + and r1244 1u128 into r1245; + add r1243 r1245 into r1246; + gte r1246 r393 into r1247; + or r1242 r1247 into r1248; + sub.w r1246 r393 into r1249; + ternary r1248 r1249 r1246 into r1250; + add r1241 1125899906842624u128 into r1251; + ternary r1248 r1251 r1241 into r1252; + gte r1250 170141183460469231731687303715884105728u128 into r1253; + add.w r1250 r1250 into r1254; + shr r191 49u8 into r1255; + and r1255 1u128 into r1256; + add r1254 r1256 into r1257; + gte r1257 r393 into r1258; + or r1253 r1258 into r1259; + sub.w r1257 r393 into r1260; + ternary r1259 r1260 r1257 into r1261; + add r1252 562949953421312u128 into r1262; + ternary r1259 r1262 r1252 into r1263; + gte r1261 170141183460469231731687303715884105728u128 into r1264; + add.w r1261 r1261 into r1265; + shr r191 48u8 into r1266; + and r1266 1u128 into r1267; + add r1265 r1267 into r1268; + gte r1268 r393 into r1269; + or r1264 r1269 into r1270; + sub.w r1268 r393 into r1271; + ternary r1270 r1271 r1268 into r1272; + add r1263 281474976710656u128 into r1273; + ternary r1270 r1273 r1263 into r1274; + gte r1272 170141183460469231731687303715884105728u128 into r1275; + add.w r1272 r1272 into r1276; + shr r191 47u8 into r1277; + and r1277 1u128 into r1278; + add r1276 r1278 into r1279; + gte r1279 r393 into r1280; + or r1275 r1280 into r1281; + sub.w r1279 r393 into r1282; + ternary r1281 r1282 r1279 into r1283; + add r1274 140737488355328u128 into r1284; + ternary r1281 r1284 r1274 into r1285; + gte r1283 170141183460469231731687303715884105728u128 into r1286; + add.w r1283 r1283 into r1287; + shr r191 46u8 into r1288; + and r1288 1u128 into r1289; + add r1287 r1289 into r1290; + gte r1290 r393 into r1291; + or r1286 r1291 into r1292; + sub.w r1290 r393 into r1293; + ternary r1292 r1293 r1290 into r1294; + add r1285 70368744177664u128 into r1295; + ternary r1292 r1295 r1285 into r1296; + gte r1294 170141183460469231731687303715884105728u128 into r1297; + add.w r1294 r1294 into r1298; + shr r191 45u8 into r1299; + and r1299 1u128 into r1300; + add r1298 r1300 into r1301; + gte r1301 r393 into r1302; + or r1297 r1302 into r1303; + sub.w r1301 r393 into r1304; + ternary r1303 r1304 r1301 into r1305; + add r1296 35184372088832u128 into r1306; + ternary r1303 r1306 r1296 into r1307; + gte r1305 170141183460469231731687303715884105728u128 into r1308; + add.w r1305 r1305 into r1309; + shr r191 44u8 into r1310; + and r1310 1u128 into r1311; + add r1309 r1311 into r1312; + gte r1312 r393 into r1313; + or r1308 r1313 into r1314; + sub.w r1312 r393 into r1315; + ternary r1314 r1315 r1312 into r1316; + add r1307 17592186044416u128 into r1317; + ternary r1314 r1317 r1307 into r1318; + gte r1316 170141183460469231731687303715884105728u128 into r1319; + add.w r1316 r1316 into r1320; + shr r191 43u8 into r1321; + and r1321 1u128 into r1322; + add r1320 r1322 into r1323; + gte r1323 r393 into r1324; + or r1319 r1324 into r1325; + sub.w r1323 r393 into r1326; + ternary r1325 r1326 r1323 into r1327; + add r1318 8796093022208u128 into r1328; + ternary r1325 r1328 r1318 into r1329; + gte r1327 170141183460469231731687303715884105728u128 into r1330; + add.w r1327 r1327 into r1331; + shr r191 42u8 into r1332; + and r1332 1u128 into r1333; + add r1331 r1333 into r1334; + gte r1334 r393 into r1335; + or r1330 r1335 into r1336; + sub.w r1334 r393 into r1337; + ternary r1336 r1337 r1334 into r1338; + add r1329 4398046511104u128 into r1339; + ternary r1336 r1339 r1329 into r1340; + gte r1338 170141183460469231731687303715884105728u128 into r1341; + add.w r1338 r1338 into r1342; + shr r191 41u8 into r1343; + and r1343 1u128 into r1344; + add r1342 r1344 into r1345; + gte r1345 r393 into r1346; + or r1341 r1346 into r1347; + sub.w r1345 r393 into r1348; + ternary r1347 r1348 r1345 into r1349; + add r1340 2199023255552u128 into r1350; + ternary r1347 r1350 r1340 into r1351; + gte r1349 170141183460469231731687303715884105728u128 into r1352; + add.w r1349 r1349 into r1353; + shr r191 40u8 into r1354; + and r1354 1u128 into r1355; + add r1353 r1355 into r1356; + gte r1356 r393 into r1357; + or r1352 r1357 into r1358; + sub.w r1356 r393 into r1359; + ternary r1358 r1359 r1356 into r1360; + add r1351 1099511627776u128 into r1361; + ternary r1358 r1361 r1351 into r1362; + gte r1360 170141183460469231731687303715884105728u128 into r1363; + add.w r1360 r1360 into r1364; + shr r191 39u8 into r1365; + and r1365 1u128 into r1366; + add r1364 r1366 into r1367; + gte r1367 r393 into r1368; + or r1363 r1368 into r1369; + sub.w r1367 r393 into r1370; + ternary r1369 r1370 r1367 into r1371; + add r1362 549755813888u128 into r1372; + ternary r1369 r1372 r1362 into r1373; + gte r1371 170141183460469231731687303715884105728u128 into r1374; + add.w r1371 r1371 into r1375; + shr r191 38u8 into r1376; + and r1376 1u128 into r1377; + add r1375 r1377 into r1378; + gte r1378 r393 into r1379; + or r1374 r1379 into r1380; + sub.w r1378 r393 into r1381; + ternary r1380 r1381 r1378 into r1382; + add r1373 274877906944u128 into r1383; + ternary r1380 r1383 r1373 into r1384; + gte r1382 170141183460469231731687303715884105728u128 into r1385; + add.w r1382 r1382 into r1386; + shr r191 37u8 into r1387; + and r1387 1u128 into r1388; + add r1386 r1388 into r1389; + gte r1389 r393 into r1390; + or r1385 r1390 into r1391; + sub.w r1389 r393 into r1392; + ternary r1391 r1392 r1389 into r1393; + add r1384 137438953472u128 into r1394; + ternary r1391 r1394 r1384 into r1395; + gte r1393 170141183460469231731687303715884105728u128 into r1396; + add.w r1393 r1393 into r1397; + shr r191 36u8 into r1398; + and r1398 1u128 into r1399; + add r1397 r1399 into r1400; + gte r1400 r393 into r1401; + or r1396 r1401 into r1402; + sub.w r1400 r393 into r1403; + ternary r1402 r1403 r1400 into r1404; + add r1395 68719476736u128 into r1405; + ternary r1402 r1405 r1395 into r1406; + gte r1404 170141183460469231731687303715884105728u128 into r1407; + add.w r1404 r1404 into r1408; + shr r191 35u8 into r1409; + and r1409 1u128 into r1410; + add r1408 r1410 into r1411; + gte r1411 r393 into r1412; + or r1407 r1412 into r1413; + sub.w r1411 r393 into r1414; + ternary r1413 r1414 r1411 into r1415; + add r1406 34359738368u128 into r1416; + ternary r1413 r1416 r1406 into r1417; + gte r1415 170141183460469231731687303715884105728u128 into r1418; + add.w r1415 r1415 into r1419; + shr r191 34u8 into r1420; + and r1420 1u128 into r1421; + add r1419 r1421 into r1422; + gte r1422 r393 into r1423; + or r1418 r1423 into r1424; + sub.w r1422 r393 into r1425; + ternary r1424 r1425 r1422 into r1426; + add r1417 17179869184u128 into r1427; + ternary r1424 r1427 r1417 into r1428; + gte r1426 170141183460469231731687303715884105728u128 into r1429; + add.w r1426 r1426 into r1430; + shr r191 33u8 into r1431; + and r1431 1u128 into r1432; + add r1430 r1432 into r1433; + gte r1433 r393 into r1434; + or r1429 r1434 into r1435; + sub.w r1433 r393 into r1436; + ternary r1435 r1436 r1433 into r1437; + add r1428 8589934592u128 into r1438; + ternary r1435 r1438 r1428 into r1439; + gte r1437 170141183460469231731687303715884105728u128 into r1440; + add.w r1437 r1437 into r1441; + and r209 1u128 into r1442; + add r1441 r1442 into r1443; + gte r1443 r393 into r1444; + or r1440 r1444 into r1445; + sub.w r1443 r393 into r1446; + ternary r1445 r1446 r1443 into r1447; + add r1439 4294967296u128 into r1448; + ternary r1445 r1448 r1439 into r1449; + gte r1447 170141183460469231731687303715884105728u128 into r1450; + add.w r1447 r1447 into r1451; + shr r191 31u8 into r1452; + and r1452 1u128 into r1453; + add r1451 r1453 into r1454; + gte r1454 r393 into r1455; + or r1450 r1455 into r1456; + sub.w r1454 r393 into r1457; + ternary r1456 r1457 r1454 into r1458; + add r1449 2147483648u128 into r1459; + ternary r1456 r1459 r1449 into r1460; + gte r1458 170141183460469231731687303715884105728u128 into r1461; + add.w r1458 r1458 into r1462; + shr r191 30u8 into r1463; + and r1463 1u128 into r1464; + add r1462 r1464 into r1465; + gte r1465 r393 into r1466; + or r1461 r1466 into r1467; + sub.w r1465 r393 into r1468; + ternary r1467 r1468 r1465 into r1469; + add r1460 1073741824u128 into r1470; + ternary r1467 r1470 r1460 into r1471; + gte r1469 170141183460469231731687303715884105728u128 into r1472; + add.w r1469 r1469 into r1473; + shr r191 29u8 into r1474; + and r1474 1u128 into r1475; + add r1473 r1475 into r1476; + gte r1476 r393 into r1477; + or r1472 r1477 into r1478; + sub.w r1476 r393 into r1479; + ternary r1478 r1479 r1476 into r1480; + add r1471 536870912u128 into r1481; + ternary r1478 r1481 r1471 into r1482; + gte r1480 170141183460469231731687303715884105728u128 into r1483; + add.w r1480 r1480 into r1484; + shr r191 28u8 into r1485; + and r1485 1u128 into r1486; + add r1484 r1486 into r1487; + gte r1487 r393 into r1488; + or r1483 r1488 into r1489; + sub.w r1487 r393 into r1490; + ternary r1489 r1490 r1487 into r1491; + add r1482 268435456u128 into r1492; + ternary r1489 r1492 r1482 into r1493; + gte r1491 170141183460469231731687303715884105728u128 into r1494; + add.w r1491 r1491 into r1495; + shr r191 27u8 into r1496; + and r1496 1u128 into r1497; + add r1495 r1497 into r1498; + gte r1498 r393 into r1499; + or r1494 r1499 into r1500; + sub.w r1498 r393 into r1501; + ternary r1500 r1501 r1498 into r1502; + add r1493 134217728u128 into r1503; + ternary r1500 r1503 r1493 into r1504; + gte r1502 170141183460469231731687303715884105728u128 into r1505; + add.w r1502 r1502 into r1506; + shr r191 26u8 into r1507; + and r1507 1u128 into r1508; + add r1506 r1508 into r1509; + gte r1509 r393 into r1510; + or r1505 r1510 into r1511; + sub.w r1509 r393 into r1512; + ternary r1511 r1512 r1509 into r1513; + add r1504 67108864u128 into r1514; + ternary r1511 r1514 r1504 into r1515; + gte r1513 170141183460469231731687303715884105728u128 into r1516; + add.w r1513 r1513 into r1517; + shr r191 25u8 into r1518; + and r1518 1u128 into r1519; + add r1517 r1519 into r1520; + gte r1520 r393 into r1521; + or r1516 r1521 into r1522; + sub.w r1520 r393 into r1523; + ternary r1522 r1523 r1520 into r1524; + add r1515 33554432u128 into r1525; + ternary r1522 r1525 r1515 into r1526; + gte r1524 170141183460469231731687303715884105728u128 into r1527; + add.w r1524 r1524 into r1528; + shr r191 24u8 into r1529; + and r1529 1u128 into r1530; + add r1528 r1530 into r1531; + gte r1531 r393 into r1532; + or r1527 r1532 into r1533; + sub.w r1531 r393 into r1534; + ternary r1533 r1534 r1531 into r1535; + add r1526 16777216u128 into r1536; + ternary r1533 r1536 r1526 into r1537; + gte r1535 170141183460469231731687303715884105728u128 into r1538; + add.w r1535 r1535 into r1539; + shr r191 23u8 into r1540; + and r1540 1u128 into r1541; + add r1539 r1541 into r1542; + gte r1542 r393 into r1543; + or r1538 r1543 into r1544; + sub.w r1542 r393 into r1545; + ternary r1544 r1545 r1542 into r1546; + add r1537 8388608u128 into r1547; + ternary r1544 r1547 r1537 into r1548; + gte r1546 170141183460469231731687303715884105728u128 into r1549; + add.w r1546 r1546 into r1550; + shr r191 22u8 into r1551; + and r1551 1u128 into r1552; + add r1550 r1552 into r1553; + gte r1553 r393 into r1554; + or r1549 r1554 into r1555; + sub.w r1553 r393 into r1556; + ternary r1555 r1556 r1553 into r1557; + add r1548 4194304u128 into r1558; + ternary r1555 r1558 r1548 into r1559; + gte r1557 170141183460469231731687303715884105728u128 into r1560; + add.w r1557 r1557 into r1561; + shr r191 21u8 into r1562; + and r1562 1u128 into r1563; + add r1561 r1563 into r1564; + gte r1564 r393 into r1565; + or r1560 r1565 into r1566; + sub.w r1564 r393 into r1567; + ternary r1566 r1567 r1564 into r1568; + add r1559 2097152u128 into r1569; + ternary r1566 r1569 r1559 into r1570; + gte r1568 170141183460469231731687303715884105728u128 into r1571; + add.w r1568 r1568 into r1572; + shr r191 20u8 into r1573; + and r1573 1u128 into r1574; + add r1572 r1574 into r1575; + gte r1575 r393 into r1576; + or r1571 r1576 into r1577; + sub.w r1575 r393 into r1578; + ternary r1577 r1578 r1575 into r1579; + add r1570 1048576u128 into r1580; + ternary r1577 r1580 r1570 into r1581; + gte r1579 170141183460469231731687303715884105728u128 into r1582; + add.w r1579 r1579 into r1583; + shr r191 19u8 into r1584; + and r1584 1u128 into r1585; + add r1583 r1585 into r1586; + gte r1586 r393 into r1587; + or r1582 r1587 into r1588; + sub.w r1586 r393 into r1589; + ternary r1588 r1589 r1586 into r1590; + add r1581 524288u128 into r1591; + ternary r1588 r1591 r1581 into r1592; + gte r1590 170141183460469231731687303715884105728u128 into r1593; + add.w r1590 r1590 into r1594; + shr r191 18u8 into r1595; + and r1595 1u128 into r1596; + add r1594 r1596 into r1597; + gte r1597 r393 into r1598; + or r1593 r1598 into r1599; + sub.w r1597 r393 into r1600; + ternary r1599 r1600 r1597 into r1601; + add r1592 262144u128 into r1602; + ternary r1599 r1602 r1592 into r1603; + gte r1601 170141183460469231731687303715884105728u128 into r1604; + add.w r1601 r1601 into r1605; + shr r191 17u8 into r1606; + and r1606 1u128 into r1607; + add r1605 r1607 into r1608; + gte r1608 r393 into r1609; + or r1604 r1609 into r1610; + sub.w r1608 r393 into r1611; + ternary r1610 r1611 r1608 into r1612; + add r1603 131072u128 into r1613; + ternary r1610 r1613 r1603 into r1614; + gte r1612 170141183460469231731687303715884105728u128 into r1615; + add.w r1612 r1612 into r1616; + shr r191 16u8 into r1617; + and r1617 1u128 into r1618; + add r1616 r1618 into r1619; + gte r1619 r393 into r1620; + or r1615 r1620 into r1621; + sub.w r1619 r393 into r1622; + ternary r1621 r1622 r1619 into r1623; + add r1614 65536u128 into r1624; + ternary r1621 r1624 r1614 into r1625; + gte r1623 170141183460469231731687303715884105728u128 into r1626; + add.w r1623 r1623 into r1627; + shr r191 15u8 into r1628; + and r1628 1u128 into r1629; + add r1627 r1629 into r1630; + gte r1630 r393 into r1631; + or r1626 r1631 into r1632; + sub.w r1630 r393 into r1633; + ternary r1632 r1633 r1630 into r1634; + add r1625 32768u128 into r1635; + ternary r1632 r1635 r1625 into r1636; + gte r1634 170141183460469231731687303715884105728u128 into r1637; + add.w r1634 r1634 into r1638; + shr r191 14u8 into r1639; + and r1639 1u128 into r1640; + add r1638 r1640 into r1641; + gte r1641 r393 into r1642; + or r1637 r1642 into r1643; + sub.w r1641 r393 into r1644; + ternary r1643 r1644 r1641 into r1645; + add r1636 16384u128 into r1646; + ternary r1643 r1646 r1636 into r1647; + gte r1645 170141183460469231731687303715884105728u128 into r1648; + add.w r1645 r1645 into r1649; + shr r191 13u8 into r1650; + and r1650 1u128 into r1651; + add r1649 r1651 into r1652; + gte r1652 r393 into r1653; + or r1648 r1653 into r1654; + sub.w r1652 r393 into r1655; + ternary r1654 r1655 r1652 into r1656; + add r1647 8192u128 into r1657; + ternary r1654 r1657 r1647 into r1658; + gte r1656 170141183460469231731687303715884105728u128 into r1659; + add.w r1656 r1656 into r1660; + shr r191 12u8 into r1661; + and r1661 1u128 into r1662; + add r1660 r1662 into r1663; + gte r1663 r393 into r1664; + or r1659 r1664 into r1665; + sub.w r1663 r393 into r1666; + ternary r1665 r1666 r1663 into r1667; + add r1658 4096u128 into r1668; + ternary r1665 r1668 r1658 into r1669; + gte r1667 170141183460469231731687303715884105728u128 into r1670; + add.w r1667 r1667 into r1671; + shr r191 11u8 into r1672; + and r1672 1u128 into r1673; + add r1671 r1673 into r1674; + gte r1674 r393 into r1675; + or r1670 r1675 into r1676; + sub.w r1674 r393 into r1677; + ternary r1676 r1677 r1674 into r1678; + add r1669 2048u128 into r1679; + ternary r1676 r1679 r1669 into r1680; + gte r1678 170141183460469231731687303715884105728u128 into r1681; + add.w r1678 r1678 into r1682; + shr r191 10u8 into r1683; + and r1683 1u128 into r1684; + add r1682 r1684 into r1685; + gte r1685 r393 into r1686; + or r1681 r1686 into r1687; + sub.w r1685 r393 into r1688; + ternary r1687 r1688 r1685 into r1689; + add r1680 1024u128 into r1690; + ternary r1687 r1690 r1680 into r1691; + gte r1689 170141183460469231731687303715884105728u128 into r1692; + add.w r1689 r1689 into r1693; + shr r191 9u8 into r1694; + and r1694 1u128 into r1695; + add r1693 r1695 into r1696; + gte r1696 r393 into r1697; + or r1692 r1697 into r1698; + sub.w r1696 r393 into r1699; + ternary r1698 r1699 r1696 into r1700; + add r1691 512u128 into r1701; + ternary r1698 r1701 r1691 into r1702; + gte r1700 170141183460469231731687303715884105728u128 into r1703; + add.w r1700 r1700 into r1704; + shr r191 8u8 into r1705; + and r1705 1u128 into r1706; + add r1704 r1706 into r1707; + gte r1707 r393 into r1708; + or r1703 r1708 into r1709; + sub.w r1707 r393 into r1710; + ternary r1709 r1710 r1707 into r1711; + add r1702 256u128 into r1712; + ternary r1709 r1712 r1702 into r1713; + gte r1711 170141183460469231731687303715884105728u128 into r1714; + add.w r1711 r1711 into r1715; + shr r191 7u8 into r1716; + and r1716 1u128 into r1717; + add r1715 r1717 into r1718; + gte r1718 r393 into r1719; + or r1714 r1719 into r1720; + sub.w r1718 r393 into r1721; + ternary r1720 r1721 r1718 into r1722; + add r1713 128u128 into r1723; + ternary r1720 r1723 r1713 into r1724; + gte r1722 170141183460469231731687303715884105728u128 into r1725; + add.w r1722 r1722 into r1726; + shr r191 6u8 into r1727; + and r1727 1u128 into r1728; + add r1726 r1728 into r1729; + gte r1729 r393 into r1730; + or r1725 r1730 into r1731; + sub.w r1729 r393 into r1732; + ternary r1731 r1732 r1729 into r1733; + add r1724 64u128 into r1734; + ternary r1731 r1734 r1724 into r1735; + gte r1733 170141183460469231731687303715884105728u128 into r1736; + add.w r1733 r1733 into r1737; + shr r191 5u8 into r1738; + and r1738 1u128 into r1739; + add r1737 r1739 into r1740; + gte r1740 r393 into r1741; + or r1736 r1741 into r1742; + sub.w r1740 r393 into r1743; + ternary r1742 r1743 r1740 into r1744; + add r1735 32u128 into r1745; + ternary r1742 r1745 r1735 into r1746; + gte r1744 170141183460469231731687303715884105728u128 into r1747; + add.w r1744 r1744 into r1748; + shr r191 4u8 into r1749; + and r1749 1u128 into r1750; + add r1748 r1750 into r1751; + gte r1751 r393 into r1752; + or r1747 r1752 into r1753; + sub.w r1751 r393 into r1754; + ternary r1753 r1754 r1751 into r1755; + add r1746 16u128 into r1756; + ternary r1753 r1756 r1746 into r1757; + gte r1755 170141183460469231731687303715884105728u128 into r1758; + add.w r1755 r1755 into r1759; + shr r191 3u8 into r1760; + and r1760 1u128 into r1761; + add r1759 r1761 into r1762; + gte r1762 r393 into r1763; + or r1758 r1763 into r1764; + sub.w r1762 r393 into r1765; + ternary r1764 r1765 r1762 into r1766; + add r1757 8u128 into r1767; + ternary r1764 r1767 r1757 into r1768; + gte r1766 170141183460469231731687303715884105728u128 into r1769; + add.w r1766 r1766 into r1770; + shr r191 2u8 into r1771; + and r1771 1u128 into r1772; + add r1770 r1772 into r1773; + gte r1773 r393 into r1774; + or r1769 r1774 into r1775; + sub.w r1773 r393 into r1776; + ternary r1775 r1776 r1773 into r1777; + add r1768 4u128 into r1778; + ternary r1775 r1778 r1768 into r1779; + gte r1777 170141183460469231731687303715884105728u128 into r1780; + add.w r1777 r1777 into r1781; + shr r191 1u8 into r1782; + and r1782 1u128 into r1783; + add r1781 r1783 into r1784; + gte r1784 r393 into r1785; + or r1780 r1785 into r1786; + sub.w r1784 r393 into r1787; + ternary r1786 r1787 r1784 into r1788; + add r1779 2u128 into r1789; + ternary r1786 r1789 r1779 into r1790; + gte r1788 170141183460469231731687303715884105728u128 into r1791; + add.w r1788 r1788 into r1792; + and r217 1u128 into r1793; + add r1792 r1793 into r1794; + gte r1794 r393 into r1795; + or r1791 r1795 into r1796; + sub.w r1794 r393 into r1797; + ternary r1796 r1797 r1794 into r1798; + add r1790 1u128 into r1799; + ternary r1796 r1799 r1790 into r1800; + gt r1798 0u128 into r1801; + add r1800 1u128 into r1802; + ternary r1801 r1802 r1800 into r1803; + ternary r366 r3.sp r1803 into r1804; + ternary r121 r3.liq 1u128 into r1805; + and r362 18446744073709551615u128 into r1806; + shr r362 64u8 into r1807; + mul r1806 9223372036854775808u128 into r1808; + mul r1807 9223372036854775808u128 into r1809; + and r1808 18446744073709551615u128 into r1810; + shr r1808 64u8 into r1811; + and r1809 18446744073709551615u128 into r1812; + add r1811 r1812 into r1813; + and r1813 18446744073709551615u128 into r1814; + shr r1813 64u8 into r1815; + shr r1809 64u8 into r1816; + add r1816 r1815 into r1817; + and r1817 18446744073709551615u128 into r1818; + shr r1817 64u8 into r1819; + shl r1814 64u8 into r1820; + add r1820 r1810 into r1821; + shl r1819 64u8 into r1822; + add r1822 r1818 into r1823; + lt r1823 r1805 into r1824; + assert.eq r1824 true; + shr r1821 96u8 into r1825; + and r1825 4294967295u128 into r1826; + shl r1823 32u8 into r1827; + add r1827 r1826 into r1828; + div r1828 r1805 into r1829; + rem r1828 r1805 into r1830; + shr r1821 64u8 into r1831; + and r1831 4294967295u128 into r1832; + shl r1830 32u8 into r1833; + add r1833 r1832 into r1834; + shl r1829 32u8 into r1835; + div r1834 r1805 into r1836; + add r1835 r1836 into r1837; + rem r1834 r1805 into r1838; + shr r1821 32u8 into r1839; + and r1839 4294967295u128 into r1840; + shl r1838 32u8 into r1841; + add r1841 r1840 into r1842; + shl r1837 32u8 into r1843; + div r1842 r1805 into r1844; + add r1843 r1844 into r1845; + rem r1842 r1805 into r1846; + shr r1821 0u8 into r1847; + and r1847 4294967295u128 into r1848; + shl r1846 32u8 into r1849; + add r1849 r1848 into r1850; + shl r1845 32u8 into r1851; + div r1850 r1805 into r1852; + add r1851 r1852 into r1853; + rem r1850 r1805 into r1854; + add r1853 1u128 into r1855; + ternary r121 r1853 0u128 into r1856; + add r3.sp r1856 into r1857; + gt r1856 r3.sp into r1858; + ternary r1858 r3.sp r1856 into r1859; + sub r3.sp r1859 into r1860; + ternary r0.z r1804 r1857 into r1861; + ternary r365 r116 r1861 into r1862; + gt r1862 r3.sp into r1863; + ternary r1863 r3.sp r1862 into r1864; + ternary r1863 r1862 r3.sp into r1865; + gt r1864 0u128 into r1866; + gt r1865 0u128 into r1867; + and r1866 r1867 into r1868; + ternary r1867 r1865 1u128 into r1869; + ternary r1866 r1864 1u128 into r1870; + lt r368 r1870 into r1871; + assert.eq r1871 true; + shl r368 32u8 into r1872; + add r1872 r196 into r1873; + div r1873 r1870 into r1874; + rem r1873 r1870 into r1875; + shl r1875 32u8 into r1876; + add r1876 r202 into r1877; + shl r1874 32u8 into r1878; + div r1877 r1870 into r1879; + add r1878 r1879 into r1880; + rem r1877 r1870 into r1881; + shl r1881 32u8 into r1882; + add r1882 r210 into r1883; + shl r1880 32u8 into r1884; + div r1883 r1870 into r1885; + add r1884 r1885 into r1886; + rem r1883 r1870 into r1887; + shl r1887 32u8 into r1888; + add r1888 r218 into r1889; + shl r1886 32u8 into r1890; + div r1889 r1870 into r1891; + add r1890 r1891 into r1892; + rem r1889 r1870 into r1893; + gt r1893 0u128 into r1894; + add r1892 1u128 into r1895; + ternary r1894 r1895 r1892 into r1896; + lt r368 r1869 into r1897; + assert.eq r1897 true; + div r1873 r1869 into r1898; + rem r1873 r1869 into r1899; + shl r1899 32u8 into r1900; + add r1900 r202 into r1901; + shl r1898 32u8 into r1902; + div r1901 r1869 into r1903; + add r1902 r1903 into r1904; + rem r1901 r1869 into r1905; + shl r1905 32u8 into r1906; + add r1906 r210 into r1907; + shl r1904 32u8 into r1908; + div r1907 r1869 into r1909; + add r1908 r1909 into r1910; + rem r1907 r1869 into r1911; + shl r1911 32u8 into r1912; + add r1912 r218 into r1913; + shl r1910 32u8 into r1914; + div r1913 r1869 into r1915; + add r1914 r1915 into r1916; + rem r1913 r1869 into r1917; + add r1916 1u128 into r1918; + gte r1896 r1916 into r1919; + ternary r1919 r1896 r1916 into r1920; + ternary r1919 r1916 r1896 into r1921; + sub r1920 r1921 into r1922; + ternary r1919 r1922 0u128 into r1923; + lt r1864 r1865 into r1924; + and r1868 r1924 into r1925; + ternary r1925 r1923 0u128 into r1926; + gt r3.sp r1862 into r1927; + ternary r1927 r1862 r3.sp into r1928; + ternary r1927 r3.sp r1862 into r1929; + sub r1929 r1928 into r1930; + and r1930 18446744073709551615u128 into r1931; + shr r1930 64u8 into r1932; + mul r132 r1931 into r1933; + mul r132 r1932 into r1934; + mul r133 r1931 into r1935; + mul r133 r1932 into r1936; + and r1933 18446744073709551615u128 into r1937; + shr r1933 64u8 into r1938; + and r1934 18446744073709551615u128 into r1939; + add r1938 r1939 into r1940; + and r1935 18446744073709551615u128 into r1941; + add r1940 r1941 into r1942; + and r1942 18446744073709551615u128 into r1943; + shr r1942 64u8 into r1944; + shr r1934 64u8 into r1945; + shr r1935 64u8 into r1946; + add r1945 r1946 into r1947; + and r1936 18446744073709551615u128 into r1948; + add r1947 r1948 into r1949; + add r1949 r1944 into r1950; + and r1950 18446744073709551615u128 into r1951; + shr r1950 64u8 into r1952; + shr r1936 64u8 into r1953; + add r1953 r1952 into r1954; + shl r1943 64u8 into r1955; + add r1955 r1937 into r1956; + shl r1954 64u8 into r1957; + add r1957 r1951 into r1958; + lt r1958 9223372036854775808u128 into r1959; + assert.eq r1959 true; + shr r1956 96u8 into r1960; + and r1960 4294967295u128 into r1961; + shl r1958 32u8 into r1962; + add r1962 r1961 into r1963; + div r1963 9223372036854775808u128 into r1964; + rem r1963 9223372036854775808u128 into r1965; + shr r1956 64u8 into r1966; + and r1966 4294967295u128 into r1967; + shl r1965 32u8 into r1968; + add r1968 r1967 into r1969; + shl r1964 32u8 into r1970; + div r1969 9223372036854775808u128 into r1971; + add r1970 r1971 into r1972; + rem r1969 9223372036854775808u128 into r1973; + shr r1956 32u8 into r1974; + and r1974 4294967295u128 into r1975; + shl r1973 32u8 into r1976; + add r1976 r1975 into r1977; + shl r1972 32u8 into r1978; + div r1977 9223372036854775808u128 into r1979; + add r1978 r1979 into r1980; + rem r1977 9223372036854775808u128 into r1981; + shr r1956 0u8 into r1982; + and r1982 4294967295u128 into r1983; + shl r1981 32u8 into r1984; + add r1984 r1983 into r1985; + shl r1980 32u8 into r1986; + div r1985 9223372036854775808u128 into r1987; + add r1986 r1987 into r1988; + rem r1985 9223372036854775808u128 into r1989; + gt r1989 0u128 into r1990; + add r1988 1u128 into r1991; + ternary r1990 r1991 r1988 into r1992; + ternary r0.z r1926 r1992 into r1993; + ternary r365 r300 r1993 into r1994; + gt r1862 r3.sp into r1995; + ternary r1995 r3.sp r1862 into r1996; + ternary r1995 r1862 r3.sp into r1997; + sub r1997 r1996 into r1998; + and r1998 18446744073709551615u128 into r1999; + shr r1998 64u8 into r2000; + mul r132 r1999 into r2001; + mul r132 r2000 into r2002; + mul r133 r1999 into r2003; + mul r133 r2000 into r2004; + and r2001 18446744073709551615u128 into r2005; + shr r2001 64u8 into r2006; + and r2002 18446744073709551615u128 into r2007; + add r2006 r2007 into r2008; + and r2003 18446744073709551615u128 into r2009; + add r2008 r2009 into r2010; + and r2010 18446744073709551615u128 into r2011; + shr r2010 64u8 into r2012; + shr r2002 64u8 into r2013; + shr r2003 64u8 into r2014; + add r2013 r2014 into r2015; + and r2004 18446744073709551615u128 into r2016; + add r2015 r2016 into r2017; + add r2017 r2012 into r2018; + and r2018 18446744073709551615u128 into r2019; + shr r2018 64u8 into r2020; + shr r2004 64u8 into r2021; + add r2021 r2020 into r2022; + shl r2011 64u8 into r2023; + add r2023 r2005 into r2024; + shl r2022 64u8 into r2025; + add r2025 r2019 into r2026; + lt r2026 9223372036854775808u128 into r2027; + assert.eq r2027 true; + shr r2024 96u8 into r2028; + and r2028 4294967295u128 into r2029; + shl r2026 32u8 into r2030; + add r2030 r2029 into r2031; + div r2031 9223372036854775808u128 into r2032; + rem r2031 9223372036854775808u128 into r2033; + shr r2024 64u8 into r2034; + and r2034 4294967295u128 into r2035; + shl r2033 32u8 into r2036; + add r2036 r2035 into r2037; + shl r2032 32u8 into r2038; + div r2037 9223372036854775808u128 into r2039; + add r2038 r2039 into r2040; + rem r2037 9223372036854775808u128 into r2041; + shr r2024 32u8 into r2042; + and r2042 4294967295u128 into r2043; + shl r2041 32u8 into r2044; + add r2044 r2043 into r2045; + shl r2040 32u8 into r2046; + div r2045 9223372036854775808u128 into r2047; + add r2046 r2047 into r2048; + rem r2045 9223372036854775808u128 into r2049; + shr r2024 0u8 into r2050; + and r2050 4294967295u128 into r2051; + shl r2049 32u8 into r2052; + add r2052 r2051 into r2053; + shl r2048 32u8 into r2054; + div r2053 9223372036854775808u128 into r2055; + add r2054 r2055 into r2056; + rem r2053 9223372036854775808u128 into r2057; + add r2056 1u128 into r2058; + gt r1928 0u128 into r2059; + gt r1929 0u128 into r2060; + and r2059 r2060 into r2061; + ternary r2060 r1929 1u128 into r2062; + ternary r2059 r1928 1u128 into r2063; + lt r368 r2063 into r2064; + assert.eq r2064 true; + div r1873 r2063 into r2065; + rem r1873 r2063 into r2066; + shl r2066 32u8 into r2067; + add r2067 r202 into r2068; + shl r2065 32u8 into r2069; + div r2068 r2063 into r2070; + add r2069 r2070 into r2071; + rem r2068 r2063 into r2072; + shl r2072 32u8 into r2073; + add r2073 r210 into r2074; + shl r2071 32u8 into r2075; + div r2074 r2063 into r2076; + add r2075 r2076 into r2077; + rem r2074 r2063 into r2078; + shl r2078 32u8 into r2079; + add r2079 r218 into r2080; + shl r2077 32u8 into r2081; + div r2080 r2063 into r2082; + add r2081 r2082 into r2083; + rem r2080 r2063 into r2084; + add r2083 1u128 into r2085; + lt r368 r2062 into r2086; + assert.eq r2086 true; + div r1873 r2062 into r2087; + rem r1873 r2062 into r2088; + shl r2088 32u8 into r2089; + add r2089 r202 into r2090; + shl r2087 32u8 into r2091; + div r2090 r2062 into r2092; + add r2091 r2092 into r2093; + rem r2090 r2062 into r2094; + shl r2094 32u8 into r2095; + add r2095 r210 into r2096; + shl r2093 32u8 into r2097; + div r2096 r2062 into r2098; + add r2097 r2098 into r2099; + rem r2096 r2062 into r2100; + shl r2100 32u8 into r2101; + add r2101 r218 into r2102; + shl r2099 32u8 into r2103; + div r2102 r2062 into r2104; + add r2103 r2104 into r2105; + rem r2102 r2062 into r2106; + gt r2106 0u128 into r2107; + add r2105 1u128 into r2108; + ternary r2107 r2108 r2105 into r2109; + gte r2083 r2109 into r2110; + ternary r2110 r2083 r2109 into r2111; + ternary r2110 r2109 r2083 into r2112; + sub r2111 r2112 into r2113; + ternary r2110 r2113 0u128 into r2114; + lt r1928 r1929 into r2115; + and r2061 r2115 into r2116; + ternary r2116 r2114 0u128 into r2117; + ternary r0.z r2056 r2117 into r2118; + cast r0.fee_pips into r2119 as u128; + cast r0.fee_pips into r2120 as u128; + sub 1000000u128 r2120 into r2121; + and r1994 18446744073709551615u128 into r2122; + shr r1994 64u8 into r2123; + and r2119 18446744073709551615u128 into r2124; + shr r2119 64u8 into r2125; + mul r2122 r2124 into r2126; + mul r2122 r2125 into r2127; + mul r2123 r2124 into r2128; + mul r2123 r2125 into r2129; + and r2126 18446744073709551615u128 into r2130; + shr r2126 64u8 into r2131; + and r2127 18446744073709551615u128 into r2132; + add r2131 r2132 into r2133; + and r2128 18446744073709551615u128 into r2134; + add r2133 r2134 into r2135; + and r2135 18446744073709551615u128 into r2136; + shr r2135 64u8 into r2137; + shr r2127 64u8 into r2138; + shr r2128 64u8 into r2139; + add r2138 r2139 into r2140; + and r2129 18446744073709551615u128 into r2141; + add r2140 r2141 into r2142; + add r2142 r2137 into r2143; + and r2143 18446744073709551615u128 into r2144; + shr r2143 64u8 into r2145; + shr r2129 64u8 into r2146; + add r2146 r2145 into r2147; + shl r2136 64u8 into r2148; + add r2148 r2130 into r2149; + shl r2147 64u8 into r2150; + add r2150 r2144 into r2151; + lt r2151 r2121 into r2152; + assert.eq r2152 true; + shr r2149 96u8 into r2153; + and r2153 4294967295u128 into r2154; + shl r2151 32u8 into r2155; + add r2155 r2154 into r2156; + div r2156 r2121 into r2157; + rem r2156 r2121 into r2158; + shr r2149 64u8 into r2159; + and r2159 4294967295u128 into r2160; + shl r2158 32u8 into r2161; + add r2161 r2160 into r2162; + shl r2157 32u8 into r2163; + div r2162 r2121 into r2164; + add r2163 r2164 into r2165; + rem r2162 r2121 into r2166; + shr r2149 32u8 into r2167; + and r2167 4294967295u128 into r2168; + shl r2166 32u8 into r2169; + add r2169 r2168 into r2170; + shl r2165 32u8 into r2171; + div r2170 r2121 into r2172; + add r2171 r2172 into r2173; + rem r2170 r2121 into r2174; + shr r2149 0u8 into r2175; + and r2175 4294967295u128 into r2176; + shl r2174 32u8 into r2177; + add r2177 r2176 into r2178; + shl r2173 32u8 into r2179; + div r2178 r2121 into r2180; + add r2179 r2180 into r2181; + rem r2178 r2121 into r2182; + gt r2182 0u128 into r2183; + add r2181 1u128 into r2184; + ternary r2183 r2184 r2181 into r2185; + gt r1994 r3.rem into r2186; + ternary r2186 r3.rem r1994 into r2187; + sub r3.rem r2187 into r2188; + ternary r365 r2185 r2188 into r2189; + ternary r120 r116 r3.sp into r2190; + ternary r123 r1862 r2190 into r2191; + ternary r123 r1994 0u128 into r2192; + ternary r123 r2118 0u128 into r2193; + ternary r123 r2189 0u128 into r2194; + cast r0.fee_protocol into r2195 as u128; + mul r2194 r2195 into r2196; + div r2196 16u128 into r2197; + sub r2194 r2197 into r2198; + add r3.pf r2197 into r2199; + add r2192 r2194 into r2200; + gt r2200 r3.rem into r2201; + ternary r2201 r3.rem r2200 into r2202; + sub r3.rem r2202 into r2203; + add r3.out r2193 into r2204; + and r2198 18446744073709551615u128 into r2205; + shr r2198 64u8 into r2206; + mul r2205 9223372036854775808u128 into r2207; + mul r2206 9223372036854775808u128 into r2208; + and r2207 18446744073709551615u128 into r2209; + shr r2207 64u8 into r2210; + and r2208 18446744073709551615u128 into r2211; + add r2210 r2211 into r2212; + and r2212 18446744073709551615u128 into r2213; + shr r2212 64u8 into r2214; + shr r2208 64u8 into r2215; + add r2215 r2214 into r2216; + and r2216 18446744073709551615u128 into r2217; + shr r2216 64u8 into r2218; + shl r2213 64u8 into r2219; + add r2219 r2209 into r2220; + shl r2218 64u8 into r2221; + add r2221 r2217 into r2222; + lt r2222 r1805 into r2223; + assert.eq r2223 true; + shr r2220 96u8 into r2224; + and r2224 4294967295u128 into r2225; + shl r2222 32u8 into r2226; + add r2226 r2225 into r2227; + div r2227 r1805 into r2228; + rem r2227 r1805 into r2229; + shr r2220 64u8 into r2230; + and r2230 4294967295u128 into r2231; + shl r2229 32u8 into r2232; + add r2232 r2231 into r2233; + shl r2228 32u8 into r2234; + div r2233 r1805 into r2235; + add r2234 r2235 into r2236; + rem r2233 r1805 into r2237; + shr r2220 32u8 into r2238; + and r2238 4294967295u128 into r2239; + shl r2237 32u8 into r2240; + add r2240 r2239 into r2241; + shl r2236 32u8 into r2242; + div r2241 r1805 into r2243; + add r2242 r2243 into r2244; + rem r2241 r1805 into r2245; + shr r2220 0u8 into r2246; + and r2246 4294967295u128 into r2247; + shl r2245 32u8 into r2248; + add r2248 r2247 into r2249; + shl r2244 32u8 into r2250; + div r2249 r1805 into r2251; + add r2250 r2251 into r2252; + rem r2249 r1805 into r2253; + add r2252 1u128 into r2254; + mul.w r2198 9223372036854775808u128 into r2255; + mul.w r2252 r1805 into r2256; + sub.w r2255 r2256 into r2257; + sub r1805 r2257 into r2258; + gte r3.resid r2258 into r2259; + and r121 r2259 into r2260; + sub.w r3.resid r2258 into r2261; + add.w r2257 r3.resid into r2262; + ternary r2260 r2261 r2262 into r2263; + ternary r2260 1u128 0u128 into r2264; + add r2252 r2264 into r2265; + sub 340282366920938463463374607431768211455u128 r3.fg into r2266; + gt r2265 r2266 into r2267; + ternary r2267 0u128 r2265 into r2268; + add r3.fg r2268 into r2269; + gte r2265 r2266 into r2270; + ternary r2270 r2265 r2266 into r2271; + sub r2271 r2266 into r2272; + gte r2272 1u128 into r2273; + ternary r2273 r2272 1u128 into r2274; + sub r2274 1u128 into r2275; + ternary r2267 r2275 r2269 into r2276; + is.eq r2191 r111 into r2277; + and r3.crossed r2277 into r2278; + is.neq r111 r0.lim into r2279; + and r2278 r2279 into r2280; + ternary r0.z r2276 r0.slot_fg0 into r2281; + ternary r0.z r0.slot_fg1 r2276 into r2282; + gte r2281 r2.fee_growth_outside0_64 into r2283; + ternary r2283 r2281 r2.fee_growth_outside0_64 into r2284; + ternary r2283 r2.fee_growth_outside0_64 r2281 into r2285; + sub r2284 r2285 into r2286; + gt r2286 0u128 into r2287; + ternary r2287 r2286 1u128 into r2288; + sub 340282366920938463463374607431768211455u128 r2288 into r2289; + add r2289 1u128 into r2290; + ternary r2283 r2286 r2290 into r2291; + gte r2282 r2.fee_growth_outside1_64 into r2292; + ternary r2292 r2282 r2.fee_growth_outside1_64 into r2293; + ternary r2292 r2.fee_growth_outside1_64 r2282 into r2294; + sub r2293 r2294 into r2295; + gt r2295 0u128 into r2296; + ternary r2296 r2295 1u128 into r2297; + sub 340282366920938463463374607431768211455u128 r2297 into r2298; + add r2298 1u128 into r2299; + ternary r2292 r2295 r2299 into r2300; + ternary r2280 r2.pool r2.pool into r2301; + ternary r2280 r2.liquidity_net r2.liquidity_net into r2302; + ternary r2280 r2.liquidity_gross r2.liquidity_gross into r2303; + ternary r2280 r2.tick r2.tick into r2304; + ternary r2280 r2291 r2.fee_growth_outside0_64 into r2305; + ternary r2280 r2300 r2.fee_growth_outside1_64 into r2306; + ternary r2280 r2.prev r2.prev into r2307; + ternary r2280 r2.next r2.next into r2308; + cast r2301 r2302 r2303 r2304 r2305 r2306 r2307 r2308 into r2309 as Tick; + sub 0i128 r2.liquidity_net into r2310; + ternary r0.z r2310 r2.liquidity_net into r2311; + ternary r2280 r2311 0i128 into r2312; + sub 0i128 r2312 into r2313; + gt r2312 0i128 into r2314; + ternary r2314 r2312 0i128 into r2315; + gt r2313 0i128 into r2316; + ternary r2316 r2313 0i128 into r2317; + cast r2315 into r2318 as u128; + cast r2317 into r2319 as u128; + gte r3.liq r2319 into r2320; + assert.eq r2320 true; + sub r3.liq r2319 into r2321; + add r3.liq r2318 into r2322; + lt r2312 0i128 into r2323; + ternary r2323 r2321 r2322 into r2324; + ternary r2280 r2324 r3.liq into r2325; + sub r1 1i32 into r2326; + ternary r0.z r2326 r1 into r2327; + is.eq r2191 r3.sp into r2328; + gte r2191 18446744073709551616u128 into r2329; + shr r2191 64u8 into r2330; + ternary r2329 r2330 r2191 into r2331; + ternary r2329 64u32 0u32 into r2332; + gte r2331 4294967296u128 into r2333; + shr r2331 32u8 into r2334; + add r2332 32u32 into r2335; + ternary r2333 r2334 r2331 into r2336; + ternary r2333 r2335 r2332 into r2337; + gte r2336 65536u128 into r2338; + shr r2336 16u8 into r2339; + add r2337 16u32 into r2340; + ternary r2338 r2339 r2336 into r2341; + ternary r2338 r2340 r2337 into r2342; + gte r2341 256u128 into r2343; + shr r2341 8u8 into r2344; + add r2342 8u32 into r2345; + ternary r2343 r2344 r2341 into r2346; + ternary r2343 r2345 r2342 into r2347; + gte r2346 16u128 into r2348; + shr r2346 4u8 into r2349; + add r2347 4u32 into r2350; + ternary r2348 r2349 r2346 into r2351; + ternary r2348 r2350 r2347 into r2352; + gte r2351 4u128 into r2353; + shr r2351 2u8 into r2354; + add r2352 2u32 into r2355; + ternary r2353 r2354 r2351 into r2356; + ternary r2353 r2355 r2352 into r2357; + gte r2356 2u128 into r2358; + add r2357 1u32 into r2359; + ternary r2358 r2359 r2357 into r2360; + gte r2360 63u32 into r2361; + ternary r2361 r2360 63u32 into r2362; + ternary r2361 63u32 r2360 into r2363; + sub r2362 r2363 into r2364; + cast r2364 into r2365 as u8; + shr r2191 r2365 into r2366; + shl r2191 r2365 into r2367; + ternary r2361 r2366 r2367 into r2368; + mul r2368 r2368 into r2369; + shr r2369 63u8 into r2370; + shr r2370 64u8 into r2371; + shl r2371 63u8 into r2372; + cast r2371 into r2373 as u8; + shr r2370 r2373 into r2374; + mul r2374 r2374 into r2375; + shr r2375 63u8 into r2376; + shr r2376 64u8 into r2377; + shl r2377 62u8 into r2378; + or r2372 r2378 into r2379; + cast r2377 into r2380 as u8; + shr r2376 r2380 into r2381; + mul r2381 r2381 into r2382; + shr r2382 63u8 into r2383; + shr r2383 64u8 into r2384; + shl r2384 61u8 into r2385; + or r2379 r2385 into r2386; + cast r2384 into r2387 as u8; + shr r2383 r2387 into r2388; + mul r2388 r2388 into r2389; + shr r2389 63u8 into r2390; + shr r2390 64u8 into r2391; + shl r2391 60u8 into r2392; + or r2386 r2392 into r2393; + cast r2391 into r2394 as u8; + shr r2390 r2394 into r2395; + mul r2395 r2395 into r2396; + shr r2396 63u8 into r2397; + shr r2397 64u8 into r2398; + shl r2398 59u8 into r2399; + or r2393 r2399 into r2400; + cast r2398 into r2401 as u8; + shr r2397 r2401 into r2402; + mul r2402 r2402 into r2403; + shr r2403 63u8 into r2404; + shr r2404 64u8 into r2405; + shl r2405 58u8 into r2406; + or r2400 r2406 into r2407; + cast r2405 into r2408 as u8; + shr r2404 r2408 into r2409; + mul r2409 r2409 into r2410; + shr r2410 63u8 into r2411; + shr r2411 64u8 into r2412; + shl r2412 57u8 into r2413; + or r2407 r2413 into r2414; + cast r2412 into r2415 as u8; + shr r2411 r2415 into r2416; + mul r2416 r2416 into r2417; + shr r2417 63u8 into r2418; + shr r2418 64u8 into r2419; + shl r2419 56u8 into r2420; + or r2414 r2420 into r2421; + cast r2419 into r2422 as u8; + shr r2418 r2422 into r2423; + mul r2423 r2423 into r2424; + shr r2424 63u8 into r2425; + shr r2425 64u8 into r2426; + shl r2426 55u8 into r2427; + or r2421 r2427 into r2428; + cast r2426 into r2429 as u8; + shr r2425 r2429 into r2430; + mul r2430 r2430 into r2431; + shr r2431 63u8 into r2432; + shr r2432 64u8 into r2433; + shl r2433 54u8 into r2434; + or r2428 r2434 into r2435; + cast r2433 into r2436 as u8; + shr r2432 r2436 into r2437; + mul r2437 r2437 into r2438; + shr r2438 63u8 into r2439; + shr r2439 64u8 into r2440; + shl r2440 53u8 into r2441; + or r2435 r2441 into r2442; + cast r2440 into r2443 as u8; + shr r2439 r2443 into r2444; + mul r2444 r2444 into r2445; + shr r2445 63u8 into r2446; + shr r2446 64u8 into r2447; + shl r2447 52u8 into r2448; + or r2442 r2448 into r2449; + cast r2447 into r2450 as u8; + shr r2446 r2450 into r2451; + mul r2451 r2451 into r2452; + shr r2452 63u8 into r2453; + shr r2453 64u8 into r2454; + shl r2454 51u8 into r2455; + or r2449 r2455 into r2456; + cast r2454 into r2457 as u8; + shr r2453 r2457 into r2458; + mul r2458 r2458 into r2459; + shr r2459 63u8 into r2460; + shr r2460 64u8 into r2461; + shl r2461 50u8 into r2462; + or r2456 r2462 into r2463; + cast r2360 into r2464 as i128; + sub r2464 63i128 into r2465; + shl r2465 64u8 into r2466; + cast r2463 into r2467 as i128; + add r2466 r2467 into r2468; + div r2468 1330584781654114i128 into r2469; + cast r2469 into r2470 as i32; + add r2470 1i32 into r2471; + gte r2471 -873409i32 into r2472; + lte r2471 873409i32 into r2473; + and r2472 r2473 into r2474; + assert.eq r2474 true; + lt r2471 0i32 into r2475; + sub 0i32 r2471 into r2476; + ternary r2475 r2476 r2471 into r2477; + gte r2477 0i32 into r2478; + assert.eq r2478 true; + cast r2477 into r2479 as u32; + and r2479 3u32 into r2480; + is.eq r2480 0u32 into r2481; + is.eq r2480 1u32 into r2482; + is.eq r2480 2u32 into r2483; + ternary r2483 9222449791875588096u128 9221988703967300608u128 into r2484; + ternary r2482 9222910902837697536u128 r2484 into r2485; + ternary r2481 9223372036854775808u128 r2485 into r2486; + and r2479 4u32 into r2487; + is.neq r2487 0u32 into r2488; + mul r2486 9221527639111677952u128 into r2489; + shr r2489 63u8 into r2490; + ternary r2488 r2490 r2486 into r2491; + and r2479 8u32 into r2492; + is.neq r2492 0u32 into r2493; + mul r2491 9219683610192801792u128 into r2494; + shr r2494 63u8 into r2495; + ternary r2493 r2495 r2491 into r2496; + and r2479 16u32 into r2497; + is.neq r2497 0u32 into r2498; + mul r2496 9215996658532725760u128 into r2499; + shr r2499 63u8 into r2500; + ternary r2498 r2500 r2496 into r2501; + and r2479 32u32 into r2502; + is.neq r2502 0u32 into r2503; + mul r2501 9208627177859081216u128 into r2504; + shr r2504 63u8 into r2505; + ternary r2503 r2505 r2501 into r2506; + and r2479 64u32 into r2507; + is.neq r2507 0u32 into r2508; + mul r2506 9193905890596798464u128 into r2509; + shr r2509 63u8 into r2510; + ternary r2508 r2510 r2506 into r2511; + and r2479 128u32 into r2512; + is.neq r2512 0u32 into r2513; + mul r2511 9164533880601766912u128 into r2514; + shr r2514 63u8 into r2515; + ternary r2513 r2515 r2511 into r2516; + and r2479 256u32 into r2517; + is.neq r2517 0u32 into r2518; + mul r2516 9106071067403056128u128 into r2519; + shr r2519 63u8 into r2520; + ternary r2518 r2520 r2516 into r2521; + and r2479 512u32 into r2522; + is.neq r2522 0u32 into r2523; + mul r2521 8990261907820801024u128 into r2524; + shr r2524 63u8 into r2525; + ternary r2523 r2525 r2521 into r2526; + and r2479 1024u32 into r2527; + is.neq r2527 0u32 into r2528; + mul r2526 8763043369415622656u128 into r2529; + shr r2529 63u8 into r2530; + ternary r2528 r2530 r2526 into r2531; + and r2479 2048u32 into r2532; + is.neq r2532 0u32 into r2533; + mul r2531 8325689215117605888u128 into r2534; + shr r2534 63u8 into r2535; + ternary r2533 r2535 r2531 into r2536; + and r2479 4096u32 into r2537; + is.neq r2537 0u32 into r2538; + mul r2536 7515375139346884608u128 into r2539; + shr r2539 63u8 into r2540; + ternary r2538 r2540 r2536 into r2541; + and r2479 8192u32 into r2542; + is.neq r2542 0u32 into r2543; + mul r2541 6123667489441693696u128 into r2544; + shr r2544 63u8 into r2545; + ternary r2543 r2545 r2541 into r2546; + and r2479 16384u32 into r2547; + is.neq r2547 0u32 into r2548; + mul r2546 4065682634442729984u128 into r2549; + shr r2549 63u8 into r2550; + ternary r2548 r2550 r2546 into r2551; + and r2479 32768u32 into r2552; + is.neq r2552 0u32 into r2553; + mul r2551 1792161827361994496u128 into r2554; + shr r2554 63u8 into r2555; + ternary r2553 r2555 r2551 into r2556; + and r2479 65536u32 into r2557; + is.neq r2557 0u32 into r2558; + mul r2556 348228825923923264u128 into r2559; + shr r2559 63u8 into r2560; + ternary r2558 r2560 r2556 into r2561; + and r2479 131072u32 into r2562; + is.neq r2562 0u32 into r2563; + mul r2561 13147394978735516u128 into r2564; + shr r2564 63u8 into r2565; + ternary r2563 r2565 r2561 into r2566; + and r2479 262144u32 into r2567; + is.neq r2567 0u32 into r2568; + mul r2566 18740867660568u128 into r2569; + shr r2569 63u8 into r2570; + ternary r2568 r2570 r2566 into r2571; + and r2479 524288u32 into r2572; + is.neq r2572 0u32 into r2573; + mul r2571 38079361u128 into r2574; + shr r2574 63u8 into r2575; + ternary r2573 r2575 r2571 into r2576; + gt r2471 0i32 into r2577; + div 85070591730234615865843651857942052864u128 r2576 into r2578; + ternary r2577 r2578 r2576 into r2579; + gte r2191 r2579 into r2580; + ternary r2580 r2471 r2470 into r2581; + gte r2581 -873409i32 into r2582; + lte r2581 873409i32 into r2583; + and r2582 r2583 into r2584; + assert.eq r2584 true; + lt r2581 0i32 into r2585; + sub 0i32 r2581 into r2586; + ternary r2585 r2586 r2581 into r2587; + gte r2587 0i32 into r2588; + assert.eq r2588 true; + cast r2587 into r2589 as u32; + and r2589 3u32 into r2590; + is.eq r2590 0u32 into r2591; + is.eq r2590 1u32 into r2592; + is.eq r2590 2u32 into r2593; + ternary r2593 9222449791875588096u128 9221988703967300608u128 into r2594; + ternary r2592 9222910902837697536u128 r2594 into r2595; + ternary r2591 9223372036854775808u128 r2595 into r2596; + and r2589 4u32 into r2597; + is.neq r2597 0u32 into r2598; + mul r2596 9221527639111677952u128 into r2599; + shr r2599 63u8 into r2600; + ternary r2598 r2600 r2596 into r2601; + and r2589 8u32 into r2602; + is.neq r2602 0u32 into r2603; + mul r2601 9219683610192801792u128 into r2604; + shr r2604 63u8 into r2605; + ternary r2603 r2605 r2601 into r2606; + and r2589 16u32 into r2607; + is.neq r2607 0u32 into r2608; + mul r2606 9215996658532725760u128 into r2609; + shr r2609 63u8 into r2610; + ternary r2608 r2610 r2606 into r2611; + and r2589 32u32 into r2612; + is.neq r2612 0u32 into r2613; + mul r2611 9208627177859081216u128 into r2614; + shr r2614 63u8 into r2615; + ternary r2613 r2615 r2611 into r2616; + and r2589 64u32 into r2617; + is.neq r2617 0u32 into r2618; + mul r2616 9193905890596798464u128 into r2619; + shr r2619 63u8 into r2620; + ternary r2618 r2620 r2616 into r2621; + and r2589 128u32 into r2622; + is.neq r2622 0u32 into r2623; + mul r2621 9164533880601766912u128 into r2624; + shr r2624 63u8 into r2625; + ternary r2623 r2625 r2621 into r2626; + and r2589 256u32 into r2627; + is.neq r2627 0u32 into r2628; + mul r2626 9106071067403056128u128 into r2629; + shr r2629 63u8 into r2630; + ternary r2628 r2630 r2626 into r2631; + and r2589 512u32 into r2632; + is.neq r2632 0u32 into r2633; + mul r2631 8990261907820801024u128 into r2634; + shr r2634 63u8 into r2635; + ternary r2633 r2635 r2631 into r2636; + and r2589 1024u32 into r2637; + is.neq r2637 0u32 into r2638; + mul r2636 8763043369415622656u128 into r2639; + shr r2639 63u8 into r2640; + ternary r2638 r2640 r2636 into r2641; + and r2589 2048u32 into r2642; + is.neq r2642 0u32 into r2643; + mul r2641 8325689215117605888u128 into r2644; + shr r2644 63u8 into r2645; + ternary r2643 r2645 r2641 into r2646; + and r2589 4096u32 into r2647; + is.neq r2647 0u32 into r2648; + mul r2646 7515375139346884608u128 into r2649; + shr r2649 63u8 into r2650; + ternary r2648 r2650 r2646 into r2651; + and r2589 8192u32 into r2652; + is.neq r2652 0u32 into r2653; + mul r2651 6123667489441693696u128 into r2654; + shr r2654 63u8 into r2655; + ternary r2653 r2655 r2651 into r2656; + and r2589 16384u32 into r2657; + is.neq r2657 0u32 into r2658; + mul r2656 4065682634442729984u128 into r2659; + shr r2659 63u8 into r2660; + ternary r2658 r2660 r2656 into r2661; + and r2589 32768u32 into r2662; + is.neq r2662 0u32 into r2663; + mul r2661 1792161827361994496u128 into r2664; + shr r2664 63u8 into r2665; + ternary r2663 r2665 r2661 into r2666; + and r2589 65536u32 into r2667; + is.neq r2667 0u32 into r2668; + mul r2666 348228825923923264u128 into r2669; + shr r2669 63u8 into r2670; + ternary r2668 r2670 r2666 into r2671; + and r2589 131072u32 into r2672; + is.neq r2672 0u32 into r2673; + mul r2671 13147394978735516u128 into r2674; + shr r2674 63u8 into r2675; + ternary r2673 r2675 r2671 into r2676; + and r2589 262144u32 into r2677; + is.neq r2677 0u32 into r2678; + mul r2676 18740867660568u128 into r2679; + shr r2679 63u8 into r2680; + ternary r2678 r2680 r2676 into r2681; + and r2589 524288u32 into r2682; + is.neq r2682 0u32 into r2683; + mul r2681 38079361u128 into r2684; + shr r2684 63u8 into r2685; + ternary r2683 r2685 r2681 into r2686; + gt r2581 0i32 into r2687; + div 85070591730234615865843651857942052864u128 r2686 into r2688; + ternary r2687 r2688 r2686 into r2689; + gt r2689 r2191 into r2690; + sub r2581 1i32 into r2691; + ternary r2690 r2691 r2581 into r2692; + ternary r2328 r3.tk r2692 into r2693; + ternary r2280 r2327 r2693 into r2694; + ternary r0.z r2.prev r1 into r2695; + ternary r2280 r2695 r3.nb into r2696; + ternary r0.z r1 r2.next into r2697; + ternary r2280 r2697 r3.na into r2698; + cast r2191 r2203 r2204 r2276 r2325 r2694 r2280 r2199 r2696 r2698 r2263 into r2699 as SwapIterState; + output r2699 as SwapIterState.public; + output r2309 as Tick.public; + +function swap: + input r0 as dynamic.record; + input r1 as field.private; + input r2 as address.public; + input r3 as field.public; + input r4 as boolean.public; + input r5 as u128.public; + input r6 as u128.public; + input r7 as u128.public; + input r8 as u64.public; + input r9 as u32.public; + input r10 as field.public; + input r11 as field.public; + call verify_blinded_address shield_swap_v3.aleo self.signer r1 r2; + cast r3 r4 r5 r6 r7 r2 r8 r9 into r12 as SwapRequest; + cast r3 r4 r5 r7 r2 r8 r2 into r13 as SwapKey; + hash.bhp256 r13 into r14 as field; + ternary r4 r10 r11 into r15; + ternary r4 r11 r10 into r16; + cast aleo1t08epjqqv8h7jpuy2m2cxm80zy2pcy5c4f3m82hnac4sjmdrjyysvx3s2h r14 r15 r16 r12 self.caller r2 into r17 as SwapComplianceRecord.record; + call.dynamic r15 'aleo' 'transfer_private_to_public' with r0 shield_swap_v3.aleo r5 (as dynamic.record address.public u128.public) into r18 r19 (as dynamic.record dynamic.future); + async swap r19 r12 r10 r11 r14 r15 r16 r2 into r20; + output r14 as field.public; + output r18 as dynamic.record; + output r17 as SwapComplianceRecord.record; + output r20 as shield_swap_v3.aleo/swap.future; + +finalize swap: + input r0 as dynamic.future; + input r1 as SwapRequest.public; + input r2 as field.public; + input r3 as field.public; + input r4 as field.public; + input r5 as field.public; + input r6 as field.public; + input r7 as address.public; + await r0; + lte block.height r1.deadline into r8; + assert.eq r8 true; + get.or_use global_paused[true] false into r9; + not r9 into r10; + assert.eq r10 true; + get pools[r1.pool] into r11; + assert.eq r11.enabled true; + get.or_use token_paused[r11.token0] false into r12; + not r12 into r13; + assert.eq r13 true; + get.or_use token_paused[r11.token1] false into r14; + not r14 into r15; + assert.eq r15 true; + cast r11.token0 r11.token1 into r16 as PairKey; + get.or_use pair_paused[r16] false into r17; + not r17 into r18; + assert.eq r18 true; + is.eq r11.token0 r2 into r19; + assert.eq r19 true; + is.eq r11.token1 r3 into r20; + assert.eq r20 true; + get slots[r1.pool] into r21; + cast r11.fee into r22 as u32; + gte r1.sqrt_price_limit 19029805711u128 into r23; + lte r1.sqrt_price_limit 4470386772317930780047134862u128 into r24; + and r23 r24 into r25; + assert.eq r25 true; + lt r1.sqrt_price_limit r21.sqrt_price into r26; + gt r1.sqrt_price_limit r21.sqrt_price into r27; + ternary r1.zero_for_one r26 r27 into r28; + assert.eq r28 true; + gt r1.amount_in 0u128 into r29; + assert.eq r29 true; + ternary r1.zero_for_one r11.scale0 r11.scale1 into r30; + ternary r1.zero_for_one r11.scale1 r11.scale0 into r31; + rem r1.amount_in r30 into r32; + is.eq r32 0u128 into r33; + assert.eq r33 true; + div r1.amount_in r30 into r34; + ternary r1.zero_for_one r21.fee_growth_global0_x_64 r21.fee_growth_global1_x_64 into r35; + ternary r1.zero_for_one r21.fee_residual0_x_64 r21.fee_residual1_x_64 into r36; + cast r1.zero_for_one r1.sqrt_price_limit r22 r21.fee_protocol r21.fee_growth_global0_x_64 r21.fee_growth_global1_x_64 into r37 as SwapIterCfg; + ternary r1.zero_for_one r21.next_init_below r21.next_init_above into r38; + cast r1.pool r38 into r39 as TickKey; + hash.bhp256 r39 into r40 as field; + get ticks[r40] into r41; + cast r21.sqrt_price r34 0u128 r35 r21.liquidity r21.tick true 0u128 r21.next_init_below r21.next_init_above r36 into r42 as SwapIterState; + call view_swap_iteration r37 r38 r41 r42 into r43 r44; + cast r1.pool r38 into r45 as TickKey; + hash.bhp256 r45 into r46 as field; + set r44 into ticks[r46]; + ternary r1.zero_for_one r43.nb r43.na into r47; + cast r1.pool r47 into r48 as TickKey; + hash.bhp256 r48 into r49 as field; + get ticks[r49] into r50; + cast r43.sp r43.rem r43.out r43.fg r43.liq r43.tk r43.crossed r43.pf r43.nb r43.na r43.resid into r51 as SwapIterState; + call view_swap_iteration r37 r47 r50 r51 into r52 r53; + cast r1.pool r47 into r54 as TickKey; + hash.bhp256 r54 into r55 as field; + set r53 into ticks[r55]; + ternary r1.zero_for_one r52.nb r52.na into r56; + cast r1.pool r56 into r57 as TickKey; + hash.bhp256 r57 into r58 as field; + get ticks[r58] into r59; + cast r52.sp r52.rem r52.out r52.fg r52.liq r52.tk r52.crossed r52.pf r52.nb r52.na r52.resid into r60 as SwapIterState; + call view_swap_iteration r37 r56 r59 r60 into r61 r62; + cast r1.pool r56 into r63 as TickKey; + hash.bhp256 r63 into r64 as field; + set r62 into ticks[r64]; + ternary r1.zero_for_one r61.nb r61.na into r65; + cast r1.pool r65 into r66 as TickKey; + hash.bhp256 r66 into r67 as field; + get ticks[r67] into r68; + cast r61.sp r61.rem r61.out r61.fg r61.liq r61.tk r61.crossed r61.pf r61.nb r61.na r61.resid into r69 as SwapIterState; + call view_swap_iteration r37 r65 r68 r69 into r70 r71; + cast r1.pool r65 into r72 as TickKey; + hash.bhp256 r72 into r73 as field; + set r71 into ticks[r73]; + ternary r1.zero_for_one r70.nb r70.na into r74; + cast r1.pool r74 into r75 as TickKey; + hash.bhp256 r75 into r76 as field; + get ticks[r76] into r77; + cast r70.sp r70.rem r70.out r70.fg r70.liq r70.tk r70.crossed r70.pf r70.nb r70.na r70.resid into r78 as SwapIterState; + call view_swap_iteration r37 r74 r77 r78 into r79 r80; + cast r1.pool r74 into r81 as TickKey; + hash.bhp256 r81 into r82 as field; + set r80 into ticks[r82]; + mul r79.out r31 into r83; + mul r79.rem r30 into r84; + gte r83 r1.amount_out_min into r85; + assert.eq r85 true; + add r21.protocol_fees0 r79.pf into r86; + ternary r1.zero_for_one r86 r21.protocol_fees0 into r87; + add r21.protocol_fees1 r79.pf into r88; + ternary r1.zero_for_one r21.protocol_fees1 r88 into r89; + ternary r1.zero_for_one r79.fg r21.fee_growth_global0_x_64 into r90; + ternary r1.zero_for_one r21.fee_growth_global1_x_64 r79.fg into r91; + ternary r1.zero_for_one r79.resid r21.fee_residual0_x_64 into r92; + ternary r1.zero_for_one r21.fee_residual1_x_64 r79.resid into r93; + cast r79.tk r21.tick_spacing r79.sp r21.fee_protocol r79.liq r90 r91 r92 r93 r21.max_liquidity_per_tick r87 r89 r79.nb r79.na into r94 as Slot; + set r94 into slots[r1.pool]; + contains swap_outputs[r4] into r95; + not r95 into r96; + assert.eq r96 true; + cast r1.recipient r7 r5 r6 r83 r84 r5 0u128 r5 0u128 into r97 as SwapOutput; + set r97 into swap_outputs[r4]; + contains used_blinded_addresses[r7] into r98; + not r98 into r99; + assert.eq r99 true; + set true into used_blinded_addresses[r7]; + +function claim_swap_output: + input r0 as field.private; + input r1 as address.public; + input r2 as field.public; + input r3 as field.public; + input r4 as field.public; + input r5 as u128.public; + input r6 as u128.public; + call verify_blinded_address shield_swap_v3.aleo self.signer r0 r1; + call.dynamic r4 'aleo' 'transfer_public_to_private' with self.signer r5 (as address.private u128.public) into r7 r8 (as dynamic.record dynamic.future); + call.dynamic r3 'aleo' 'transfer_public_to_private' with self.signer r6 (as address.private u128.public) into r9 r10 (as dynamic.record dynamic.future); + async claim_swap_output r8 r10 r2 r3 r4 r5 r6 r1 into r11; + output r7 as dynamic.record; + output r9 as dynamic.record; + output r11 as shield_swap_v3.aleo/claim_swap_output.future; + +finalize claim_swap_output: + input r0 as dynamic.future; + input r1 as dynamic.future; + input r2 as field.public; + input r3 as field.public; + input r4 as field.public; + input r5 as u128.public; + input r6 as u128.public; + input r7 as address.public; + await r0; + await r1; + get swap_outputs[r2] into r8; + is.eq r8.caller r7 into r9; + assert.eq r9 true; + is.eq r8.recipient r7 into r10; + assert.eq r10 true; + is.eq r8.token_in r3 into r11; + assert.eq r11 true; + is.eq r8.token_out r4 into r12; + assert.eq r12 true; + is.eq r8.amount_out r5 into r13; + assert.eq r13 true; + is.eq r8.amount_remaining r6 into r14; + assert.eq r14 true; + is.eq r8.amount_remaining_1 0u128 into r15; + assert.eq r15 true; + is.eq r8.amount_remaining_2 0u128 into r16; + assert.eq r16 true; + remove swap_outputs[r2]; + +function swap_multi_hop: + input r0 as field.private; + input r1 as address.public; + input r2 as dynamic.record; + input r3 as field.public; + input r4 as field.public; + input r5 as u128.public; + input r6 as u128.public; + input r7 as SwapHop.public; + input r8 as SwapHop.public; + input r9 as SwapHop.public; + input r10 as u8.public; + input r11 as u64.public; + input r12 as u32.public; + call verify_blinded_address shield_swap_v3.aleo self.signer r0 r1; + cast r3 r4 r5 r6 r1 r7 r8 r9 r10 r11 r12 r1 into r13 as SwapMultiHopRequest; + hash.bhp256 r13 into r14 as field; + cast aleo1t08epjqqv8h7jpuy2m2cxm80zy2pcy5c4f3m82hnac4sjmdrjyysvx3s2h r14 r13 self.caller r1 into r15 as MultiHopSwapComplianceRecord.record; + call.dynamic r3 'aleo' 'transfer_private_to_public' with r2 shield_swap_v3.aleo r5 (as dynamic.record address.public u128.public) into r16 r17 (as dynamic.record dynamic.future); + async swap_multi_hop r17 r13 r14 into r18; + output r14 as field.public; + output r16 as dynamic.record; + output r15 as MultiHopSwapComplianceRecord.record; + output r18 as shield_swap_v3.aleo/swap_multi_hop.future; + +finalize swap_multi_hop: + input r0 as dynamic.future; + input r1 as SwapMultiHopRequest.public; + input r2 as field.public; + await r0; + lte block.height r1.deadline into r3; + assert.eq r3 true; + gte r1.hop_count 2u8 into r4; + lte r1.hop_count 3u8 into r5; + and r4 r5 into r6; + assert.eq r6 true; + gt r1.amount_in 0u128 into r7; + assert.eq r7 true; + get.or_use global_paused[true] false into r8; + not r8 into r9; + assert.eq r9 true; + get pools[r1.hop0.pool] into r10; + assert.eq r10.enabled true; + get.or_use token_paused[r10.token0] false into r11; + not r11 into r12; + assert.eq r12 true; + get.or_use token_paused[r10.token1] false into r13; + not r13 into r14; + assert.eq r14 true; + cast r10.token0 r10.token1 into r15 as PairKey; + get.or_use pair_paused[r15] false into r16; + not r16 into r17; + assert.eq r17 true; + ternary r1.hop0.zero_for_one r10.token0 r10.token1 into r18; + ternary r1.hop0.zero_for_one r10.token1 r10.token0 into r19; + is.eq r18 r1.token_in into r20; + assert.eq r20 true; + get slots[r1.hop0.pool] into r21; + cast r10.fee into r22 as u32; + gte r1.hop0.sqrt_price_limit 19029805711u128 into r23; + lte r1.hop0.sqrt_price_limit 4470386772317930780047134862u128 into r24; + and r23 r24 into r25; + assert.eq r25 true; + lt r1.hop0.sqrt_price_limit r21.sqrt_price into r26; + gt r1.hop0.sqrt_price_limit r21.sqrt_price into r27; + ternary r1.hop0.zero_for_one r26 r27 into r28; + assert.eq r28 true; + ternary r1.hop0.zero_for_one r10.scale0 r10.scale1 into r29; + rem r1.amount_in r29 into r30; + is.eq r30 0u128 into r31; + assert.eq r31 true; + div r1.amount_in r29 into r32; + ternary r1.hop0.zero_for_one r21.fee_growth_global0_x_64 r21.fee_growth_global1_x_64 into r33; + ternary r1.hop0.zero_for_one r21.fee_residual0_x_64 r21.fee_residual1_x_64 into r34; + cast r1.hop0.zero_for_one r1.hop0.sqrt_price_limit r22 r21.fee_protocol r21.fee_growth_global0_x_64 r21.fee_growth_global1_x_64 into r35 as SwapIterCfg; + ternary r1.hop0.zero_for_one r21.next_init_below r21.next_init_above into r36; + cast r1.hop0.pool r36 into r37 as TickKey; + hash.bhp256 r37 into r38 as field; + get ticks[r38] into r39; + cast r21.sqrt_price r32 0u128 r33 r21.liquidity r21.tick true 0u128 r21.next_init_below r21.next_init_above r34 into r40 as SwapIterState; + call view_swap_iteration r35 r36 r39 r40 into r41 r42; + cast r1.hop0.pool r36 into r43 as TickKey; + hash.bhp256 r43 into r44 as field; + set r42 into ticks[r44]; + ternary r1.hop0.zero_for_one r41.nb r41.na into r45; + cast r1.hop0.pool r45 into r46 as TickKey; + hash.bhp256 r46 into r47 as field; + get ticks[r47] into r48; + cast r41.sp r41.rem r41.out r41.fg r41.liq r41.tk r41.crossed r41.pf r41.nb r41.na r41.resid into r49 as SwapIterState; + call view_swap_iteration r35 r45 r48 r49 into r50 r51; + cast r1.hop0.pool r45 into r52 as TickKey; + hash.bhp256 r52 into r53 as field; + set r51 into ticks[r53]; + ternary r1.hop0.zero_for_one r50.nb r50.na into r54; + cast r1.hop0.pool r54 into r55 as TickKey; + hash.bhp256 r55 into r56 as field; + get ticks[r56] into r57; + cast r50.sp r50.rem r50.out r50.fg r50.liq r50.tk r50.crossed r50.pf r50.nb r50.na r50.resid into r58 as SwapIterState; + call view_swap_iteration r35 r54 r57 r58 into r59 r60; + cast r1.hop0.pool r54 into r61 as TickKey; + hash.bhp256 r61 into r62 as field; + set r60 into ticks[r62]; + add r21.protocol_fees0 r59.pf into r63; + ternary r1.hop0.zero_for_one r63 r21.protocol_fees0 into r64; + add r21.protocol_fees1 r59.pf into r65; + ternary r1.hop0.zero_for_one r21.protocol_fees1 r65 into r66; + ternary r1.hop0.zero_for_one r59.fg r21.fee_growth_global0_x_64 into r67; + ternary r1.hop0.zero_for_one r21.fee_growth_global1_x_64 r59.fg into r68; + ternary r1.hop0.zero_for_one r59.resid r21.fee_residual0_x_64 into r69; + ternary r1.hop0.zero_for_one r21.fee_residual1_x_64 r59.resid into r70; + cast r59.tk r21.tick_spacing r59.sp r21.fee_protocol r59.liq r67 r68 r69 r70 r21.max_liquidity_per_tick r64 r66 r59.nb r59.na into r71 as Slot; + set r71 into slots[r1.hop0.pool]; + get pools[r1.hop1.pool] into r72; + assert.eq r72.enabled true; + get.or_use token_paused[r72.token0] false into r73; + not r73 into r74; + assert.eq r74 true; + get.or_use token_paused[r72.token1] false into r75; + not r75 into r76; + assert.eq r76 true; + cast r72.token0 r72.token1 into r77 as PairKey; + get.or_use pair_paused[r77] false into r78; + not r78 into r79; + assert.eq r79 true; + ternary r1.hop1.zero_for_one r72.token0 r72.token1 into r80; + ternary r1.hop1.zero_for_one r72.token1 r72.token0 into r81; + is.eq r80 r19 into r82; + assert.eq r82 true; + get slots[r1.hop1.pool] into r83; + cast r72.fee into r84 as u32; + gte r1.hop1.sqrt_price_limit 19029805711u128 into r85; + lte r1.hop1.sqrt_price_limit 4470386772317930780047134862u128 into r86; + and r85 r86 into r87; + assert.eq r87 true; + lt r1.hop1.sqrt_price_limit r83.sqrt_price into r88; + gt r1.hop1.sqrt_price_limit r83.sqrt_price into r89; + ternary r1.hop1.zero_for_one r88 r89 into r90; + assert.eq r90 true; + ternary r1.hop1.zero_for_one r83.fee_growth_global0_x_64 r83.fee_growth_global1_x_64 into r91; + ternary r1.hop1.zero_for_one r83.fee_residual0_x_64 r83.fee_residual1_x_64 into r92; + cast r1.hop1.zero_for_one r1.hop1.sqrt_price_limit r84 r83.fee_protocol r83.fee_growth_global0_x_64 r83.fee_growth_global1_x_64 into r93 as SwapIterCfg; + ternary r1.hop1.zero_for_one r83.next_init_below r83.next_init_above into r94; + cast r1.hop1.pool r94 into r95 as TickKey; + hash.bhp256 r95 into r96 as field; + get ticks[r96] into r97; + cast r83.sqrt_price r59.out 0u128 r91 r83.liquidity r83.tick true 0u128 r83.next_init_below r83.next_init_above r92 into r98 as SwapIterState; + call view_swap_iteration r93 r94 r97 r98 into r99 r100; + cast r1.hop1.pool r94 into r101 as TickKey; + hash.bhp256 r101 into r102 as field; + set r100 into ticks[r102]; + ternary r1.hop1.zero_for_one r99.nb r99.na into r103; + cast r1.hop1.pool r103 into r104 as TickKey; + hash.bhp256 r104 into r105 as field; + get ticks[r105] into r106; + cast r99.sp r99.rem r99.out r99.fg r99.liq r99.tk r99.crossed r99.pf r99.nb r99.na r99.resid into r107 as SwapIterState; + call view_swap_iteration r93 r103 r106 r107 into r108 r109; + cast r1.hop1.pool r103 into r110 as TickKey; + hash.bhp256 r110 into r111 as field; + set r109 into ticks[r111]; + ternary r1.hop1.zero_for_one r108.nb r108.na into r112; + cast r1.hop1.pool r112 into r113 as TickKey; + hash.bhp256 r113 into r114 as field; + get ticks[r114] into r115; + cast r108.sp r108.rem r108.out r108.fg r108.liq r108.tk r108.crossed r108.pf r108.nb r108.na r108.resid into r116 as SwapIterState; + call view_swap_iteration r93 r112 r115 r116 into r117 r118; + cast r1.hop1.pool r112 into r119 as TickKey; + hash.bhp256 r119 into r120 as field; + set r118 into ticks[r120]; + add r83.protocol_fees0 r117.pf into r121; + ternary r1.hop1.zero_for_one r121 r83.protocol_fees0 into r122; + add r83.protocol_fees1 r117.pf into r123; + ternary r1.hop1.zero_for_one r83.protocol_fees1 r123 into r124; + ternary r1.hop1.zero_for_one r117.fg r83.fee_growth_global0_x_64 into r125; + ternary r1.hop1.zero_for_one r83.fee_growth_global1_x_64 r117.fg into r126; + ternary r1.hop1.zero_for_one r117.resid r83.fee_residual0_x_64 into r127; + ternary r1.hop1.zero_for_one r83.fee_residual1_x_64 r117.resid into r128; + cast r117.tk r83.tick_spacing r117.sp r83.fee_protocol r117.liq r125 r126 r127 r128 r83.max_liquidity_per_tick r122 r124 r117.nb r117.na into r129 as Slot; + set r129 into slots[r1.hop1.pool]; + is.eq r1.hop_count 3u8 into r130; + cast 0field 0field 0u16 false 1u128 1u128 into r131 as PoolState; + get.or_use pools[r1.hop2.pool] r131 into r132; + branch.eq r130 false to end_then_0_0; + assert.eq r132.enabled true; + get.or_use token_paused[r132.token0] false into r133; + not r133 into r134; + assert.eq r134 true; + get.or_use token_paused[r132.token1] false into r135; + not r135 into r136; + assert.eq r136 true; + cast r132.token0 r132.token1 into r137 as PairKey; + get.or_use pair_paused[r137] false into r138; + not r138 into r139; + assert.eq r139 true; + branch.eq true true to end_otherwise_0_1; + position end_then_0_0; + position end_otherwise_0_1; + ternary r1.hop2.zero_for_one r132.token0 r132.token1 into r140; + ternary r1.hop2.zero_for_one r132.token1 r132.token0 into r141; + not r130 into r142; + is.eq r140 r81 into r143; + or r142 r143 into r144; + assert.eq r144 true; + ternary r130 r141 r81 into r145; + is.eq r145 r1.token_out into r146; + assert.eq r146 true; + cast 0i32 1u32 9223372036854775808u128 0u8 0u128 0u128 0u128 0u128 0u128 0u128 0u128 0u128 0i32 0i32 into r147 as Slot; + get.or_use slots[r1.hop2.pool] r147 into r148; + cast r132.fee into r149 as u32; + gte r1.hop2.sqrt_price_limit 19029805711u128 into r150; + lte r1.hop2.sqrt_price_limit 4470386772317930780047134862u128 into r151; + and r150 r151 into r152; + or r142 r152 into r153; + assert.eq r153 true; + lt r1.hop2.sqrt_price_limit r148.sqrt_price into r154; + gt r1.hop2.sqrt_price_limit r148.sqrt_price into r155; + ternary r1.hop2.zero_for_one r154 r155 into r156; + or r142 r156 into r157; + assert.eq r157 true; + ternary r1.hop2.zero_for_one r148.fee_growth_global0_x_64 r148.fee_growth_global1_x_64 into r158; + ternary r1.hop2.zero_for_one r148.fee_residual0_x_64 r148.fee_residual1_x_64 into r159; + cast r1.hop2.zero_for_one r1.hop2.sqrt_price_limit r149 r148.fee_protocol r148.fee_growth_global0_x_64 r148.fee_growth_global1_x_64 into r160 as SwapIterCfg; + ternary r1.hop2.zero_for_one r148.next_init_below r148.next_init_above into r161; + cast r1.hop2.pool 0i128 0u128 r161 0u128 0u128 r161 r161 into r162 as Tick; + cast r1.hop2.pool r161 into r163 as TickKey; + hash.bhp256 r163 into r164 as field; + get.or_use ticks[r164] r162 into r165; + cast r148.sqrt_price r117.out 0u128 r158 r148.liquidity r148.tick r130 0u128 r148.next_init_below r148.next_init_above r159 into r166 as SwapIterState; + call view_swap_iteration r160 r161 r165 r166 into r167 r168; + branch.eq r130 false to end_then_0_2; + cast r1.hop2.pool r161 into r169 as TickKey; + hash.bhp256 r169 into r170 as field; + set r168 into ticks[r170]; + branch.eq true true to end_otherwise_0_3; + position end_then_0_2; + position end_otherwise_0_3; + ternary r1.hop2.zero_for_one r167.nb r167.na into r171; + cast r1.hop2.pool 0i128 0u128 r171 0u128 0u128 r171 r171 into r172 as Tick; + cast r1.hop2.pool r171 into r173 as TickKey; + hash.bhp256 r173 into r174 as field; + get.or_use ticks[r174] r172 into r175; + cast r167.sp r167.rem r167.out r167.fg r167.liq r167.tk r167.crossed r167.pf r167.nb r167.na r167.resid into r176 as SwapIterState; + call view_swap_iteration r160 r171 r175 r176 into r177 r178; + branch.eq r130 false to end_then_0_4; + cast r1.hop2.pool r171 into r179 as TickKey; + hash.bhp256 r179 into r180 as field; + set r178 into ticks[r180]; + branch.eq true true to end_otherwise_0_5; + position end_then_0_4; + position end_otherwise_0_5; + ternary r1.hop2.zero_for_one r177.nb r177.na into r181; + cast r1.hop2.pool 0i128 0u128 r181 0u128 0u128 r181 r181 into r182 as Tick; + cast r1.hop2.pool r181 into r183 as TickKey; + hash.bhp256 r183 into r184 as field; + get.or_use ticks[r184] r182 into r185; + cast r177.sp r177.rem r177.out r177.fg r177.liq r177.tk r177.crossed r177.pf r177.nb r177.na r177.resid into r186 as SwapIterState; + call view_swap_iteration r160 r181 r185 r186 into r187 r188; + branch.eq r130 false to end_then_0_6; + cast r1.hop2.pool r181 into r189 as TickKey; + hash.bhp256 r189 into r190 as field; + set r188 into ticks[r190]; + branch.eq true true to end_otherwise_0_7; + position end_then_0_6; + position end_otherwise_0_7; + add r148.protocol_fees0 r187.pf into r191; + ternary r1.hop2.zero_for_one r191 r148.protocol_fees0 into r192; + add r148.protocol_fees1 r187.pf into r193; + ternary r1.hop2.zero_for_one r148.protocol_fees1 r193 into r194; + branch.eq r130 false to end_then_0_8; + ternary r1.hop2.zero_for_one r187.fg r148.fee_growth_global0_x_64 into r195; + ternary r1.hop2.zero_for_one r148.fee_growth_global1_x_64 r187.fg into r196; + ternary r1.hop2.zero_for_one r187.resid r148.fee_residual0_x_64 into r197; + ternary r1.hop2.zero_for_one r148.fee_residual1_x_64 r187.resid into r198; + cast r187.tk r148.tick_spacing r187.sp r148.fee_protocol r187.liq r195 r196 r197 r198 r148.max_liquidity_per_tick r192 r194 r187.nb r187.na into r199 as Slot; + set r199 into slots[r1.hop2.pool]; + branch.eq true true to end_otherwise_0_9; + position end_then_0_8; + position end_otherwise_0_9; + ternary r1.hop1.zero_for_one r72.scale0 r72.scale1 into r200; + ternary r1.hop2.zero_for_one r132.scale0 r132.scale1 into r201; + ternary r1.hop2.zero_for_one r132.scale1 r132.scale0 into r202; + ternary r1.hop1.zero_for_one r72.scale1 r72.scale0 into r203; + ternary r130 r202 r203 into r204; + ternary r130 r187.out r117.out into r205; + mul r205 r204 into r206; + gte r206 r1.amount_out_min into r207; + assert.eq r207 true; + contains swap_outputs[r2] into r208; + not r208 into r209; + assert.eq r209 true; + ternary r130 r140 r80 into r210; + mul r59.rem r29 into r211; + mul r117.rem r200 into r212; + mul r187.rem r201 into r213; + ternary r130 r213 0u128 into r214; + cast r1.recipient r1.caller r18 r1.token_out r206 r211 r80 r212 r210 r214 into r215 as SwapOutput; + set r215 into swap_outputs[r2]; + contains used_blinded_addresses[r1.caller] into r216; + not r216 into r217; + assert.eq r217 true; + set true into used_blinded_addresses[r1.caller]; + +function claim_multi_hop_output: + input r0 as field.private; + input r1 as address.public; + input r2 as field.public; + input r3 as field.public; + input r4 as field.public; + input r5 as u128.public; + input r6 as u128.public; + input r7 as field.public; + input r8 as u128.public; + input r9 as field.public; + input r10 as u128.public; + call verify_blinded_address shield_swap_v3.aleo self.signer r0 r1; + call.dynamic r4 'aleo' 'transfer_public_to_private' with self.signer r5 (as address.private u128.public) into r11 r12 (as dynamic.record dynamic.future); + call.dynamic r3 'aleo' 'transfer_public_to_private' with self.signer r6 (as address.private u128.public) into r13 r14 (as dynamic.record dynamic.future); + call.dynamic r7 'aleo' 'transfer_public_to_private' with self.signer r8 (as address.private u128.public) into r15 r16 (as dynamic.record dynamic.future); + call.dynamic r9 'aleo' 'transfer_public_to_private' with self.signer r10 (as address.private u128.public) into r17 r18 (as dynamic.record dynamic.future); + async claim_multi_hop_output r12 r14 r16 r18 r2 r3 r4 r5 r6 r7 r8 r9 r10 r1 into r19; + output r11 as dynamic.record; + output r13 as dynamic.record; + output r15 as dynamic.record; + output r17 as dynamic.record; + output r19 as shield_swap_v3.aleo/claim_multi_hop_output.future; + +finalize claim_multi_hop_output: + input r0 as dynamic.future; + input r1 as dynamic.future; + input r2 as dynamic.future; + input r3 as dynamic.future; + input r4 as field.public; + input r5 as field.public; + input r6 as field.public; + input r7 as u128.public; + input r8 as u128.public; + input r9 as field.public; + input r10 as u128.public; + input r11 as field.public; + input r12 as u128.public; + input r13 as address.public; + await r0; + await r1; + await r2; + await r3; + get swap_outputs[r4] into r14; + is.eq r14.caller r13 into r15; + assert.eq r15 true; + is.eq r14.recipient r13 into r16; + assert.eq r16 true; + is.eq r14.token_in r5 into r17; + assert.eq r17 true; + is.eq r14.token_out r6 into r18; + assert.eq r18 true; + is.eq r14.amount_out r7 into r19; + assert.eq r19 true; + is.eq r14.amount_remaining r8 into r20; + assert.eq r20 true; + is.eq r14.token_in_1 r9 into r21; + assert.eq r21 true; + is.eq r14.amount_remaining_1 r10 into r22; + assert.eq r22 true; + is.eq r14.token_in_2 r11 into r23; + assert.eq r23 true; + is.eq r14.amount_remaining_2 r12 into r24; + assert.eq r24 true; + remove swap_outputs[r4]; + +constructor: + is.eq edition 0u16 into r0; + branch.eq r0 false to end_then_0_0; + contains admin[true] into r1; + not r1 into r2; + assert.eq r2 true; + set aleo1z3zwzgpgakk89xpknync5rtklkjkyv33g7cvaqe0gku64zs3lv9qyux0qc into admin[true]; + set false into pool_creation_is_open[true]; + set false into global_paused[true]; + branch.eq true true to end_otherwise_0_1; + position end_then_0_0; + position end_otherwise_0_1; + gt edition 0u16 into r3; + branch.eq r3 false to end_then_0_2; + cast checksum edition into r4 as ChecksumEdition; + hash.bhp256 r4 into r5 as field; + cast shield_swap_v3.aleo r5 into r6 as test_shield_swap_multisig_core.aleo/WalletSigningOpId; + hash.bhp256 r6 into r7 as field; + contains test_shield_swap_multisig_core.aleo/completed_signing_ops[r7] into r8; + assert.eq r8 true; + branch.eq true true to end_otherwise_0_3; + position end_then_0_2; + position end_otherwise_0_3; + diff --git a/shield-swap-sdk/tests/fixtures/programs/test_shield_swap_multisig_core.aleo b/shield-swap-sdk/tests/fixtures/programs/test_shield_swap_multisig_core.aleo new file mode 100644 index 00000000..34a2570b --- /dev/null +++ b/shield-swap-sdk/tests/fixtures/programs/test_shield_swap_multisig_core.aleo @@ -0,0 +1,827 @@ +// _source: aleo-viem@4a63636 packages/shield-swap/test/fixtures/programs/test_shield_swap_multisig_core.aleo +program test_shield_swap_multisig_core.aleo; + +struct AdminOp: + op as u8; + threshold as u8; + aleo_signer as address; + ecdsa_signer as [u8; 20u32]; + +struct WalletSigningOpId: + wallet_id as address; + signing_op_id as field; + +struct WalletSigningOpIdNonce: + wallet_id as address; + signing_op_id as field; + nonce as u64; + +struct WalletSigningOp: + confirmations as u8; + initiated_at_block as u32; + expires_at_block as u32; + round as u32; + +struct SigningOpConfirmation: + wallet_signing_op_id_hash as field; + wallet_signer_hash as field; + +struct ProgramSettings: + allow_upgrades as boolean; + upgrader_address as address; + guard_create_wallet as boolean; + +struct GuardedCreateWalletOp: + wallet_id as address; + threshold as u8; + aleo_signers as [address; 4u32]; + ecdsa_signers as [[u8; 20u32]; 4u32]; + +struct WalletAleoSigner: + wallet_id as address; + aleo_signer as address; + +struct WalletEcdsaSigner: + wallet_id as address; + ecdsa_signer as [u8; 20u32]; + +struct WalletSettings: + threshold as u8; + num_signers as u8; + +mapping program_settings_map: + key as boolean.public; + value as ProgramSettings.public; + +mapping signers_map: + key as field.public; + value as boolean.public; + +mapping wallets_map: + key as address.public; + value as WalletSettings.public; + +mapping pending_signing_ops: + key as field.public; + value as WalletSigningOp.public; + +mapping pending_signing_confirmations: + key as field.public; + value as u32.public; + +mapping completed_signing_ops: + key as field.public; + value as u32.public; + +mapping used_nonces: + key as field.public; + value as boolean.public; + +mapping pending_admin_ops: + key as field.public; + value as AdminOp.public; + +function init: + input r0 as address.private; + input r1 as boolean.private; + async init self.caller r0 r1 into r2; + output r2 as test_shield_swap_multisig_core.aleo/init.future; + +finalize init: + input r0 as address.public; + input r1 as address.public; + input r2 as boolean.public; + assert.eq r0 aleo1sa2gyw566v8k7ezjljs8hg4y6ja3vf0sm0kwzfvw5hvredjq3gys6wvfys; + contains program_settings_map[true] into r3; + not r3 into r4; + assert.eq r4 true; + cast true r1 r2 into r5 as ProgramSettings; + set r5 into program_settings_map[true]; + +function disallow_upgrades: + async disallow_upgrades self.caller into r0; + output r0 as test_shield_swap_multisig_core.aleo/disallow_upgrades.future; + +finalize disallow_upgrades: + input r0 as address.public; + contains program_settings_map[true] into r1; + assert.eq r1 true; + get program_settings_map[true] into r2; + assert.eq r0 r2.upgrader_address; + cast false r2.upgrader_address r2.guard_create_wallet into r3 as ProgramSettings; + set r3 into program_settings_map[true]; + +function set_upgrader_address: + input r0 as address.private; + async set_upgrader_address self.caller r0 into r1; + output r1 as test_shield_swap_multisig_core.aleo/set_upgrader_address.future; + +finalize set_upgrader_address: + input r0 as address.public; + input r1 as address.public; + contains program_settings_map[true] into r2; + assert.eq r2 true; + get program_settings_map[true] into r3; + assert.eq r0 r3.upgrader_address; + assert.eq r3.allow_upgrades true; + cast r3.allow_upgrades r1 r3.guard_create_wallet into r4 as ProgramSettings; + set r4 into program_settings_map[true]; + +function create_wallet: + input r0 as address.public; + input r1 as u8.public; + input r2 as [address; 4u32].private; + input r3 as [[u8; 20u32]; 4u32].private; + gt r1 0u8 into r4; + lte r1 8u8 into r5; + and r4 r5 into r6; + assert.eq r6 true; + cast r0 r2[0u32] into r7 as WalletAleoSigner; + hash.bhp256 r7 into r8 as field; + cast r0 r2[1u32] into r9 as WalletAleoSigner; + hash.bhp256 r9 into r10 as field; + cast r0 r2[2u32] into r11 as WalletAleoSigner; + hash.bhp256 r11 into r12 as field; + cast r0 r2[3u32] into r13 as WalletAleoSigner; + hash.bhp256 r13 into r14 as field; + cast r8 r10 r12 r14 into r15 as [field; 4u32]; + cast r0 r3[0u32] into r16 as WalletEcdsaSigner; + hash.bhp256 r16 into r17 as field; + cast r0 r3[1u32] into r18 as WalletEcdsaSigner; + hash.bhp256 r18 into r19 as field; + cast r0 r3[2u32] into r20 as WalletEcdsaSigner; + hash.bhp256 r20 into r21 as field; + cast r0 r3[3u32] into r22 as WalletEcdsaSigner; + hash.bhp256 r22 into r23 as field; + cast r17 r19 r21 r23 into r24 as [field; 4u32]; + async create_wallet r0 r1 r2 r3 self.caller r15 r24 into r25; + output r25 as test_shield_swap_multisig_core.aleo/create_wallet.future; + +finalize create_wallet: + input r0 as address.public; + input r1 as u8.public; + input r2 as [address; 4u32].public; + input r3 as [[u8; 20u32]; 4u32].public; + input r4 as address.public; + input r5 as [field; 4u32].public; + input r6 as [field; 4u32].public; + contains program_settings_map[true] into r7; + assert.eq r7 true; + get program_settings_map[true] into r8; + is.neq r0 test_shield_swap_multisig_core.aleo into r9; + and r8.guard_create_wallet r9 into r10; + branch.eq r10 false to end_then_0_0; + cast r0 r1 r2 r3 into r11 as GuardedCreateWalletOp; + hash.bhp256 r11 into r12 as field; + cast test_shield_swap_multisig_core.aleo r12 into r13 as WalletSigningOpId; + hash.bhp256 r13 into r14 as field; + contains completed_signing_ops[r14] into r15; + assert.eq r15 true; + branch.eq true true to end_otherwise_0_1; + position end_then_0_0; + is.eq r0 test_shield_swap_multisig_core.aleo into r16; + branch.eq r16 false to end_then_1_2; + assert.eq r4 aleo1sa2gyw566v8k7ezjljs8hg4y6ja3vf0sm0kwzfvw5hvredjq3gys6wvfys; + branch.eq true true to end_otherwise_1_3; + position end_then_1_2; + position end_otherwise_1_3; + position end_otherwise_0_1; + contains wallets_map[r0] into r17; + not r17 into r18; + assert.eq r18 true; + cast r0 aleo1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3ljyzc into r19 as WalletAleoSigner; + hash.bhp256 r19 into r20 as field; + cast 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 into r21 as [u8; 20u32]; + cast r0 r21 into r22 as WalletEcdsaSigner; + hash.bhp256 r22 into r23 as field; + is.neq r5[0u32] r20 into r24; + branch.eq r24 false to end_then_0_4; + contains signers_map[r5[0u32]] into r25; + not r25 into r26; + assert.eq r26 true; + set true into signers_map[r5[0u32]]; + branch.eq true true to end_otherwise_0_5; + position end_then_0_4; + position end_otherwise_0_5; + ternary r24 1u8 0u8 into r27; + is.neq r6[0u32] r23 into r28; + branch.eq r28 false to end_then_0_6; + contains signers_map[r6[0u32]] into r29; + not r29 into r30; + assert.eq r30 true; + set true into signers_map[r6[0u32]]; + branch.eq true true to end_otherwise_0_7; + position end_then_0_6; + position end_otherwise_0_7; + ternary r28 1u8 0u8 into r31; + add r27 r31 into r32; + is.neq r5[1u32] r20 into r33; + branch.eq r33 false to end_then_0_8; + contains signers_map[r5[1u32]] into r34; + not r34 into r35; + assert.eq r35 true; + set true into signers_map[r5[1u32]]; + branch.eq true true to end_otherwise_0_9; + position end_then_0_8; + position end_otherwise_0_9; + ternary r33 1u8 0u8 into r36; + add r32 r36 into r37; + is.neq r6[1u32] r23 into r38; + branch.eq r38 false to end_then_0_10; + contains signers_map[r6[1u32]] into r39; + not r39 into r40; + assert.eq r40 true; + set true into signers_map[r6[1u32]]; + branch.eq true true to end_otherwise_0_11; + position end_then_0_10; + position end_otherwise_0_11; + ternary r38 1u8 0u8 into r41; + add r37 r41 into r42; + is.neq r5[2u32] r20 into r43; + branch.eq r43 false to end_then_0_12; + contains signers_map[r5[2u32]] into r44; + not r44 into r45; + assert.eq r45 true; + set true into signers_map[r5[2u32]]; + branch.eq true true to end_otherwise_0_13; + position end_then_0_12; + position end_otherwise_0_13; + ternary r43 1u8 0u8 into r46; + add r42 r46 into r47; + is.neq r6[2u32] r23 into r48; + branch.eq r48 false to end_then_0_14; + contains signers_map[r6[2u32]] into r49; + not r49 into r50; + assert.eq r50 true; + set true into signers_map[r6[2u32]]; + branch.eq true true to end_otherwise_0_15; + position end_then_0_14; + position end_otherwise_0_15; + ternary r48 1u8 0u8 into r51; + add r47 r51 into r52; + is.neq r5[3u32] r20 into r53; + branch.eq r53 false to end_then_0_16; + contains signers_map[r5[3u32]] into r54; + not r54 into r55; + assert.eq r55 true; + set true into signers_map[r5[3u32]]; + branch.eq true true to end_otherwise_0_17; + position end_then_0_16; + position end_otherwise_0_17; + ternary r53 1u8 0u8 into r56; + add r52 r56 into r57; + is.neq r6[3u32] r23 into r58; + branch.eq r58 false to end_then_0_18; + contains signers_map[r6[3u32]] into r59; + not r59 into r60; + assert.eq r60 true; + set true into signers_map[r6[3u32]]; + branch.eq true true to end_otherwise_0_19; + position end_then_0_18; + position end_otherwise_0_19; + ternary r58 1u8 0u8 into r61; + add r57 r61 into r62; + gte r62 r1 into r63; + assert.eq r63 true; + cast r1 r62 into r64 as WalletSettings; + set r64 into wallets_map[r0]; + +function initiate_signing_op: + input r0 as address.public; + input r1 as field.public; + input r2 as u32.public; + gt r2 0u32 into r3; + assert.eq r3 true; + cast r0 r1 into r4 as WalletSigningOpId; + hash.bhp256 r4 into r5 as field; + cast r0 self.signer into r6 as WalletAleoSigner; + hash.bhp256 r6 into r7 as field; + async initiate_signing_op r0 r5 r7 r2 into r8; + output r5 as field.private; + output r8 as test_shield_swap_multisig_core.aleo/initiate_signing_op.future; + +finalize initiate_signing_op: + input r0 as address.public; + input r1 as field.public; + input r2 as field.public; + input r3 as u32.public; + cast 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 into r4 as [u8; 20u32]; + cast 0u8 0u8 aleo1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3ljyzc r4 into r5 as AdminOp; + contains wallets_map[r0] into r6; + assert.eq r6 true; + contains completed_signing_ops[r1] into r7; + not r7 into r8; + assert.eq r8 true; + contains pending_signing_ops[r1] into r9; + not r9 into r10; + branch.eq r10 false to end_then_0_0; + cast 0u8 0u32 0u32 0u32 into r11 as WalletSigningOp; + set r11 into pending_signing_ops[r1]; + branch.eq true true to end_otherwise_0_1; + position end_then_0_0; + position end_otherwise_0_1; + get pending_signing_ops[r1] into r12; + lt r12.expires_at_block block.height into r13; + assert.eq r13 true; + is.eq r3 4294967295u32 into r14; + ternary r14 0u32 r3 into r15; + add block.height r15 into r16; + ternary r14 4294967295u32 r16 into r17; + add r12.round 1u32 into r18; + contains signers_map[r2] into r19; + branch.eq r19 false to end_then_0_2; + cast 1u8 block.height r17 r18 into r20 as WalletSigningOp; + set r20 into pending_signing_ops[r1]; + cast r1 r2 into r21 as SigningOpConfirmation; + hash.bhp256 r21 into r22 as field; + get.or_use pending_signing_confirmations[r22] 0u32 into r23; + gt r18 r23 into r24; + assert.eq r24 true; + set r18 into pending_signing_confirmations[r22]; + get wallets_map[r0] into r25; + gte 1u8 r25.threshold into r26; + branch.eq r26 false to end_then_1_4; + set block.height into completed_signing_ops[r1]; + branch.eq true true to end_otherwise_1_5; + position end_then_1_4; + position end_otherwise_1_5; + branch.eq true true to end_otherwise_0_3; + position end_then_0_2; + cast 0u8 block.height r17 r18 into r27 as WalletSigningOp; + set r27 into pending_signing_ops[r1]; + position end_otherwise_0_3; + contains pending_admin_ops[r1] into r28; + branch.eq r28 false to end_then_0_6; + get pending_admin_ops[r1] into r29; + assert.eq r5 r29; + branch.eq true true to end_otherwise_0_7; + position end_then_0_6; + set r5 into pending_admin_ops[r1]; + position end_otherwise_0_7; + +function sign: + input r0 as address.public; + input r1 as field.public; + cast r0 self.signer into r2 as WalletAleoSigner; + hash.bhp256 r2 into r3 as field; + async sign r0 r1 r3 into r4; + output r4 as test_shield_swap_multisig_core.aleo/sign.future; + +finalize sign: + input r0 as address.public; + input r1 as field.public; + input r2 as field.public; + contains wallets_map[r0] into r3; + assert.eq r3 true; + contains signers_map[r2] into r4; + assert.eq r4 true; + cast r0 r1 into r5 as WalletSigningOpId; + hash.bhp256 r5 into r6 as field; + contains pending_signing_ops[r6] into r7; + assert.eq r7 true; + get pending_signing_ops[r6] into r8; + lt r8.expires_at_block block.height into r9; + not r9 into r10; + assert.eq r10 true; + cast r6 r2 into r11 as SigningOpConfirmation; + hash.bhp256 r11 into r12 as field; + get.or_use pending_signing_confirmations[r12] 0u32 into r13; + gt r8.round r13 into r14; + assert.eq r14 true; + set r8.round into pending_signing_confirmations[r12]; + add r8.confirmations 1u8 into r15; + cast r15 r8.initiated_at_block r8.expires_at_block r8.round into r16 as WalletSigningOp; + set r16 into pending_signing_ops[r6]; + get wallets_map[r0] into r17; + gte r15 r17.threshold into r18; + branch.eq r18 false to end_then_0_0; + set block.height into completed_signing_ops[r6]; + branch.eq true true to end_otherwise_0_1; + position end_then_0_0; + position end_otherwise_0_1; + +function sign_for_round: + input r0 as address.public; + input r1 as field.public; + input r2 as u32.public; + cast r0 self.signer into r3 as WalletAleoSigner; + hash.bhp256 r3 into r4 as field; + async sign_for_round r0 r1 r4 r2 into r5; + output r5 as test_shield_swap_multisig_core.aleo/sign_for_round.future; + +finalize sign_for_round: + input r0 as address.public; + input r1 as field.public; + input r2 as field.public; + input r3 as u32.public; + contains wallets_map[r0] into r4; + assert.eq r4 true; + contains signers_map[r2] into r5; + assert.eq r5 true; + cast r0 r1 into r6 as WalletSigningOpId; + hash.bhp256 r6 into r7 as field; + contains pending_signing_ops[r7] into r8; + assert.eq r8 true; + get pending_signing_ops[r7] into r9; + lt r9.expires_at_block block.height into r10; + not r10 into r11; + assert.eq r11 true; + is.eq r3 0u32 into r12; + is.eq r3 r9.round into r13; + or r12 r13 into r14; + assert.eq r14 true; + cast r7 r2 into r15 as SigningOpConfirmation; + hash.bhp256 r15 into r16 as field; + get.or_use pending_signing_confirmations[r16] 0u32 into r17; + gt r9.round r17 into r18; + assert.eq r18 true; + set r9.round into pending_signing_confirmations[r16]; + add r9.confirmations 1u8 into r19; + cast r19 r9.initiated_at_block r9.expires_at_block r9.round into r20 as WalletSigningOp; + set r20 into pending_signing_ops[r7]; + get wallets_map[r0] into r21; + gte r19 r21.threshold into r22; + branch.eq r22 false to end_then_0_0; + set block.height into completed_signing_ops[r7]; + branch.eq true true to end_otherwise_0_1; + position end_then_0_0; + position end_otherwise_0_1; + +function sign_ecdsa: + input r0 as address.public; + input r1 as field.public; + input r2 as [u8; 20u32].public; + input r3 as [u8; 65u32].public; + input r4 as u64.public; + cast r0 r2 into r5 as WalletEcdsaSigner; + async sign_ecdsa r0 r1 r5 r3 r4 into r6; + output r6 as test_shield_swap_multisig_core.aleo/sign_ecdsa.future; + +finalize sign_ecdsa: + input r0 as address.public; + input r1 as field.public; + input r2 as WalletEcdsaSigner.public; + input r3 as [u8; 65u32].public; + input r4 as u64.public; + contains wallets_map[r0] into r5; + assert.eq r5 true; + hash.bhp256 r2 into r6 as field; + contains signers_map[r6] into r7; + assert.eq r7 true; + cast r0 r1 r4 into r8 as WalletSigningOpIdNonce; + hash.bhp256 r8 into r9 as field; + contains used_nonces[r9] into r10; + not r10 into r11; + assert.eq r11 true; + set true into used_nonces[r9]; + cast r0 r1 into r12 as WalletSigningOpId; + hash.bhp256 r12 into r13 as field; + contains pending_signing_ops[r13] into r14; + assert.eq r14 true; + get pending_signing_ops[r13] into r15; + lt r15.expires_at_block block.height into r16; + not r16 into r17; + assert.eq r17 true; + serialize.bits.raw r9 (field) into r18 ([boolean; 253u32]); + cast false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false into r19 as [boolean; 256u32]; + cast r18[0u32] r18[1u32] r18[2u32] r18[3u32] r18[4u32] r18[5u32] r18[6u32] r18[7u32] r18[8u32] r18[9u32] r18[10u32] r18[11u32] r18[12u32] r18[13u32] r18[14u32] r18[15u32] r18[16u32] r18[17u32] r18[18u32] r18[19u32] r18[20u32] r18[21u32] r18[22u32] r18[23u32] r18[24u32] r18[25u32] r18[26u32] r18[27u32] r18[28u32] r18[29u32] r18[30u32] r18[31u32] r18[32u32] r18[33u32] r18[34u32] r18[35u32] r18[36u32] r18[37u32] r18[38u32] r18[39u32] r18[40u32] r18[41u32] r18[42u32] r18[43u32] r18[44u32] r18[45u32] r18[46u32] r18[47u32] r18[48u32] r18[49u32] r18[50u32] r18[51u32] r18[52u32] r18[53u32] r18[54u32] r18[55u32] r18[56u32] r18[57u32] r18[58u32] r18[59u32] r18[60u32] r18[61u32] r18[62u32] r18[63u32] r18[64u32] r18[65u32] r18[66u32] r18[67u32] r18[68u32] r18[69u32] r18[70u32] r18[71u32] r18[72u32] r18[73u32] r18[74u32] r18[75u32] r18[76u32] r18[77u32] r18[78u32] r18[79u32] r18[80u32] r18[81u32] r18[82u32] r18[83u32] r18[84u32] r18[85u32] r18[86u32] r18[87u32] r18[88u32] r18[89u32] r18[90u32] r18[91u32] r18[92u32] r18[93u32] r18[94u32] r18[95u32] r18[96u32] r18[97u32] r18[98u32] r18[99u32] r18[100u32] r18[101u32] r18[102u32] r18[103u32] r18[104u32] r18[105u32] r18[106u32] r18[107u32] r18[108u32] r18[109u32] r18[110u32] r18[111u32] r18[112u32] r18[113u32] r18[114u32] r18[115u32] r18[116u32] r18[117u32] r18[118u32] r18[119u32] r18[120u32] r18[121u32] r18[122u32] r18[123u32] r18[124u32] r18[125u32] r18[126u32] r18[127u32] r18[128u32] r18[129u32] r18[130u32] r18[131u32] r18[132u32] r18[133u32] r18[134u32] r18[135u32] r18[136u32] r18[137u32] r18[138u32] r18[139u32] r18[140u32] r18[141u32] r18[142u32] r18[143u32] r18[144u32] r18[145u32] r18[146u32] r18[147u32] r18[148u32] r18[149u32] r18[150u32] r18[151u32] r18[152u32] r18[153u32] r18[154u32] r18[155u32] r18[156u32] r18[157u32] r18[158u32] r18[159u32] r18[160u32] r18[161u32] r18[162u32] r18[163u32] r18[164u32] r18[165u32] r18[166u32] r18[167u32] r18[168u32] r18[169u32] r18[170u32] r18[171u32] r18[172u32] r18[173u32] r18[174u32] r18[175u32] r18[176u32] r18[177u32] r18[178u32] r18[179u32] r18[180u32] r18[181u32] r18[182u32] r18[183u32] r18[184u32] r18[185u32] r18[186u32] r18[187u32] r18[188u32] r18[189u32] r18[190u32] r18[191u32] r18[192u32] r18[193u32] r18[194u32] r18[195u32] r18[196u32] r18[197u32] r18[198u32] r18[199u32] r18[200u32] r18[201u32] r18[202u32] r18[203u32] r18[204u32] r18[205u32] r18[206u32] r18[207u32] r18[208u32] r18[209u32] r18[210u32] r18[211u32] r18[212u32] r18[213u32] r18[214u32] r18[215u32] r18[216u32] r18[217u32] r18[218u32] r18[219u32] r18[220u32] r18[221u32] r18[222u32] r18[223u32] r18[224u32] r18[225u32] r18[226u32] r18[227u32] r18[228u32] r18[229u32] r18[230u32] r18[231u32] r18[232u32] r18[233u32] r18[234u32] r18[235u32] r18[236u32] r18[237u32] r18[238u32] r18[239u32] r18[240u32] r18[241u32] r18[242u32] r18[243u32] r18[244u32] r18[245u32] r18[246u32] r18[247u32] r18[248u32] r18[249u32] r18[250u32] r18[251u32] r18[252u32] r19[253u32] r19[254u32] r19[255u32] into r20 as [boolean; 256u32]; + deserialize.bits.raw r20 ([boolean; 256u32]) into r21 ([u8; 32u32]); + cast 25u8 69u8 116u8 104u8 101u8 114u8 101u8 117u8 109u8 32u8 83u8 105u8 103u8 110u8 101u8 100u8 32u8 77u8 101u8 115u8 115u8 97u8 103u8 101u8 58u8 10u8 51u8 50u8 r21[0u32] r21[1u32] r21[2u32] r21[3u32] r21[4u32] r21[5u32] r21[6u32] r21[7u32] r21[8u32] r21[9u32] r21[10u32] r21[11u32] r21[12u32] r21[13u32] r21[14u32] r21[15u32] r21[16u32] r21[17u32] r21[18u32] r21[19u32] r21[20u32] r21[21u32] r21[22u32] r21[23u32] r21[24u32] r21[25u32] r21[26u32] r21[27u32] r21[28u32] r21[29u32] r21[30u32] r21[31u32] into r22 as [u8; 60u32]; + hash.keccak256.native.raw r22 into r23 as [boolean; 256u32]; + deserialize.bits.raw r23 ([boolean; 256u32]) into r24 ([u8; 32u32]); + ecdsa.verify.digest.eth r3 r2.ecdsa_signer r24 into r25; + assert.eq r25 true; + cast r13 r6 into r26 as SigningOpConfirmation; + hash.bhp256 r26 into r27 as field; + get.or_use pending_signing_confirmations[r27] 0u32 into r28; + gt r15.round r28 into r29; + assert.eq r29 true; + set r15.round into pending_signing_confirmations[r27]; + add r15.confirmations 1u8 into r30; + cast r30 r15.initiated_at_block r15.expires_at_block r15.round into r31 as WalletSigningOp; + set r31 into pending_signing_ops[r13]; + get wallets_map[r0] into r32; + gte r30 r32.threshold into r33; + branch.eq r33 false to end_then_0_0; + set block.height into completed_signing_ops[r13]; + branch.eq true true to end_otherwise_0_1; + position end_then_0_0; + position end_otherwise_0_1; + +function sign_ecdsa_for_round: + input r0 as address.public; + input r1 as field.public; + input r2 as [u8; 20u32].public; + input r3 as [u8; 65u32].public; + input r4 as u64.public; + input r5 as u32.public; + cast r0 r2 into r6 as WalletEcdsaSigner; + async sign_ecdsa_for_round r0 r1 r6 r3 r4 r5 into r7; + output r7 as test_shield_swap_multisig_core.aleo/sign_ecdsa_for_round.future; + +finalize sign_ecdsa_for_round: + input r0 as address.public; + input r1 as field.public; + input r2 as WalletEcdsaSigner.public; + input r3 as [u8; 65u32].public; + input r4 as u64.public; + input r5 as u32.public; + contains wallets_map[r0] into r6; + assert.eq r6 true; + hash.bhp256 r2 into r7 as field; + contains signers_map[r7] into r8; + assert.eq r8 true; + cast r0 r1 r4 into r9 as WalletSigningOpIdNonce; + hash.bhp256 r9 into r10 as field; + contains used_nonces[r10] into r11; + not r11 into r12; + assert.eq r12 true; + set true into used_nonces[r10]; + cast r0 r1 into r13 as WalletSigningOpId; + hash.bhp256 r13 into r14 as field; + contains pending_signing_ops[r14] into r15; + assert.eq r15 true; + get pending_signing_ops[r14] into r16; + lt r16.expires_at_block block.height into r17; + not r17 into r18; + assert.eq r18 true; + is.eq r5 0u32 into r19; + is.eq r5 r16.round into r20; + or r19 r20 into r21; + assert.eq r21 true; + serialize.bits.raw r10 (field) into r22 ([boolean; 253u32]); + cast false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false into r23 as [boolean; 256u32]; + cast r22[0u32] r22[1u32] r22[2u32] r22[3u32] r22[4u32] r22[5u32] r22[6u32] r22[7u32] r22[8u32] r22[9u32] r22[10u32] r22[11u32] r22[12u32] r22[13u32] r22[14u32] r22[15u32] r22[16u32] r22[17u32] r22[18u32] r22[19u32] r22[20u32] r22[21u32] r22[22u32] r22[23u32] r22[24u32] r22[25u32] r22[26u32] r22[27u32] r22[28u32] r22[29u32] r22[30u32] r22[31u32] r22[32u32] r22[33u32] r22[34u32] r22[35u32] r22[36u32] r22[37u32] r22[38u32] r22[39u32] r22[40u32] r22[41u32] r22[42u32] r22[43u32] r22[44u32] r22[45u32] r22[46u32] r22[47u32] r22[48u32] r22[49u32] r22[50u32] r22[51u32] r22[52u32] r22[53u32] r22[54u32] r22[55u32] r22[56u32] r22[57u32] r22[58u32] r22[59u32] r22[60u32] r22[61u32] r22[62u32] r22[63u32] r22[64u32] r22[65u32] r22[66u32] r22[67u32] r22[68u32] r22[69u32] r22[70u32] r22[71u32] r22[72u32] r22[73u32] r22[74u32] r22[75u32] r22[76u32] r22[77u32] r22[78u32] r22[79u32] r22[80u32] r22[81u32] r22[82u32] r22[83u32] r22[84u32] r22[85u32] r22[86u32] r22[87u32] r22[88u32] r22[89u32] r22[90u32] r22[91u32] r22[92u32] r22[93u32] r22[94u32] r22[95u32] r22[96u32] r22[97u32] r22[98u32] r22[99u32] r22[100u32] r22[101u32] r22[102u32] r22[103u32] r22[104u32] r22[105u32] r22[106u32] r22[107u32] r22[108u32] r22[109u32] r22[110u32] r22[111u32] r22[112u32] r22[113u32] r22[114u32] r22[115u32] r22[116u32] r22[117u32] r22[118u32] r22[119u32] r22[120u32] r22[121u32] r22[122u32] r22[123u32] r22[124u32] r22[125u32] r22[126u32] r22[127u32] r22[128u32] r22[129u32] r22[130u32] r22[131u32] r22[132u32] r22[133u32] r22[134u32] r22[135u32] r22[136u32] r22[137u32] r22[138u32] r22[139u32] r22[140u32] r22[141u32] r22[142u32] r22[143u32] r22[144u32] r22[145u32] r22[146u32] r22[147u32] r22[148u32] r22[149u32] r22[150u32] r22[151u32] r22[152u32] r22[153u32] r22[154u32] r22[155u32] r22[156u32] r22[157u32] r22[158u32] r22[159u32] r22[160u32] r22[161u32] r22[162u32] r22[163u32] r22[164u32] r22[165u32] r22[166u32] r22[167u32] r22[168u32] r22[169u32] r22[170u32] r22[171u32] r22[172u32] r22[173u32] r22[174u32] r22[175u32] r22[176u32] r22[177u32] r22[178u32] r22[179u32] r22[180u32] r22[181u32] r22[182u32] r22[183u32] r22[184u32] r22[185u32] r22[186u32] r22[187u32] r22[188u32] r22[189u32] r22[190u32] r22[191u32] r22[192u32] r22[193u32] r22[194u32] r22[195u32] r22[196u32] r22[197u32] r22[198u32] r22[199u32] r22[200u32] r22[201u32] r22[202u32] r22[203u32] r22[204u32] r22[205u32] r22[206u32] r22[207u32] r22[208u32] r22[209u32] r22[210u32] r22[211u32] r22[212u32] r22[213u32] r22[214u32] r22[215u32] r22[216u32] r22[217u32] r22[218u32] r22[219u32] r22[220u32] r22[221u32] r22[222u32] r22[223u32] r22[224u32] r22[225u32] r22[226u32] r22[227u32] r22[228u32] r22[229u32] r22[230u32] r22[231u32] r22[232u32] r22[233u32] r22[234u32] r22[235u32] r22[236u32] r22[237u32] r22[238u32] r22[239u32] r22[240u32] r22[241u32] r22[242u32] r22[243u32] r22[244u32] r22[245u32] r22[246u32] r22[247u32] r22[248u32] r22[249u32] r22[250u32] r22[251u32] r22[252u32] r23[253u32] r23[254u32] r23[255u32] into r24 as [boolean; 256u32]; + deserialize.bits.raw r24 ([boolean; 256u32]) into r25 ([u8; 32u32]); + cast 25u8 69u8 116u8 104u8 101u8 114u8 101u8 117u8 109u8 32u8 83u8 105u8 103u8 110u8 101u8 100u8 32u8 77u8 101u8 115u8 115u8 97u8 103u8 101u8 58u8 10u8 51u8 50u8 r25[0u32] r25[1u32] r25[2u32] r25[3u32] r25[4u32] r25[5u32] r25[6u32] r25[7u32] r25[8u32] r25[9u32] r25[10u32] r25[11u32] r25[12u32] r25[13u32] r25[14u32] r25[15u32] r25[16u32] r25[17u32] r25[18u32] r25[19u32] r25[20u32] r25[21u32] r25[22u32] r25[23u32] r25[24u32] r25[25u32] r25[26u32] r25[27u32] r25[28u32] r25[29u32] r25[30u32] r25[31u32] into r26 as [u8; 60u32]; + hash.keccak256.native.raw r26 into r27 as [boolean; 256u32]; + deserialize.bits.raw r27 ([boolean; 256u32]) into r28 ([u8; 32u32]); + ecdsa.verify.digest.eth r3 r2.ecdsa_signer r28 into r29; + assert.eq r29 true; + cast r14 r7 into r30 as SigningOpConfirmation; + hash.bhp256 r30 into r31 as field; + get.or_use pending_signing_confirmations[r31] 0u32 into r32; + gt r16.round r32 into r33; + assert.eq r33 true; + set r16.round into pending_signing_confirmations[r31]; + add r16.confirmations 1u8 into r34; + cast r34 r16.initiated_at_block r16.expires_at_block r16.round into r35 as WalletSigningOp; + set r35 into pending_signing_ops[r14]; + get wallets_map[r0] into r36; + gte r34 r36.threshold into r37; + branch.eq r37 false to end_then_0_0; + set block.height into completed_signing_ops[r14]; + branch.eq true true to end_otherwise_0_1; + position end_then_0_0; + position end_otherwise_0_1; + +closure assert_valid_admin_op: + input r0 as AdminOp; + is.eq r0.op 1u8 into r1; + not r1 into r2; + is.neq r0.threshold 0u8 into r3; + or r3 r2 into r4; + assert.eq r4 true; + is.eq r0.aleo_signer aleo1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3ljyzc into r5; + or r5 r2 into r6; + assert.eq r6 true; + cast 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 into r7 as [u8; 20u32]; + is.eq r0.ecdsa_signer r7 into r8; + or r8 r2 into r9; + assert.eq r9 true; + is.eq r0.op 2u8 into r10; + is.eq r0.op 3u8 into r11; + or r10 r11 into r12; + and r2 r12 into r13; + not r13 into r14; + is.eq r0.threshold 0u8 into r15; + or r15 r14 into r16; + assert.eq r16 true; + is.eq r0.aleo_signer aleo1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3ljyzc into r17; + is.eq r0.ecdsa_signer r7 into r18; + and r17 r18 into r19; + and r13 r19 into r20; + not r20 into r21; + assert.eq r21 true; + not r19 into r22; + is.neq r0.aleo_signer aleo1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3ljyzc into r23; + is.neq r0.ecdsa_signer r7 into r24; + and r23 r24 into r25; + and r13 r22 into r26; + and r26 r25 into r27; + not r27 into r28; + assert.eq r28 true; + not r12 into r29; + and r2 r29 into r30; + not r30 into r31; + assert.eq r31 true; + +function init_admin_op: + input r0 as address.public; + input r1 as field.public; + input r2 as u32.public; + input r3 as AdminOp.private; + call assert_valid_admin_op r3; + cast r0 r1 into r4 as WalletSigningOpId; + hash.bhp256 r4 into r5 as field; + cast r0 self.signer into r6 as WalletAleoSigner; + hash.bhp256 r6 into r7 as field; + async init_admin_op r0 r5 r7 r2 r3 into r8; + output r5 as field.private; + output r8 as test_shield_swap_multisig_core.aleo/init_admin_op.future; + +finalize init_admin_op: + input r0 as address.public; + input r1 as field.public; + input r2 as field.public; + input r3 as u32.public; + input r4 as AdminOp.public; + contains wallets_map[r0] into r5; + assert.eq r5 true; + contains completed_signing_ops[r1] into r6; + not r6 into r7; + assert.eq r7 true; + contains pending_signing_ops[r1] into r8; + not r8 into r9; + branch.eq r9 false to end_then_0_0; + cast 0u8 0u32 0u32 0u32 into r10 as WalletSigningOp; + set r10 into pending_signing_ops[r1]; + branch.eq true true to end_otherwise_0_1; + position end_then_0_0; + position end_otherwise_0_1; + get pending_signing_ops[r1] into r11; + lt r11.expires_at_block block.height into r12; + assert.eq r12 true; + is.eq r3 4294967295u32 into r13; + ternary r13 0u32 r3 into r14; + add block.height r14 into r15; + ternary r13 4294967295u32 r15 into r16; + add r11.round 1u32 into r17; + contains signers_map[r2] into r18; + branch.eq r18 false to end_then_0_2; + cast 1u8 block.height r16 r17 into r19 as WalletSigningOp; + set r19 into pending_signing_ops[r1]; + cast r1 r2 into r20 as SigningOpConfirmation; + hash.bhp256 r20 into r21 as field; + get.or_use pending_signing_confirmations[r21] 0u32 into r22; + gt r17 r22 into r23; + assert.eq r23 true; + set r17 into pending_signing_confirmations[r21]; + get wallets_map[r0] into r24; + gte 1u8 r24.threshold into r25; + branch.eq r25 false to end_then_1_4; + set block.height into completed_signing_ops[r1]; + branch.eq true true to end_otherwise_1_5; + position end_then_1_4; + position end_otherwise_1_5; + branch.eq true true to end_otherwise_0_3; + position end_then_0_2; + cast 0u8 block.height r16 r17 into r26 as WalletSigningOp; + set r26 into pending_signing_ops[r1]; + position end_otherwise_0_3; + contains pending_admin_ops[r1] into r27; + branch.eq r27 false to end_then_0_6; + get pending_admin_ops[r1] into r28; + assert.eq r4 r28; + branch.eq true true to end_otherwise_0_7; + position end_then_0_6; + set r4 into pending_admin_ops[r1]; + position end_otherwise_0_7; + +function exec_admin_op: + input r0 as address.public; + input r1 as field.public; + input r2 as AdminOp.private; + call assert_valid_admin_op r2; + cast r0 r1 into r3 as WalletSigningOpId; + hash.bhp256 r3 into r4 as field; + async exec_admin_op r0 r4 r2 into r5; + output r5 as test_shield_swap_multisig_core.aleo/exec_admin_op.future; + +finalize exec_admin_op: + input r0 as address.public; + input r1 as field.public; + input r2 as AdminOp.public; + contains wallets_map[r0] into r3; + assert.eq r3 true; + contains completed_signing_ops[r1] into r4; + assert.eq r4 true; + get pending_admin_ops[r1] into r5; + assert.eq r5 r2; + remove pending_admin_ops[r1]; + get wallets_map[r0] into r6; + is.eq r2.op 1u8 into r7; + branch.eq r7 false to end_then_0_0; + lte r2.threshold r6.num_signers into r8; + assert.eq r8 true; + cast r2.threshold r6.num_signers into r9 as WalletSettings; + set r9 into wallets_map[r0]; + branch.eq true true to end_otherwise_0_1; + position end_then_0_0; + is.eq r2.op 2u8 into r10; + branch.eq r10 false to end_then_1_2; + is.eq r2.op 2u8 into r11; + is.eq r2.op 3u8 into r12; + or r11 r12 into r13; + assert.eq r13 true; + is.neq r2.aleo_signer aleo1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3ljyzc into r14; + cast r0 r2.aleo_signer into r15 as WalletAleoSigner; + hash.bhp256 r15 into r16 as field; + ternary r14 r16 0field into r17; + cast 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 into r18 as [u8; 20u32]; + is.neq r2.ecdsa_signer r18 into r19; + not r19 into r20; + is.eq r17 0field into r21; + or r21 r20 into r22; + assert.eq r22 true; + cast r0 r2.ecdsa_signer into r23 as WalletEcdsaSigner; + hash.bhp256 r23 into r24 as field; + ternary r19 r24 r17 into r25; + assert.neq r25 0field; + contains signers_map[r25] into r26; + not r26 into r27; + assert.eq r27 true; + set true into signers_map[r25]; + add r6.num_signers 1u8 into r28; + cast r6.threshold r28 into r29 as WalletSettings; + set r29 into wallets_map[r0]; + branch.eq true true to end_otherwise_1_3; + position end_then_1_2; + is.eq r2.op 3u8 into r30; + branch.eq r30 false to end_then_2_4; + is.eq r2.op 2u8 into r31; + is.eq r2.op 3u8 into r32; + or r31 r32 into r33; + assert.eq r33 true; + is.neq r2.aleo_signer aleo1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3ljyzc into r34; + cast r0 r2.aleo_signer into r35 as WalletAleoSigner; + hash.bhp256 r35 into r36 as field; + ternary r34 r36 0field into r37; + cast 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 into r38 as [u8; 20u32]; + is.neq r2.ecdsa_signer r38 into r39; + not r39 into r40; + is.eq r37 0field into r41; + or r41 r40 into r42; + assert.eq r42 true; + cast r0 r2.ecdsa_signer into r43 as WalletEcdsaSigner; + hash.bhp256 r43 into r44 as field; + ternary r39 r44 r37 into r45; + assert.neq r45 0field; + contains signers_map[r45] into r46; + assert.eq r46 true; + remove signers_map[r45]; + sub r6.num_signers 1u8 into r47; + gte r47 r6.threshold into r48; + assert.eq r48 true; + sub r6.num_signers 1u8 into r49; + cast r6.threshold r49 into r50 as WalletSettings; + set r50 into wallets_map[r0]; + branch.eq true true to end_otherwise_2_5; + position end_then_2_4; + assert.eq false true; + position end_otherwise_2_5; + position end_otherwise_1_3; + position end_otherwise_0_1; + +function get_signing_op_id_hash: + input r0 as address.public; + input r1 as field.public; + cast r0 r1 into r2 as WalletSigningOpId; + hash.bhp256 r2 into r3 as field; + output r3 as field.private; + +function guarded_create_wallet_op_hash: + input r0 as address.public; + input r1 as u8.public; + input r2 as [address; 4u32].private; + input r3 as [[u8; 20u32]; 4u32].private; + cast r0 r1 r2 r3 into r4 as GuardedCreateWalletOp; + hash.bhp256 r4 into r5 as field; + output r5 as field.private; + +function assert_signing_completed: + input r0 as address.public; + input r1 as field.public; + async assert_signing_completed r0 r1 into r2; + output r2 as test_shield_swap_multisig_core.aleo/assert_signing_completed.future; + +finalize assert_signing_completed: + input r0 as address.public; + input r1 as field.public; + cast r0 r1 into r2 as WalletSigningOpId; + hash.bhp256 r2 into r3 as field; + contains completed_signing_ops[r3] into r4; + assert.eq r4 true; + +constructor: + gt edition 0u16 into r0; + branch.eq r0 false to end_then_0_0; + contains program_settings_map[true] into r1; + assert.eq r1 true; + get program_settings_map[true] into r2; + assert.eq r2.allow_upgrades true; + assert.eq program_owner r2.upgrader_address; + branch.eq true true to end_otherwise_0_1; + position end_then_0_0; + position end_otherwise_0_1; + diff --git a/shield-swap-sdk/tests/fixtures/programs/test_token_a.aleo b/shield-swap-sdk/tests/fixtures/programs/test_token_a.aleo new file mode 100644 index 00000000..c33b3027 --- /dev/null +++ b/shield-swap-sdk/tests/fixtures/programs/test_token_a.aleo @@ -0,0 +1,193 @@ +// _source: compiled with leo 4.3.2 from aleo-viem@4a63636 packages/shield-swap/test/fixtures/programs/test_token_a.leo +program test_token_a.aleo; + +record Token: + owner as address.private; + amount as u128.private; + +struct TokenAllowance: + account as address; + spender as address; + +mapping balances: + key as address.public; + value as u128.public; + +mapping allowances: + key as TokenAllowance.public; + value as u128.public; + +function decimals: + output 6u8 as u8.private; + +function mint_public: + input r0 as address.public; + input r1 as u128.public; + assert.eq self.signer aleo1rhgdu77hgyqd3xjj8ucu3jj9r2krwz6mnzyd80gncr5fxcwlh5rsvzp9px; + async mint_public r0 r1 into r2; + output r2 as test_token_a.aleo/mint_public.future; + +finalize mint_public: + input r0 as address.public; + input r1 as u128.public; + get.or_use balances[r0] 0u128 into r2; + add r2 r1 into r3; + set r3 into balances[r0]; + +function transfer_public: + input r0 as address.public; + input r1 as u128.public; + async transfer_public self.caller r1 r0 into r2; + output r2 as test_token_a.aleo/transfer_public.future; + +finalize transfer_public: + input r0 as address.public; + input r1 as u128.public; + input r2 as address.public; + get balances[r0] into r3; + sub r3 r1 into r4; + set r4 into balances[r0]; + get.or_use balances[r2] 0u128 into r5; + add r5 r1 into r6; + set r6 into balances[r2]; + +function transfer_public_as_signer: + input r0 as address.public; + input r1 as u128.public; + async transfer_public_as_signer self.signer r1 r0 into r2; + output r2 as test_token_a.aleo/transfer_public_as_signer.future; + +finalize transfer_public_as_signer: + input r0 as address.public; + input r1 as u128.public; + input r2 as address.public; + get balances[r0] into r3; + sub r3 r1 into r4; + set r4 into balances[r0]; + get.or_use balances[r2] 0u128 into r5; + add r5 r1 into r6; + set r6 into balances[r2]; + +function transfer_private: + input r0 as Token.record; + input r1 as address.private; + input r2 as u128.private; + is.eq r0.owner self.signer into r3; + assert.eq r3 true; + sub r0.amount r2 into r4; + cast r0.owner r4 into r5 as Token.record; + cast r1 r2 into r6 as Token.record; + output r5 as Token.record; + output r6 as Token.record; + +function transfer_private_to_public: + input r0 as Token.record; + input r1 as address.public; + input r2 as u128.public; + is.eq r0.owner self.signer into r3; + assert.eq r3 true; + sub r0.amount r2 into r4; + cast r0.owner r4 into r5 as Token.record; + async transfer_private_to_public r1 r2 into r6; + output r5 as Token.record; + output r6 as test_token_a.aleo/transfer_private_to_public.future; + +finalize transfer_private_to_public: + input r0 as address.public; + input r1 as u128.public; + get.or_use balances[r0] 0u128 into r2; + add r2 r1 into r3; + set r3 into balances[r0]; + +function transfer_public_to_private: + input r0 as address.private; + input r1 as u128.public; + cast r0 r1 into r2 as Token.record; + async transfer_public_to_private self.caller r1 into r3; + output r2 as Token.record; + output r3 as test_token_a.aleo/transfer_public_to_private.future; + +finalize transfer_public_to_private: + input r0 as address.public; + input r1 as u128.public; + get balances[r0] into r2; + sub r2 r1 into r3; + set r3 into balances[r0]; + +function approve_public: + input r0 as address.public; + input r1 as u128.public; + cast self.caller r0 into r2 as TokenAllowance; + async approve_public r2 r1 into r3; + output r3 as test_token_a.aleo/approve_public.future; + +finalize approve_public: + input r0 as TokenAllowance.public; + input r1 as u128.public; + get.or_use allowances[r0] 0u128 into r2; + add r2 r1 into r3; + set r3 into allowances[r0]; + +function unapprove_public: + input r0 as address.public; + input r1 as u128.public; + cast self.caller r0 into r2 as TokenAllowance; + async unapprove_public r2 r1 into r3; + output r3 as test_token_a.aleo/unapprove_public.future; + +finalize unapprove_public: + input r0 as TokenAllowance.public; + input r1 as u128.public; + get allowances[r0] into r2; + sub r2 r1 into r3; + set r3 into allowances[r0]; + +function transfer_from_public: + input r0 as address.public; + input r1 as address.public; + input r2 as u128.public; + cast r0 self.caller into r3 as TokenAllowance; + async transfer_from_public r3 r2 r0 r1 into r4; + output r4 as test_token_a.aleo/transfer_from_public.future; + +finalize transfer_from_public: + input r0 as TokenAllowance.public; + input r1 as u128.public; + input r2 as address.public; + input r3 as address.public; + get allowances[r0] into r4; + gte r4 r1 into r5; + assert.eq r5 true; + sub r4 r1 into r6; + set r6 into allowances[r0]; + get balances[r2] into r7; + sub r7 r1 into r8; + set r8 into balances[r2]; + get.or_use balances[r3] 0u128 into r9; + add r9 r1 into r10; + set r10 into balances[r3]; + +function transfer_from_public_to_private: + input r0 as address.public; + input r1 as u128.public; + cast r0 self.caller into r2 as TokenAllowance; + cast self.caller r1 into r3 as Token.record; + async transfer_from_public_to_private r2 r1 r0 into r4; + output r3 as Token.record; + output r4 as test_token_a.aleo/transfer_from_public_to_private.future; + +finalize transfer_from_public_to_private: + input r0 as TokenAllowance.public; + input r1 as u128.public; + input r2 as address.public; + get allowances[r0] into r3; + gte r3 r1 into r4; + assert.eq r4 true; + sub r3 r1 into r5; + set r5 into allowances[r0]; + get balances[r2] into r6; + sub r6 r1 into r7; + set r7 into balances[r2]; + +constructor: + assert.eq edition 0u16; diff --git a/shield-swap-sdk/tests/fixtures/programs/test_token_b.aleo b/shield-swap-sdk/tests/fixtures/programs/test_token_b.aleo new file mode 100644 index 00000000..c78a2a5a --- /dev/null +++ b/shield-swap-sdk/tests/fixtures/programs/test_token_b.aleo @@ -0,0 +1,193 @@ +// _source: compiled with leo 4.3.2 from aleo-viem@4a63636 packages/shield-swap/test/fixtures/programs/test_token_b.leo +program test_token_b.aleo; + +record Token: + owner as address.private; + amount as u128.private; + +struct TokenAllowance: + account as address; + spender as address; + +mapping balances: + key as address.public; + value as u128.public; + +mapping allowances: + key as TokenAllowance.public; + value as u128.public; + +function decimals: + output 6u8 as u8.private; + +function mint_public: + input r0 as address.public; + input r1 as u128.public; + assert.eq self.signer aleo1rhgdu77hgyqd3xjj8ucu3jj9r2krwz6mnzyd80gncr5fxcwlh5rsvzp9px; + async mint_public r0 r1 into r2; + output r2 as test_token_b.aleo/mint_public.future; + +finalize mint_public: + input r0 as address.public; + input r1 as u128.public; + get.or_use balances[r0] 0u128 into r2; + add r2 r1 into r3; + set r3 into balances[r0]; + +function transfer_public: + input r0 as address.public; + input r1 as u128.public; + async transfer_public self.caller r1 r0 into r2; + output r2 as test_token_b.aleo/transfer_public.future; + +finalize transfer_public: + input r0 as address.public; + input r1 as u128.public; + input r2 as address.public; + get balances[r0] into r3; + sub r3 r1 into r4; + set r4 into balances[r0]; + get.or_use balances[r2] 0u128 into r5; + add r5 r1 into r6; + set r6 into balances[r2]; + +function transfer_public_as_signer: + input r0 as address.public; + input r1 as u128.public; + async transfer_public_as_signer self.signer r1 r0 into r2; + output r2 as test_token_b.aleo/transfer_public_as_signer.future; + +finalize transfer_public_as_signer: + input r0 as address.public; + input r1 as u128.public; + input r2 as address.public; + get balances[r0] into r3; + sub r3 r1 into r4; + set r4 into balances[r0]; + get.or_use balances[r2] 0u128 into r5; + add r5 r1 into r6; + set r6 into balances[r2]; + +function transfer_private: + input r0 as Token.record; + input r1 as address.private; + input r2 as u128.private; + is.eq r0.owner self.signer into r3; + assert.eq r3 true; + sub r0.amount r2 into r4; + cast r0.owner r4 into r5 as Token.record; + cast r1 r2 into r6 as Token.record; + output r5 as Token.record; + output r6 as Token.record; + +function transfer_private_to_public: + input r0 as Token.record; + input r1 as address.public; + input r2 as u128.public; + is.eq r0.owner self.signer into r3; + assert.eq r3 true; + sub r0.amount r2 into r4; + cast r0.owner r4 into r5 as Token.record; + async transfer_private_to_public r1 r2 into r6; + output r5 as Token.record; + output r6 as test_token_b.aleo/transfer_private_to_public.future; + +finalize transfer_private_to_public: + input r0 as address.public; + input r1 as u128.public; + get.or_use balances[r0] 0u128 into r2; + add r2 r1 into r3; + set r3 into balances[r0]; + +function transfer_public_to_private: + input r0 as address.private; + input r1 as u128.public; + cast r0 r1 into r2 as Token.record; + async transfer_public_to_private self.caller r1 into r3; + output r2 as Token.record; + output r3 as test_token_b.aleo/transfer_public_to_private.future; + +finalize transfer_public_to_private: + input r0 as address.public; + input r1 as u128.public; + get balances[r0] into r2; + sub r2 r1 into r3; + set r3 into balances[r0]; + +function approve_public: + input r0 as address.public; + input r1 as u128.public; + cast self.caller r0 into r2 as TokenAllowance; + async approve_public r2 r1 into r3; + output r3 as test_token_b.aleo/approve_public.future; + +finalize approve_public: + input r0 as TokenAllowance.public; + input r1 as u128.public; + get.or_use allowances[r0] 0u128 into r2; + add r2 r1 into r3; + set r3 into allowances[r0]; + +function unapprove_public: + input r0 as address.public; + input r1 as u128.public; + cast self.caller r0 into r2 as TokenAllowance; + async unapprove_public r2 r1 into r3; + output r3 as test_token_b.aleo/unapprove_public.future; + +finalize unapprove_public: + input r0 as TokenAllowance.public; + input r1 as u128.public; + get allowances[r0] into r2; + sub r2 r1 into r3; + set r3 into allowances[r0]; + +function transfer_from_public: + input r0 as address.public; + input r1 as address.public; + input r2 as u128.public; + cast r0 self.caller into r3 as TokenAllowance; + async transfer_from_public r3 r2 r0 r1 into r4; + output r4 as test_token_b.aleo/transfer_from_public.future; + +finalize transfer_from_public: + input r0 as TokenAllowance.public; + input r1 as u128.public; + input r2 as address.public; + input r3 as address.public; + get allowances[r0] into r4; + gte r4 r1 into r5; + assert.eq r5 true; + sub r4 r1 into r6; + set r6 into allowances[r0]; + get balances[r2] into r7; + sub r7 r1 into r8; + set r8 into balances[r2]; + get.or_use balances[r3] 0u128 into r9; + add r9 r1 into r10; + set r10 into balances[r3]; + +function transfer_from_public_to_private: + input r0 as address.public; + input r1 as u128.public; + cast r0 self.caller into r2 as TokenAllowance; + cast self.caller r1 into r3 as Token.record; + async transfer_from_public_to_private r2 r1 r0 into r4; + output r3 as Token.record; + output r4 as test_token_b.aleo/transfer_from_public_to_private.future; + +finalize transfer_from_public_to_private: + input r0 as TokenAllowance.public; + input r1 as u128.public; + input r2 as address.public; + get allowances[r0] into r3; + gte r3 r1 into r4; + assert.eq r4 true; + sub r3 r1 into r5; + set r5 into allowances[r0]; + get balances[r2] into r6; + sub r6 r1 into r7; + set r7 into balances[r2]; + +constructor: + assert.eq edition 0u16; diff --git a/shield-swap-sdk/tests/integration/__init__.py b/shield-swap-sdk/tests/integration/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/shield-swap-sdk/tests/integration/conftest.py b/shield-swap-sdk/tests/integration/conftest.py new file mode 100644 index 00000000..74b9d9fe --- /dev/null +++ b/shield-swap-sdk/tests/integration/conftest.py @@ -0,0 +1,61 @@ +"""Live tiers, matching the main SDK's convention (test_live_e2e.py): +every module here sets ``pytestmark = pytest.mark.live`` — excluded from the +default run (pytest.ini addopts); opt in with ``-m live``. The write tier +additionally skips without funded credentials.""" +from __future__ import annotations + +import os + +import pytest + +ENDPOINT = os.environ.get("ALEO_E2E_ENDPOINT", "https://api.provable.com") # origin, no /v2 +WRITE = all(os.environ.get(k) for k in + ("ALEO_E2E_PRIVATE_KEY", "ALEO_E2E_API_KEY", "ALEO_E2E_CONSUMER_ID")) + +write_tier = pytest.mark.skipif(not WRITE, reason="write-tier env vars not set") + + +def _make_live_dex(): + from aleo import Aleo, HTTPProvider + + from aleo_shield_swap import ShieldSwap + + aleo = Aleo(HTTPProvider(ENDPOINT, network="testnet")) + dex = ShieldSwap(aleo) + # Some API endpoints are auth-gated (signature challenge/verify) and + # additionally invite-gated per account. Prefer the e2e account (it has + # access when provisioned); fall back to a throwaway signature so the + # JWT layer is still exercised. Gated tests skip on 401/403. + pk = os.environ.get("ALEO_E2E_PRIVATE_KEY") + acct = aleo.account.from_private_key(pk) if pk else aleo.account.create() + try: + dex.api.authenticate( + str(acct.address), + lambda msg: str(aleo.account.sign(msg.encode(), acct)), + ) + except Exception: + pass # auth endpoint down — gated tests will skip + return dex + + +def skip_if_access_gated(call): + """Run *call*; skip the test when the API says the account lacks access.""" + from aleo_shield_swap.errors import DexApiError + + try: + return call() + except DexApiError as exc: + if exc.status in (401, 403): + pytest.skip(f"DEX API access-gated for this account: {exc.body[:80]}") + raise + + +@pytest.fixture +def live_dex(): + return _make_live_dex() + + +@pytest.fixture(scope="module") +def live_dex_module(): + """Module-scoped live client — read tests share pools/token fetches.""" + return _make_live_dex() diff --git a/shield-swap-sdk/tests/integration/devnode_amm.py b/shield-swap-sdk/tests/integration/devnode_amm.py new file mode 100644 index 00000000..d9917709 --- /dev/null +++ b/shield-swap-sdk/tests/integration/devnode_amm.py @@ -0,0 +1,276 @@ +"""Devnode AMM fixture: the full shield_swap stack on a local devnode. + +Python port of the TS suite's ``devnodeAmm.ts``: boots ``aleo-devnode``, +advances past the last TEST consensus-version height (the devnode's snarkVM +uses the test schedule — V17 from height 20), deploys the vendored AMM + +multisig import and two locally-compiled ARC-20 test tokens, runs the admin +configuration, and funds a non-admin user. Fully hermetic — no live network. + +Two execution ladders (see the suite docstring): + +* **proven** (default): every execution transaction is fully proven locally + via the facade's ``transact`` — slow (SNARK params + key synthesis) but + exercises exactly what a real network requires. +* **unproven** (``ALEO_DEVNODE_UNPROVEN=1``): executions are built without + proofs (the devnode skips proof verification) via the SDK's + ``Execution.from_authorization_unproven`` — fast, devnode-only. + +Deployment transactions are always proofless (both ladders): dummy verifying +keys/certificates via ``Deployment.from_program_unproven`` plus an unproven +fee — mirroring the wasm SDK's ``buildDevnodeDeploymentTransaction``. Real +key synthesis for the AMM takes ~14 minutes and buys nothing on a devnode, +which skips certificate verification anyway. +""" +from __future__ import annotations + +import os +import re +import time +from dataclasses import dataclass +from pathlib import Path +from typing import Any, Optional + +from aleo_shield_swap._core import ensure_programs + +FIXTURES = Path(__file__).parents[1] / "fixtures" / "programs" + +AMM_PROGRAM = "shield_swap_v3.aleo" +MULTISIG_PROGRAM = "test_shield_swap_multisig_core.aleo" +TOKEN_A = "test_token_a.aleo" +TOKEN_B = "test_token_b.aleo" + +# One million tokens at 6 decimals — the per-user provisioning amount. +TOKEN_SUPPLY = 1_000_000_000_000 + +# The devnode's snarkVM uses TEST consensus heights: the last version +# activates at height 20. Advance past it so records and costs are built +# and validated at the same (latest) version on both sides. +LAST_TEST_CONSENSUS_HEIGHT = 20 + +UNPROVEN = os.environ.get("ALEO_DEVNODE_UNPROVEN") == "1" + + +def identifier_to_field(identifier: str) -> str: + """Encodes a program identifier (no ``.aleo``) the way the AMM keys + tokens: little-endian bytes as a field literal.""" + value = 0 + for byte in reversed(identifier.encode()): + value = (value << 8) | byte + return f"{value}field" + + +def read_fixture(file_name: str) -> str: + return (FIXTURES / file_name).read_text() + + +def patch_admin_address(source: str, admin_address: str) -> str: + """Rewrites the baked deployer/admin address in the AMM source to + *admin_address* — the constructor promotes that literal to the ``admin`` + mapping at edition 0.""" + constructor = source[source.index("constructor:"):] + baked = re.search(r"aleo1[a-z0-9]{58}", constructor) + if not baked: + raise RuntimeError("No admin address literal found in the AMM constructor") + return source.replace(baked.group(0), admin_address) + + +@dataclass +class AmmDevnode: + """The running fixture: node, facade client, actors, and helpers.""" + + devnode: Any + aleo: Any + admin: Any # facade Account (genesis 0 — token mint admin) + user: Any # facade Account (non-admin, funded) + imports: dict[str, str] # program id -> source (dynamic dispatch) + token0_field: str + token1_field: str + token0_program: str + token1_program: str + + # ── Chain plumbing ─────────────────────────────────────────────────────── + + def _net(self) -> Any: + from aleo import testnet + return testnet + + def state_root(self) -> str: + return str(self.aleo.network.get_state_root()) + + def submit_and_confirm(self, tx: Any, label: str) -> str: + """Broadcast a built transaction, mine it, and require acceptance.""" + tx_id = self.aleo.network.submit_transaction(tx) + self.devnode.advance(1) + confirmed = self.aleo.network.get_confirmed_transaction(str(tx_id)) + status = str(confirmed) + if '"accepted"' not in status and "'accepted'" not in status: + raise RuntimeError( + f"{label}: transaction {tx_id} was not accepted: {status[:400]}\n" + f"devnode logs:\n" + "\n".join(self.devnode.logs()[-15:]) + ) + return str(tx_id) + + def wait_queryable(self, program_id: str) -> None: + """Wait until the devnode serves a deployed program's source.""" + for _ in range(20): + try: + src = self.aleo.network.get_program(program_id) + if f"program {program_id}" in str(src): + return + except Exception: + pass + self.devnode.advance(1) + time.sleep(0.3) + raise RuntimeError(f"{program_id} never became queryable on the devnode") + + # ── Deployment (unproven fee — devnode only) ───────────────────────────── + + def deploy_program(self, source: str, label: str) -> str: + """Deploy *source* proofless: dummy verifying keys (no synthesis) and + an unproven public fee paid by the admin — devnode-only.""" + net = self._net() + process = self.aleo.process + program = net.Program.from_source(source) + + deployment = net.Deployment.from_program_unproven(program, self.admin.address) + cost = process.deployment_cost(deployment) + fee_auth = process.authorize_fee_public( + self.admin.private_key, cost, 0, deployment.deployment_id()) + fee = net.Fee.from_authorization_unproven(fee_auth, self.state_root()) + tx = net.Transaction.from_deployment(self.admin.private_key, deployment, fee) + tx_id = self.submit_and_confirm(tx, f"deploy {label}") + self.wait_queryable(label) + # Later deployments/executions resolve this program from the process. + process.add_program(program) + return tx_id + + # ── Execution (ladder: proven via facade, or unproven) ────────────────── + + def execute(self, account: Any, program_id: str, function: str, + inputs: list[Any], label: str) -> str: + """Run one program function as *account* and require acceptance. + + Proven ladder: the facade's ``build_transaction`` (full local proof). + Unproven ladder: authorization + proofless execution/fee. + """ + ensure_programs(self.aleo, [program_id], self.imports) + bound = self.aleo.programs.get(program_id).functions[function](*inputs) + + if not UNPROVEN: + result = bound.build_transaction(account) + return self.submit_and_confirm(result.raw, label) + + net = self._net() + process = self.aleo.process + auth = bound.authorize(account).raw + root = self.state_root() + execution = net.Execution.from_authorization_unproven(auth, root) + cost, _ = process.execution_cost(execution) + fee_auth = process.authorize_fee_public( + account.private_key, cost, 0, execution.execution_id) + fee = net.Fee.from_authorization_unproven(fee_auth, root) + tx = net.Transaction.from_execution(execution, fee) + return self.submit_and_confirm(tx, label) + + # ── Records ────────────────────────────────────────────────────────────── + + def records_of(self, account: Any, tx_id: str) -> list[str]: + """Record plaintexts of a confirmed transaction owned by *account*.""" + tx = self.aleo.network.get_transaction_object(tx_id) + return [str(r) for r in tx.owned_records(account.view_key)] + + def privatize_token(self, account: Any, token_program: str, amount: int) -> str: + """``transfer_public_to_private`` and return the new Token record.""" + tx_id = self.execute( + account, token_program, "transfer_public_to_private", + [str(account.address), f"{amount}u128"], + f"privatize {amount} of {token_program}", + ) + records = [r for r in self.records_of(account, tx_id) if "amount" in r] + if not records: + raise RuntimeError( + f"No Token record in {token_program} privatize outputs (tx {tx_id})") + return records[0] + + def read_mapping(self, mapping: str, key: str) -> Optional[str]: + from aleo_shield_swap._core import normalize_mapping_value + raw = self.aleo.programs.get(AMM_PROGRAM).mapping(mapping).get(key) + return normalize_mapping_value(raw) + + def stop(self) -> None: + self.devnode.stop() + + +def setup_amm_devnode() -> AmmDevnode: + """Boot a devnode with the full AMM stack deployed, configured, funded.""" + from aleo.testing import Devnode + + devnode = Devnode().start() + aleo = devnode.aleo + admin = devnode.accounts[0] # genesis 0 — also the tokens' baked admin + aleo.default_account = admin + aleo.record_provider = None # no scanner on a devnode — explicit records + + # Advance past the last TEST consensus-version height so the node (and + # everything built against it) runs at the latest consensus version. + devnode.advance(LAST_TEST_CONSENSUS_HEIGHT + 2) + + multisig_source = read_fixture(MULTISIG_PROGRAM) + amm_source = patch_admin_address(read_fixture(AMM_PROGRAM), str(admin.address)) + token_a_source = read_fixture(f"{TOKEN_A.removesuffix('.aleo')}.aleo") + token_b_source = read_fixture(f"{TOKEN_B.removesuffix('.aleo')}.aleo") + credits_source = str(aleo.network.get_program("credits.aleo")) + + imports = { + MULTISIG_PROGRAM: multisig_source, + AMM_PROGRAM: amm_source, + TOKEN_A: token_a_source, + TOKEN_B: token_b_source, + "credits.aleo": credits_source, + } + + a_field = identifier_to_field("test_token_a") + b_field = identifier_to_field("test_token_b") + a_first = int(a_field.removesuffix("field")) < int(b_field.removesuffix("field")) + + ctx = AmmDevnode( + devnode=devnode, aleo=aleo, admin=admin, user=None, imports=imports, + token0_field=a_field if a_first else b_field, + token1_field=b_field if a_first else a_field, + token0_program=TOKEN_A if a_first else TOKEN_B, + token1_program=TOKEN_B if a_first else TOKEN_A, + ) + + # Deploy in dependency order; the AMM statically imports the multisig. + ctx.deploy_program(multisig_source, MULTISIG_PROGRAM) + ctx.deploy_program(amm_source, AMM_PROGRAM) + ctx.deploy_program(token_a_source, TOKEN_A) + ctx.deploy_program(token_b_source, TOKEN_B) + + # Admin configuration: fee tiers, spacings, bindings, token registration. + for label, function, inputs in [ + ("add_fee_tier 3000", "add_fee_tier", ["3000u16"]), + ("add_fee_tier 500", "add_fee_tier", ["500u16"]), + ("add_tick_spacing 60", "add_tick_spacing", ["60u32"]), + ("add_tick_spacing 10", "add_tick_spacing", ["10u32"]), + ("bind 3000->60", "bind_fee_to_tick_spacing", ["3000u16", "60u32"]), + ("bind 500->10", "bind_fee_to_tick_spacing", ["500u16", "10u32"]), + ("decimals A", "set_token_decimals", [a_field, "6u8"]), + ("decimals B", "set_token_decimals", [b_field, "6u8"]), + ("allow A", "allow_token", [a_field]), + ("allow B", "allow_token", [b_field]), + ("open pool creation", "set_pool_creation_is_open", ["true"]), + ]: + ctx.execute(admin, AMM_PROGRAM, function, inputs, f"admin {label}") + + # A non-admin user proves the open-pool-creation gate: fund fees, mint + # both tokens to it publicly. + user = aleo.account.create() + ctx.user = user + ctx.execute(admin, "credits.aleo", "transfer_public", + [str(user.address), "100000000u64"], "fund user") + for token in (TOKEN_A, TOKEN_B): + ctx.execute(admin, token, "mint_public", + [str(user.address), f"{TOKEN_SUPPLY}u128"], f"mint {token}") + + return ctx diff --git a/shield-swap-sdk/tests/integration/test_devnode_lifecycle.py b/shield-swap-sdk/tests/integration/test_devnode_lifecycle.py new file mode 100644 index 00000000..95bb6ea3 --- /dev/null +++ b/shield-swap-sdk/tests/integration/test_devnode_lifecycle.py @@ -0,0 +1,334 @@ +"""Full AMM lifecycle on a devnode, through the ShieldSwap verbs. + +Python analog of the TS suite's ``devnodeLifecycle.actions.e2e.test.ts``: a +non-admin user creates two pools (same pair, two fee tiers), mints and +resizes positions, swaps both directions and claims the outputs, collects +earnings, and burns out — with the on-chain mappings asserted after every +step. Fully hermetic: vendored programs, local devnode, no live network. + +Run with:: + + python -m pytest tests/integration/test_devnode_lifecycle.py -m devnode -v + +Requires the ``aleo-devnode`` binary (skips otherwise). Deployments are +always proofless (dummy verifying keys — see ``devnode_amm``). Executions +run on one of two ladders: + +* default — every execution fully proven locally (slow: SNARK parameter + downloads + proving-key synthesis on first use) +* ``ALEO_DEVNODE_UNPROVEN=1`` — proofless executions (the devnode skips + proof verification); fast +""" +from __future__ import annotations + +import re + +import pytest + +from aleo_shield_swap import ShieldSwap +from aleo_shield_swap.errors import SwapOutputNotFinalizedError +from aleo_shield_swap.tick_math import MIN_TICK + +from .devnode_amm import AMM_PROGRAM, AmmDevnode, setup_amm_devnode + +pytestmark = pytest.mark.devnode + +POOLS = [ + {"fee": 3000, "tick_spacing": 60}, + {"fee": 500, "tick_spacing": 10}, +] + + +def _position_numbers(plaintext: str) -> dict[str, int]: + out = {} + for name in ("liquidity", "tokens_owed0", "tokens_owed1"): + m = re.search(rf"{name}:\s*(\d+)u128", plaintext) + assert m, f"no {name} in position: {plaintext}" + out[name] = int(m.group(1)) + return out + + +@pytest.fixture(scope="module") +def ctx() -> AmmDevnode: + try: + context = setup_amm_devnode() + except Exception as exc: + if "aleo-devnode not found" in str(exc): + pytest.skip(f"aleo-devnode binary not available: {exc}") + raise + yield context + context.stop() + + +@pytest.fixture(scope="module") +def dex(ctx) -> ShieldSwap: + dex = ShieldSwap(ctx.aleo, program=AMM_PROGRAM) + ctx.aleo.default_account = ctx.user + return dex + + +class _Journey: + """Mutable per-pool state threaded through the ordered tests.""" + + def __init__(self): + self.pools = [dict(p) for p in POOLS] + + +@pytest.fixture(scope="module") +def journey() -> _Journey: + return _Journey() + + +def _refresh_nft(ctx, pool_case, tx_id): + records = ctx.records_of(ctx.user, tx_id) + nfts = [r for r in records if "tick_lower" in r] + assert nfts, f"no PositionNFT record in {tx_id}" + if "nft_record" not in pool_case: + spacing = pool_case["tick_spacing"] + assert re.search(rf"tick_lower:\s*{-10 * spacing}i32", nfts[0]) + assert re.search(rf"tick_upper:\s*{10 * spacing}i32", nfts[0]) + pool_case["nft_record"] = nfts[0] + + +def _position(ctx, pool_case): + raw = ctx.read_mapping("positions", pool_case["position_token_id"]) + assert raw, f"positions[{pool_case['position_token_id']}] is empty" + return _position_numbers(raw) + + +def _submit(ctx, call, account): + """Drive a DexCall through the fixture's ladder: transact() on the proven + ladder; hand-built unproven transaction otherwise.""" + from .devnode_amm import UNPROVEN + + if not UNPROVEN: + result = call.transact(account) + ctx.devnode.advance(1) + return result + # Unproven: reuse the DexCall's bound call + result builder. + from aleo_shield_swap._calls import root_outputs + + net = ctx._net() + process = ctx.aleo.process + auth = call._bound.authorize(account).raw + root = ctx.state_root() + execution = net.Execution.from_authorization_unproven(auth, root) + cost, _ = process.execution_cost(execution) + fee_auth = process.authorize_fee_public( + account.private_key, cost, 0, execution.execution_id) + fee = net.Fee.from_authorization_unproven(fee_auth, root) + tx = net.Transaction.from_execution(execution, fee) + tx_id = ctx.submit_and_confirm(tx, "dex call") + decoded = [ + {"program": str(t.program_id), "function": str(t.function_name), + "outputs": list(t.outputs())} + for t in ctx.aleo.network.get_transaction_object(tx_id).transitions() + ] + outputs = root_outputs(decoded, call._bound.program_id, + call._bound.function_name) + return call._build(tx_id, outputs) + + +def test_admin_setup_landed(ctx): + assert ctx.read_mapping("fee_tiers", "3000u16") == "true" + assert ctx.read_mapping("fee_tiers", "500u16") == "true" + assert ctx.read_mapping("tick_spacings", "60u32") == "true" + assert ctx.read_mapping("fee_to_tick_spacing", "500u16") == "10u32" + assert ctx.read_mapping("token_allowed", ctx.token0_field) == "true" + assert ctx.read_mapping("token_decimals", ctx.token1_field) == "6u8" + assert ctx.read_mapping("pool_creation_is_open", "true") == "true" + assert ctx.read_mapping("admin", "true") == str(ctx.admin.address) + + +def test_non_admin_creates_two_pools(ctx, dex, journey): + for pool_case in journey.pools: + call = dex.create_pool( + token0_id=ctx.token0_field, token1_id=ctx.token1_field, + fee=pool_case["fee"], initial_tick=0, + imports=ctx.imports, account=ctx.user) + result = _submit(ctx, call, ctx.user) + assert result.transaction_id.startswith("at1") + + # Authoritative parity: locally derived key == the chain's. + pool_key = dex.derive_pool_key(ctx.token0_field, ctx.token1_field, + pool_case["fee"]) + assert result.position_token_id == pool_key # create_pool's field output + pool_case["pool_key"] = pool_key + + assert ctx.read_mapping("initialized_pools", pool_key) == "true" + pool_struct = ctx.read_mapping("pools", pool_key) + assert "enabled: true" in pool_struct + assert f"fee: {pool_case['fee']}u16" in pool_struct + slot = dex.get_slot(pool_key) + assert slot.tick == 0 + assert slot.tick_spacing == pool_case["tick_spacing"] + assert slot.liquidity == 0 + assert journey.pools[0]["pool_key"] != journey.pools[1]["pool_key"] + + +def test_mint_opens_positions(ctx, dex, journey): + for pool_case in journey.pools: + record0 = ctx.privatize_token(ctx.user, ctx.token0_program, 200_000_000) + record1 = ctx.privatize_token(ctx.user, ctx.token1_program, 200_000_000) + spacing = pool_case["tick_spacing"] + call = dex.mint( + pool_key=pool_case["pool_key"], + tick_lower=-10 * spacing, tick_upper=10 * spacing, + amount0_desired=100_000_000, amount1_desired=100_000_000, + token0_record=record0, token1_record=record1, + imports=ctx.imports, account=ctx.user) + result = _submit(ctx, call, ctx.user) + assert result.position_token_id and result.position_token_id.endswith("field") + pool_case["position_token_id"] = result.position_token_id + _refresh_nft(ctx, pool_case, result.transaction_id) + + # Tick-key parity: the mint initialized tick_lower; the locally + # derived key must locate it in the ticks mapping. + tick_key = dex.derive_tick_key(pool_case["pool_key"], -10 * spacing) + assert ctx.read_mapping("ticks", tick_key) + + pos = _position(ctx, pool_case) + assert pos["liquidity"] > 0 + slot = dex.get_slot(pool_case["pool_key"]) + assert slot.liquidity == pos["liquidity"] + + +def test_increase_liquidity_grows_position(ctx, dex, journey): + for pool_case in journey.pools: + before = _position(ctx, pool_case) + record0 = ctx.privatize_token(ctx.user, ctx.token0_program, 100_000_000) + record1 = ctx.privatize_token(ctx.user, ctx.token1_program, 100_000_000) + call = dex.increase_liquidity( + pool_key=pool_case["pool_key"], + amount0_desired=50_000_000, amount1_desired=50_000_000, + position_record=pool_case["nft_record"], + token0_record=record0, token1_record=record1, + # The position's ticks are already initialized, so the contract + # skips hint validation — the MIN sentinel passes through. + tick_lower_hint=MIN_TICK - 1, tick_upper_hint=MIN_TICK - 1, + imports=ctx.imports, account=ctx.user) + result = _submit(ctx, call, ctx.user) + _refresh_nft(ctx, pool_case, result.transaction_id) + assert _position(ctx, pool_case)["liquidity"] > before["liquidity"] + + +def test_decrease_liquidity_settles_owed(ctx, dex, journey): + for pool_case in journey.pools: + before = _position(ctx, pool_case) + call = dex.decrease_liquidity( + pool_key=pool_case["pool_key"], + liquidity_to_remove=before["liquidity"] // 4, + position_record=pool_case["nft_record"], + imports=ctx.imports, account=ctx.user) + result = _submit(ctx, call, ctx.user) + _refresh_nft(ctx, pool_case, result.transaction_id) + after = _position(ctx, pool_case) + assert after["liquidity"] == before["liquidity"] - before["liquidity"] // 4 + assert after["tokens_owed0"] + after["tokens_owed1"] > 0 + + +def test_swaps_both_directions_and_claims(ctx, dex, journey): + pool_case = journey.pools[0] + for zero_for_one in (True, False): + token_in_program = ctx.token0_program if zero_for_one else ctx.token1_program + token_in_id = ctx.token0_field if zero_for_one else ctx.token1_field + slot_before = dex.get_slot(pool_case["pool_key"]) + token_record = ctx.privatize_token(ctx.user, token_in_program, 20_000_000) + + call = dex.swap( + pool_key=pool_case["pool_key"], token_in_id=token_in_id, + amount_in=10_000_000, + # A 10M swap against ~150M of liquidity moves the price a lot: + # pin the floor at zero and assert on the claimed amount instead. + expected_out=0, slippage_bps=0, + token_record=token_record, + imports=ctx.imports, account=ctx.user) + handle = _submit(ctx, call, ctx.user) + assert handle.swap_id and handle.swap_id.endswith("field") + + # The finalize computed the outcome — read it fresh from chain. + output = dex.get_swap_output(handle) + assert output.amount_out > 0 + + claim = _submit(ctx, dex.claim_swap_output( + handle, imports=ctx.imports, account=ctx.user), ctx.user) + assert claim.transaction_id.startswith("at1") + # The SDK-reported amount must match the chain's own computation. + assert claim.amount_out == output.amount_out + + # The private output landed as a Token record of exactly amount_out. + records = ctx.records_of(ctx.user, claim.transaction_id) + assert any(f"amount: {output.amount_out}u128" in r for r in records), \ + f"no claimed Token record of {output.amount_out} in {records}" + + with pytest.raises(SwapOutputNotFinalizedError): + dex.get_swap_output(handle) # the claim consumed the entry + + slot_after = dex.get_slot(pool_case["pool_key"]) + if zero_for_one: + assert slot_after.sqrt_price < slot_before.sqrt_price + else: + assert slot_after.sqrt_price > slot_before.sqrt_price + + +def test_collect_pays_out_owed(ctx, dex, journey): + for pool_case in journey.pools: + # tokens_owed updates lazily: collect folds accrued fees into owed + # first, then pays — two passes drain fully. + paid_out = 0 + for pass_no in range(2): + owed = _position(ctx, pool_case) + if owed["tokens_owed0"] + owed["tokens_owed1"] == 0: + assert pass_no > 0, "collect precondition: position owes nothing" + break + call = dex.collect( + pool_key=pool_case["pool_key"], + amount0_requested=owed["tokens_owed0"], + amount1_requested=owed["tokens_owed1"], + position_record=pool_case["nft_record"], + imports=ctx.imports, account=ctx.user) + result = _submit(ctx, call, ctx.user) + for r in ctx.records_of(ctx.user, result.transaction_id): + m = re.search(r"amount:\s*(\d+)u128", r) + if m: + paid_out += int(m.group(1)) + _refresh_nft(ctx, pool_case, result.transaction_id) + after = _position(ctx, pool_case) + assert after["tokens_owed0"] == 0 and after["tokens_owed1"] == 0 + assert paid_out > 0 + + +def test_burn_exits_positions(ctx, dex, journey): + for pool_case in journey.pools: + remaining = _position(ctx, pool_case) + if remaining["liquidity"] > 0: + result = _submit(ctx, dex.decrease_liquidity( + pool_key=pool_case["pool_key"], + liquidity_to_remove=remaining["liquidity"], + position_record=pool_case["nft_record"], + imports=ctx.imports, account=ctx.user), ctx.user) + _refresh_nft(ctx, pool_case, result.transaction_id) + owed = _position(ctx, pool_case) + if owed["tokens_owed0"] + owed["tokens_owed1"] > 0: + result = _submit(ctx, dex.collect( + pool_key=pool_case["pool_key"], + amount0_requested=owed["tokens_owed0"], + amount1_requested=owed["tokens_owed1"], + position_record=pool_case["nft_record"], + imports=ctx.imports, account=ctx.user), ctx.user) + _refresh_nft(ctx, pool_case, result.transaction_id) + + result = _submit(ctx, dex.burn( + pool_key=pool_case["pool_key"], + position_record=pool_case["nft_record"], account=ctx.user), ctx.user) + assert result.transaction_id.startswith("at1") + # The position mapping entry is removed by the burn finalize. + assert ctx.read_mapping("positions", pool_case["position_token_id"]) is None + + +def test_identifier_to_field_golden(): + from .devnode_amm import identifier_to_field + + # Golden values from the TS suite — pins the LE-byte token-id encoding. + assert identifier_to_field("test_token_a") == "30135415236709662781336675700field" + assert identifier_to_field("test_token_b") == "30444900246531007850061456756field" diff --git a/shield-swap-sdk/tests/integration/test_drift.py b/shield-swap-sdk/tests/integration/test_drift.py new file mode 100644 index 00000000..6aa59f6a --- /dev/null +++ b/shield-swap-sdk/tests/integration/test_drift.py @@ -0,0 +1,37 @@ +"""Pinned-ABI drift test: a contract redeploy fails OUR CI, not a consumer.""" +import json +import re +from pathlib import Path + +import pytest + +from .conftest import ENDPOINT + +pytestmark = pytest.mark.live + +ABI_PATH = Path(__file__).parents[2] / "codegen" / "shield_swap.abi.json" +PROGRAM = "shield_swap_v3.aleo" + + +def _fetch(program_id: str) -> str: + import requests + + r = requests.get(f"{ENDPOINT}/v2/testnet/program/{program_id}", timeout=30) + r.raise_for_status() + return r.json() + + +def test_pinned_abi_matches_deployed(): + import aleo.abi + + src = _fetch(PROGRAM) + deps = [] + for dep in re.findall(r"^import\s+(\S+?);\s*$", src, re.MULTILINE): + if dep != "credits.aleo": + deps.append((dep, _fetch(dep))) + live = aleo.abi.generate_abi(src, "testnet", imports=deps) + violations = aleo.abi.check_compatibility(live, json.loads(ABI_PATH.read_text())) + assert violations == [], ( + f"deployed {PROGRAM} drifted from the pinned ABI — rerun " + f"codegen/regen-abi.sh and review the diff: {violations}" + ) diff --git a/shield-swap-sdk/tests/integration/test_reads_live.py b/shield-swap-sdk/tests/integration/test_reads_live.py new file mode 100644 index 00000000..35bab5b0 --- /dev/null +++ b/shield-swap-sdk/tests/integration/test_reads_live.py @@ -0,0 +1,153 @@ +"""Read tier: EVERY read action against the live DEX API + testnet chain. + +No credentials, no spending — run with ``-m live``. Assertions target +invariants and shapes, not exact live figures (testnet state varies). +""" +from __future__ import annotations + +import pytest + +from aleo_shield_swap.errors import ( + DexApiError, + PoolNotFoundError, + SwapOutputNotFinalizedError, +) +from .conftest import skip_if_access_gated +from aleo_shield_swap.tick_math import ( + MAX_SQRT_PRICE, + MAX_TICK, + MIN_SQRT_PRICE, + MIN_TICK, +) + +pytestmark = pytest.mark.live + +BURN_ADDRESS = "aleo1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3ljyzc" + + +@pytest.fixture(scope="module") +def pools(live_dex_module): + entries = live_dex_module.api.get_pools() + assert entries, "no pools on the DEX API" + return entries + + +@pytest.fixture(scope="module") +def pool(pools): + return pools[0] + + +# ── dex.api (off-chain service) ────────────────────────────────────────────── + +def test_api_get_pools_shapes(pools): + for entry in pools: + assert entry.key.endswith("field") + assert entry.token0.endswith("field") and entry.token1.endswith("field") + assert isinstance(entry.enabled, bool) + if entry.token0_info is not None: + assert entry.token0_info.decimals >= 0 + assert entry.token0_info.wrapper_program.endswith(".aleo") + + +def test_api_get_tokens(live_dex_module): + tokens = live_dex_module.api.get_tokens() + assert tokens, "no tokens in the registry" + for tok in tokens: + assert tok.address.endswith("field") + assert tok.decimals >= 0 + assert tok.symbol + + +def test_api_get_route_quotes_both_directions(live_dex_module, pool): + scale = 10 ** (pool.token0_info.decimals if pool.token0_info else 6) + fwd = skip_if_access_gated(lambda: live_dex_module.api.get_route( + token_in=pool.token0, token_out=pool.token1, amount_in=scale)) + assert fwd.token_in == pool.token0 and fwd.token_out == pool.token1 + assert fwd.hops, "route has no hops" + rev = live_dex_module.api.get_route( + token_in=pool.token1, token_out=pool.token0) + assert rev.token_in == pool.token1 + + +def test_api_get_ohlcv(live_dex_module, pool): + candles = skip_if_access_gated(lambda: live_dex_module.api.get_ohlcv( + pool.key, granularity="1d", + from_ts="2026-01-01T00:00:00", to_ts="2026-12-31T00:00:00")) + for candle in candles: # may be empty on a quiet pool + assert float(candle.h) >= float(candle.l) + + +def test_api_get_public_balances_shape(live_dex_module): + # Any address is valid to query; the burn address just returns few/none. + balances = skip_if_access_gated( + lambda: live_dex_module.api.get_public_balances(BURN_ADDRESS)) + for bal in balances: + assert int(bal.balance) >= 0 + assert bal.token_id.endswith("field") + + +def test_api_get_swap_unknown_id_raises(live_dex_module): + with pytest.raises(DexApiError): + live_dex_module.api.get_swap("0field") + + +# ── Chain reads (node, via the facade) ─────────────────────────────────────── + +def test_get_pool_matches_api(live_dex_module, pool): + chain_pool = live_dex_module.get_pool(pool.key) + assert chain_pool.token0 == pool.token0 + assert chain_pool.token1 == pool.token1 + assert chain_pool.scale0 >= 1 and chain_pool.scale1 >= 1 + + +def test_get_slot_invariants(live_dex_module, pool): + slot = live_dex_module.get_slot(pool.key) + assert MIN_SQRT_PRICE <= slot.sqrt_price <= MAX_SQRT_PRICE + assert MIN_TICK <= slot.tick <= MAX_TICK + assert slot.tick_spacing > 0 + assert slot.next_init_below <= slot.tick <= slot.next_init_above + d0 = pool.token0_info.decimals if pool.token0_info else 9 + d1 = pool.token1_info.decimals if pool.token1_info else 9 + assert slot.price(d0, d1) > 0 + + +def test_is_pool_initialized(live_dex_module, pool): + assert live_dex_module.is_pool_initialized(pool.key) is True + assert live_dex_module.is_pool_initialized("1field") is False + + +def test_missing_pool_raises(live_dex_module): + with pytest.raises(PoolNotFoundError): + live_dex_module.get_pool("1field") + + +def test_get_swap_output_absent_raises(live_dex_module): + with pytest.raises(SwapOutputNotFinalizedError): + live_dex_module.get_swap_output("1field") + + +# ── Local derivations vs live chain (the strongest cheap invariants) ───────── + +def test_local_pool_key_matches_indexer(live_dex_module, pools): + """Local BHP256 derivation must reproduce the indexer's pool keys.""" + matched = 0 + for entry in pools: + chain_pool = live_dex_module.get_pool(entry.key) + derived = live_dex_module.derive_pool_key( + chain_pool.token0, chain_pool.token1, chain_pool.fee) + assert derived == entry.key + matched += 1 + assert matched > 0 + + +def test_local_tick_key_locates_initialized_tick(live_dex_module, pool): + """A tick the slot names as initialized must be readable via the locally + derived tick key (i32 struct-hash parity with the contract).""" + slot = live_dex_module.get_slot(pool.key) + for tick in (slot.next_init_below, slot.next_init_above): + if MIN_TICK < tick < MAX_TICK: # sentinels bound the list + key = live_dex_module.derive_tick_key(pool.key, tick) + raw = live_dex_module._mapping_value("ticks", key) + assert raw is not None, f"ticks[{tick}] unreachable via derived key" + return + pytest.skip("no non-sentinel initialized tick to probe") diff --git a/shield-swap-sdk/tests/integration/test_swap_lifecycle.py b/shield-swap-sdk/tests/integration/test_swap_lifecycle.py new file mode 100644 index 00000000..c8b945fe --- /dev/null +++ b/shield-swap-sdk/tests/integration/test_swap_lifecycle.py @@ -0,0 +1,84 @@ +"""Write tier: the full private-swap lifecycle on the REAL testnet. + +Spends real testnet funds (DPS fee master pays proving fees). Mirrors the +main SDK's live-e2e conventions: pytest.mark.live + credential skips. +""" +from __future__ import annotations + +import os +import time + +import pytest + +from aleo_shield_swap.errors import SwapOutputNotFinalizedError +from aleo_shield_swap.types import SwapHandle + +from .conftest import ENDPOINT, write_tier + +pytestmark = [pytest.mark.live, pytest.mark.slow] + + +def _with_retry(fn, attempts=3, delay=5.0): + last = None + for _ in range(attempts): + try: + return fn() + except Exception as exc: # noqa: BLE001 - live services flake + last = exc + time.sleep(delay) + raise last + + +@write_tier +def test_private_swap_roundtrip(): + from aleo import Aleo, HTTPProvider + + from aleo_shield_swap import ShieldSwap + + provider = HTTPProvider(ENDPOINT, network="testnet", + api_key=os.environ["ALEO_E2E_API_KEY"]) + aleo = Aleo(provider) + aleo.network_client.consumer_id = os.environ["ALEO_E2E_CONSUMER_ID"] + acct = aleo.account.from_private_key(os.environ["ALEO_E2E_PRIVATE_KEY"]) + aleo.default_account = acct + aleo.records.register(acct) + dex = ShieldSwap(aleo) + + # Pick a pool where the account holds a private balance of one side. + pools = dex.api.get_pools() + assert pools + pool = pools[0] + token_in = pool.token0 + program_in = pool.token0_info.wrapper_program + + balances = dex.get_private_balances([program_in], account=acct) + amount_in = min(balances[program_in], 10 ** max(pool.token0_info.decimals - 2, 0)) + if amount_in == 0: + pytest.skip(f"account holds no private {program_in} records to swap") + + route = dex.api.get_route(token_in=token_in, token_out=pool.token1, + amount_in=amount_in) + expected = (int(float(route.estimated_amount_out) * 10 ** pool.token1_info.decimals) + if route.estimated_amount_out else None) + + handle = _with_retry(lambda: dex.swap( + pool_key=pool.key, token_in_id=token_in, amount_in=amount_in, + expected_out=expected, slippage_bps=100, + token_in_program=program_in).delegate(acct)) + assert isinstance(handle, SwapHandle) + assert handle.swap_id and handle.blinded_address + assert SwapHandle.from_json(handle.to_json()) == handle + + # Poll until the request finalizes (~a few blocks). + deadline = time.time() + 300 + while True: + try: + dex.get_swap_output(handle.swap_id) + break + except SwapOutputNotFinalizedError: + if time.time() > deadline: + pytest.fail("swap request did not finalize within 5 minutes") + time.sleep(10) + + result = _with_retry(lambda: dex.claim_swap_output(handle).delegate(acct)) + assert result.amount_out > 0 diff --git a/shield-swap-sdk/tests/test_agent.py b/shield-swap-sdk/tests/test_agent.py new file mode 100644 index 00000000..2557fcdf --- /dev/null +++ b/shield-swap-sdk/tests/test_agent.py @@ -0,0 +1,38 @@ +import json + +import pytest + +from aleo_shield_swap.agent import dispatch_tool, shield_swap_tools +from aleo_shield_swap.client import ShieldSwap + + +def test_tool_definitions_shape(): + tools = shield_swap_tools() + names = {t["name"] for t in tools} + assert {"get_pools", "get_route", "get_slot", "get_balances", + "swap", "claim_swap_output", "mint"} <= names + for t in tools: + assert t["description"] + assert t["input_schema"]["type"] == "object" + json.dumps(t) # fully serializable + + +def test_dispatch_get_slot(stub_aleo): + out = dispatch_tool(ShieldSwap(stub_aleo), "get_slot", {"pool_key": "5field"}) + assert out["tick"] == 4055 + json.dumps(out) + + +def test_dispatch_swap_returns_serialized_handle(stub_aleo): + out = dispatch_tool(ShieldSwap(stub_aleo), "swap", + {"pool_key": "5field", "token_in_id": "1field", + "amount_in": 10**9, "expected_out": 1_000_000, + "token_in_program": "tok.aleo"}) + assert out["swap_id"] == "77field" # delegate path, decoded tx + assert out["blinding_factor"] + json.dumps(out) + + +def test_dispatch_unknown_tool(stub_aleo): + with pytest.raises(ValueError, match="Unknown"): + dispatch_tool(ShieldSwap(stub_aleo), "nope", {}) diff --git a/shield-swap-sdk/tests/test_api_client.py b/shield-swap-sdk/tests/test_api_client.py new file mode 100644 index 00000000..ef9290ca --- /dev/null +++ b/shield-swap-sdk/tests/test_api_client.py @@ -0,0 +1,90 @@ +import json +from pathlib import Path + +import pytest + +from aleo_shield_swap.api import ApiClient +from aleo_shield_swap.errors import DexApiError + +POOLS = json.loads((Path(__file__).parent / "fixtures" / "pools_response.json").read_text()) + + +class _Resp: + def __init__(self, status_code, payload): + self.status_code = status_code + self._payload = payload + self.text = json.dumps(payload) + + def json(self): + return self._payload + + +class _Session: + def __init__(self, responses): + self.responses = list(responses) + self.calls = [] + + def get(self, url, params=None, timeout=None, headers=None): + self.calls.append(("GET", url, params, headers)) + return self.responses.pop(0) + + def post(self, url, json=None, timeout=None, headers=None): + self.calls.append(("POST", url, json, headers)) + return self.responses.pop(0) + + +def test_get_pools_parses_models_and_token_info(): + s = _Session([_Resp(200, POOLS)]) + pools = ApiClient(base_url="https://x", session=s).get_pools() + assert s.calls[0][1] == "https://x/pools" + entry = pools[0] + assert entry.key.endswith("field") # delegation to PoolStateDoc + assert entry.token0_info.wrapper_program.endswith(".aleo") + + +def test_get_route_stringifies_amount(): + payload = {"data": {"hops": [], "token_in": "1field", "token_out": "2field", + "estimated_amount_out": "42.5"}} + s = _Session([_Resp(200, payload)]) + route = ApiClient(base_url="https://x", session=s).get_route( + token_in="1field", token_out="2field", amount_in=10**18) + assert route.estimated_amount_out == "42.5" + _, url, params, _ = s.calls[0] + assert url == "https://x/route" + assert params == {"token_in": "1field", "token_out": "2field", + "amount_in": str(10**18)} + + +def test_get_public_balances_passes_user(): + payload = {"data": [{"balance": "5", "decimals": 6, "name": "USDCx", + "symbol": "wUSDCx", "token_address": "4field", + "token_id": "4field", "extra_field": "ignored"}]} + s = _Session([_Resp(200, payload)]) + bals = ApiClient(base_url="https://x", session=s).get_public_balances("aleo1me") + assert bals[0].balance == "5" + assert s.calls[0][2] == {"user": "aleo1me"} + + +def test_non_2xx_raises_dex_api_error(): + s = _Session([_Resp(503, {"error": "down"})]) + with pytest.raises(DexApiError) as ei: + ApiClient(base_url="https://x", session=s).get_pools() + assert ei.value.status == 503 + + +def test_authenticate_stores_bearer_token(): + s = _Session([ + _Resp(200, {"data": {"message": "sign me"}}), + _Resp(200, {"data": {"token": "jwt-abc"}}), + _Resp(200, {"data": []}), + ]) + client = ApiClient(base_url="https://x", session=s) + signed = [] + token = client.authenticate("aleo1me", lambda msg: signed.append(msg) or "sign1xyz") + assert token == "jwt-abc" and signed == ["sign me"] + method, url, body, _ = s.calls[1] + assert (method, url) == ("POST", "https://x/auth/verify") + assert body == {"address": "aleo1me", "signature": "sign1xyz"} + client.get_public_balances("aleo1me") + headers = s.calls[2][3] + assert headers["authorization"] == "Bearer jwt-abc" diff --git a/shield-swap-sdk/tests/test_api_models.py b/shield-swap-sdk/tests/test_api_models.py new file mode 100644 index 00000000..1ac45ade --- /dev/null +++ b/shield-swap-sdk/tests/test_api_models.py @@ -0,0 +1,40 @@ +"""Sanity: the generated OpenAPI models parse a captured live /pools entry. + +The live API returns MORE fields than the documented schemas (e.g. the +pools entries carry undocumented token0_info/token1_info) — the client +(api.py) builds models tolerantly by filtering to declared fields. These +tests pin that reality so a regenerated spec that gains the fields shows up +as a test-visible change. +""" +import json +from dataclasses import fields +from pathlib import Path + +from aleo_shield_swap import _api_models as m + +FIXTURE = Path(__file__).parent / "fixtures" / "pools_response.json" +POOLS = json.loads(FIXTURE.read_text()) + + +def _filtered(cls, d: dict): + names = {f.name for f in fields(cls)} + return cls(**{k: v for k, v in d.items() if k in names}) + + +def test_pool_state_doc_parses_live_entry(): + entry = POOLS["data"][0] + pool = _filtered(m.PoolStateDoc, entry) + assert pool.key.endswith("field") + assert pool.token0.endswith("field") and pool.token1.endswith("field") + assert isinstance(pool.enabled, bool) + + +def test_token_doc_parses_undocumented_token_info(): + info = POOLS["data"][0]["token0_info"] + tok = _filtered(m.TokenDoc, info) + assert tok.decimals >= 0 + assert tok.wrapper_program is not None and tok.wrapper_program.endswith(".aleo") + + +def test_route_models_exist(): + assert hasattr(m, "RouteResultDoc") and hasattr(m, "RouteResponseDoc") diff --git a/shield-swap-sdk/tests/test_async_client.py b/shield-swap-sdk/tests/test_async_client.py new file mode 100644 index 00000000..960accec --- /dev/null +++ b/shield-swap-sdk/tests/test_async_client.py @@ -0,0 +1,192 @@ +"""AsyncShieldSwap over an async stub facade — mirrors the sync assertions +for reads and the swap input order.""" +import pytest + +from aleo_shield_swap.async_client import AsyncShieldSwap +from aleo_shield_swap.errors import SwapOutputNotFinalizedError +from aleo_shield_swap.tick_math import MIN_SQRT_PRICE + +from .conftest import ( + BLINDED_ADDRESS_0, + BLINDING_FACTOR_0, + POOL_TEXT, + RECORD_TEXT, + SLOT_TEXT, + StubAccount, +) + +pytestmark = pytest.mark.asyncio + + +from .conftest import PROGRAM_ID, _Process, _StubTransition, _valid_source + + +class _AsyncMapping: + def __init__(self, values): + self.values = values + + async def get(self, key): + return self.values.get(key) + + +class _Tx: + """Shape-faithful async TransactionResult stub (root transition LAST).""" + + id = "at1asynctx" + raw = object() + + def __init__(self, fn): + self._fn = fn + + @property + def outputs(self): + return [[{"value": "999field"}], [{"value": "88field"}]] + + def decoded(self): + return [{"program": "tok.aleo", "function": "transfer", + "outputs": [{"value": "999field"}]}, + {"program": PROGRAM_ID, "function": self._fn, + "outputs": [{"value": "88field"}]}] + + def transitions(self): + return [_StubTransition("tok.aleo", "transfer", ["999field"]), + _StubTransition(PROGRAM_ID, self._fn, ["88field"])] + + +class _AsyncBoundCall: + def __init__(self, recorder, fn, args): + self.program_id = PROGRAM_ID + self.function_name = fn + self._recorder = recorder + recorder.last_call = (fn, list(args)) + + def simulate(self, account=None): + return "simulated" + + async def build_transaction(self, account=None, **kw): + return _Tx(self.function_name) + + async def delegate(self, account=None, **kw): + self._recorder.delegated_fn = self.function_name + return {"transaction_id": "at1delegated"} + + +class _AsyncFunctions: + def __init__(self, recorder): + self._recorder = recorder + + def __getattr__(self, fn): + def call(*args): + return _AsyncBoundCall(self._recorder, fn, args) + return call + + +class _AsyncProgram: + def __init__(self, recorder, mappings, pid): + self._mappings = mappings + self.functions = _AsyncFunctions(recorder) + self.source = _valid_source(pid) + + def mapping(self, name): + return _AsyncMapping(self._mappings.get(name, {})) + + +class _AsyncPrograms: + def __init__(self, recorder, mappings): + self._recorder = recorder + self._mappings = mappings + + async def get(self, pid): + return _AsyncProgram(self._recorder, self._mappings, pid) + + +class _AsyncNetwork: + def __init__(self, recorder): + self._recorder = recorder + + async def get_latest_height(self): + return 1000 + + async def submit_transaction(self, raw): + self._recorder.submitted.append(raw) + return "at1asynctx" + + async def wait_for_transaction(self, tx_id, **kw): + self._recorder.waited.append(tx_id) + + async def get_transaction_object(self, tx_id): + return _Tx(self._recorder.delegated_fn) + + +class _AsyncProvider: + def __init__(self, records): + self._records = records + + async def find(self, account=None, *, program=None, unspent=True, **_): + return self._records + + +class AsyncStubAleo: + network_name = "testnet" + + def __init__(self, mappings=None, records=None): + self.last_call = None + self.delegated_fn = None + self.submitted = [] + self.waited = [] + self.registered_programs = [] + self.programs = _AsyncPrograms(self, mappings or {}) + self.record_provider = _AsyncProvider( + records if records is not None else [{"record_plaintext": RECORD_TEXT}]) + self.network = _AsyncNetwork(self) + self.process = _Process(self) + self.default_account = StubAccount() + + +@pytest.fixture +def astub(): + return AsyncStubAleo(mappings={ + "pools": {"5field": POOL_TEXT}, + "slots": {"5field": SLOT_TEXT}, + "swap_outputs": {}, + "used_blinded_addresses": {}, + }) + + +async def test_async_reads(astub): + dex = AsyncShieldSwap(astub) + slot = await dex.get_slot("5field") + assert slot.tick == 4055 + pool = await dex.get_pool("5field") + assert pool.fee == 3000 + with pytest.raises(SwapOutputNotFinalizedError): + await dex.get_swap_output("9field") + + +async def test_async_swap_inputs_and_handle(astub): + dex = AsyncShieldSwap(astub) + call = await dex.swap(pool_key="5field", token_in_id="1field", + amount_in=10**9, nonce=123, expected_out=1_000_000, + token_in_program="tok.aleo") + fn, args = astub.last_call + assert fn == "swap" and len(args) == 12 + assert args[0] == RECORD_TEXT + assert args[1] == BLINDING_FACTOR_0 and args[2] == BLINDED_ADDRESS_0 + assert args[7] == f"{MIN_SQRT_PRICE}u128" + assert args[9] == "1100u32" + + handle = await call.transact() + assert handle.swap_id == "88field" + assert handle.transaction_id == "at1asynctx" + assert astub.submitted + + +async def test_async_delegate_waits_and_recovers(astub): + dex = AsyncShieldSwap(astub) + call = await dex.swap(pool_key="5field", token_in_id="1field", + amount_in=10**9, expected_out=1_000_000, + token_in_program="tok.aleo") + handle = await call.delegate() + assert handle.transaction_id == "at1delegated" + assert handle.swap_id == "88field" + assert astub.waited == ["at1delegated"] diff --git a/shield-swap-sdk/tests/test_blinding.py b/shield-swap-sdk/tests/test_blinding.py new file mode 100644 index 00000000..e40399b2 --- /dev/null +++ b/shield-swap-sdk/tests/test_blinding.py @@ -0,0 +1,92 @@ +"""Blinded identity derivation vs golden vectors from the TS SDK +(test/utils/blinding/identity.test.ts), which pin the reference derivation in +amm-v3-tests. The program's verify_blinded_address re-computes this hash and +rejects any deviation — the vectors must reproduce exactly.""" +import pytest + +from aleo_shield_swap.derivations import ( + BlindedIdentity, + derive_blinded_address, + derive_blinding_factor, + next_blinded_identity, +) + +VIEW_KEY_SCALAR = "334926304971763782347498121479281870911723639068413954564748091722770623877scalar" +SIGNER = "aleo1rhgdu77hgyqd3xjj8ucu3jj9r2krwz6mnzyd80gncr5fxcwlh5rsvzp9px" +VECTORS = [ + (0, "4588552248780721950435785476596782217652350429588181106944985529417784595808field", + "aleo1tucdl48jvu54emu9atq3vf0rslwtdpze83zcc2jrc8zxema0r5gq3zd76l"), + (1, "6996211042158127437642182917952771252908546914090630418129936449807650494378field", + "aleo17gc56avc2x3dwj3mjazag8szl5skm8y4u5h6ep37kvl34cynrqyqm0cuj8"), + (7, "4426391170839722244039367865632426610408126795108463201618230895243256084792field", + "aleo1jjq9qtr2uv86pans7f7v3tgcesg0autqhhu2cp2eecfxhtv4acgskyz80k"), +] + + +@pytest.mark.parametrize("counter,bf,ba", VECTORS) +def test_golden_vectors(counter, bf, ba): + assert derive_blinding_factor(VIEW_KEY_SCALAR, counter) == bf + assert derive_blinded_address(bf, SIGNER) == ba + + +def test_deterministic(): + a = derive_blinding_factor(VIEW_KEY_SCALAR, 0) + b = derive_blinding_factor(VIEW_KEY_SCALAR, 0) + assert a == b + assert derive_blinded_address(a, SIGNER) == derive_blinded_address(b, SIGNER) + + +class _Mapping: + def __init__(self, used): + self.used = used + + def get(self, key): + return "true" if key in self.used else None + + +class _StubAleo: + network_name = "testnet" + + def __init__(self, used): + mapping = _Mapping(used) + + class _Prog: + def mapping(self, name): + assert name == "used_blinded_addresses" + return mapping + + class _Programs: + def get(self, pid): + return _Prog() + + self.programs = _Programs() + + +class _StubAccount: + """Account stub carrying the vector view-key scalar + signer address.""" + + class _VK: + def to_scalar(self): + return VIEW_KEY_SCALAR + + view_key = _VK() + address = SIGNER + + +def test_next_blinded_identity_returns_first_free(): + ident = next_blinded_identity(_StubAleo(used=set()), _StubAccount()) + assert ident == BlindedIdentity(0, VECTORS[0][1], VECTORS[0][2]) + + +def test_next_blinded_identity_skips_used(): + used = {VECTORS[0][2], VECTORS[1][2]} + ident = next_blinded_identity(_StubAleo(used=used), _StubAccount()) + assert ident.counter == 2 + assert ident.blinded_address not in used + + +def test_next_blinded_identity_max_scan(): + # Counters 0 and 1 are both used and max_scan=2 stops the scan there. + used = {VECTORS[0][2], VECTORS[1][2]} + with pytest.raises(ValueError, match="No unused blinded address"): + next_blinded_identity(_StubAleo(used=used), _StubAccount(), max_scan=2) diff --git a/shield-swap-sdk/tests/test_claim.py b/shield-swap-sdk/tests/test_claim.py new file mode 100644 index 00000000..25438ee1 --- /dev/null +++ b/shield-swap-sdk/tests/test_claim.py @@ -0,0 +1,58 @@ +"""claim_swap_output() — input order per TS claimSwapOutput.ts: +[blinding_factor, blinded_address, swap_id, token_in, token_out, + amount_out u128, amount_remaining u128]""" +import pytest + +from aleo_shield_swap.client import ShieldSwap +from aleo_shield_swap.errors import SwapOutputNotFinalizedError +from aleo_shield_swap.types import ClaimResult, SwapHandle + +from .conftest import POOL_TEXT, SLOT_TEXT, StubAleo + +SWAP_OUTPUT_TEXT = ( + "{ recipient: 3field, caller: 4field, token_in: 1field, token_out: 2field, " + "amount_out: 990000u128, amount_remaining: 0u128, token_in_1: 1field, " + "amount_remaining_1: 0u128, token_in_2: 1field, amount_remaining_2: 0u128 }" +) + + +def _handle(**over): + base = dict(swap_id="77field", blinding_factor="11field", blinded_address="aleo1blinded", + token_in_id="1field", token_out_id="2field", pool_key="5field", + amount_in=10**9, transaction_id="at1req", program="shield_swap_v3.aleo") + base.update(over) + return SwapHandle(**base) + + +def _stub(swap_outputs): + return StubAleo(mappings={ + "pools": {"5field": POOL_TEXT}, + "slots": {"5field": SLOT_TEXT}, + "swap_outputs": swap_outputs, + }) + + +def test_claim_builds_exact_inputs_and_result(): + stub = _stub({"77field": SWAP_OUTPUT_TEXT}) + dex = ShieldSwap(stub) + result = dex.claim_swap_output(_handle()).transact() + fn, args = stub.last_call + assert fn == "claim_swap_output" + assert args == ["11field", "aleo1blinded", "77field", + "1field", "2field", "990000u128", "0u128"] + assert result == ClaimResult("at1stubtx", 990000, 0) + + +def test_claim_not_finalized_raises_before_any_call(): + stub = _stub({}) + with pytest.raises(SwapOutputNotFinalizedError): + ShieldSwap(stub).claim_swap_output(_handle()) + assert stub.last_call is None # no transaction was prepared + + +def test_claim_incomplete_handle_raises(): + stub = _stub({"77field": SWAP_OUTPUT_TEXT}) + with pytest.raises(ValueError, match="swap_id"): + ShieldSwap(stub).claim_swap_output(_handle(swap_id=None)) + with pytest.raises(ValueError, match="blinding_factor"): + ShieldSwap(stub).claim_swap_output(_handle(blinding_factor=None)) diff --git a/shield-swap-sdk/tests/test_client_reads.py b/shield-swap-sdk/tests/test_client_reads.py new file mode 100644 index 00000000..9388ac0f --- /dev/null +++ b/shield-swap-sdk/tests/test_client_reads.py @@ -0,0 +1,74 @@ +import pytest + +from aleo_shield_swap.client import ShieldSwap +from aleo_shield_swap.errors import ( + PoolNotFoundError, + PoolNotInitializedError, + SwapOutputNotFinalizedError, +) +from aleo_shield_swap.types import SwapHandle + +from .conftest import StubAleo + + +def test_get_slot_returns_slotview(stub_aleo): + dex = ShieldSwap(stub_aleo) + slot = dex.get_slot("5field") + assert slot.tick == 4055 and slot.tick_spacing == 60 + + +def test_get_pool_returns_poolstate(stub_aleo): + pool = ShieldSwap(stub_aleo).get_pool("5field") + assert pool.token0 == "1field" and pool.fee == 3000 + assert pool.scale0 == 10**9 + + +def test_missing_pool_raises(stub_aleo): + with pytest.raises(PoolNotFoundError): + ShieldSwap(stub_aleo).get_pool("9field") + + +def test_get_swap_output_absent_raises(stub_aleo): + with pytest.raises(SwapOutputNotFinalizedError): + ShieldSwap(stub_aleo).get_swap_output("9field") + + +def test_get_swap_output_accepts_handle(stub_aleo): + handle = SwapHandle(swap_id="9field", blinding_factor=None, blinded_address=None, + token_in_id="1field", token_out_id="2field", pool_key="5field", + amount_in=1, transaction_id="at1x", program="shield_swap_v3.aleo") + with pytest.raises(SwapOutputNotFinalizedError): # resolved to the id + ShieldSwap(stub_aleo).get_swap_output(handle) + with pytest.raises(ValueError, match="no swap_id"): + ShieldSwap(stub_aleo).get_swap_output( + SwapHandle(swap_id=None, blinding_factor=None, blinded_address=None, + token_in_id="1field", token_out_id="2field", pool_key="5field", + amount_in=1, transaction_id="at1x", program="shield_swap_v3.aleo")) + + +def test_uninitialized_pool_distinct_from_missing(stub_aleo): + from .conftest import POOL_TEXT, StubAleo + aleo = StubAleo(mappings={"pools": {"5field": POOL_TEXT}, "slots": {}}) + with pytest.raises(PoolNotInitializedError): + ShieldSwap(aleo).get_slot("5field") + with pytest.raises(PoolNotFoundError): + ShieldSwap(aleo).get_slot("6field") + + +def test_quoted_mapping_values_are_unwrapped(): + aleo = StubAleo(mappings={"initialized_pools": {"5field": '"true"'}}) + assert ShieldSwap(aleo).is_pool_initialized("5field") is True + assert ShieldSwap(aleo).is_pool_initialized("6field") is False + + +def test_derive_passthroughs(stub_aleo): + dex = ShieldSwap(stub_aleo) + key = dex.derive_pool_key("1234567890123456789field", "9876543210987654321field", 3000) + assert key == ("50041712585455958488907677199499969829064388375192540321564089" + "29642095152812field") + + +def test_get_private_balances(stub_aleo): + dex = ShieldSwap(stub_aleo) + out = dex.get_private_balances(["tok.aleo"]) + assert out == {"tok.aleo": 2_000_000_000} diff --git a/shield-swap-sdk/tests/test_core.py b/shield-swap-sdk/tests/test_core.py new file mode 100644 index 00000000..e3105e91 --- /dev/null +++ b/shield-swap-sdk/tests/test_core.py @@ -0,0 +1,129 @@ +import pytest + +from aleo_shield_swap._core import ( + generate_field_nonce, + generate_swap_nonce, + parse_token_record_info, + resolve_imports, + resolve_swap_params, + select_token_record, +) +from aleo_shield_swap.errors import InsufficientRecordsError +from aleo_shield_swap.tick_math import MAX_SQRT_PRICE, MIN_SQRT_PRICE, Q64 + + +class _Pool: # duck-typed: only the fields resolve_swap_params reads + token0 = "1field" + token1 = "2field" + scale0 = 10**9 + scale1 = 1 + + +class _Slot: + sqrt_price = Q64 # price 1.0 in normalized units + + +def test_direction_and_spot_estimate(): + r = resolve_swap_params(pool=_Pool(), slot=_Slot(), token_in_id="1field", + amount_in=10**9, slippage_bps=50) + assert r.zero_for_one is True and r.token_out_id == "2field" + # spot: norm_in=1, price 1.0, scale_out=1 → expected 1; 1*9950//10000 == 0 + assert r.amount_out_min == 0 + assert r.sqrt_price_limit == MIN_SQRT_PRICE + + +def test_explicit_quote_and_reverse_direction(): + r = resolve_swap_params(pool=_Pool(), slot=_Slot(), token_in_id="2field", + amount_in=5, slippage_bps=100, expected_out=10**9) + assert r.zero_for_one is False and r.token_out_id == "1field" + assert r.amount_out_min == 10**9 * 9900 // 10000 + assert r.sqrt_price_limit == MAX_SQRT_PRICE + + +def test_rejections(): + with pytest.raises(ValueError, match="dust"): + resolve_swap_params(pool=_Pool(), slot=_Slot(), token_in_id="1field", + amount_in=10**9 + 1, slippage_bps=50) + with pytest.raises(ValueError, match="not in this pool"): + resolve_swap_params(pool=_Pool(), slot=_Slot(), token_in_id="9field", + amount_in=10**9, slippage_bps=50) + with pytest.raises(ValueError, match="slippage_bps"): + resolve_swap_params(pool=_Pool(), slot=_Slot(), token_in_id="1field", + amount_in=10**9, slippage_bps=10_001) + with pytest.raises(ValueError, match="sqrt_price_limit"): + resolve_swap_params(pool=_Pool(), slot=_Slot(), token_in_id="1field", + amount_in=10**9, slippage_bps=0, + sqrt_price_limit=MIN_SQRT_PRICE - 1) + + +def test_nonces(): + assert 0 <= generate_swap_nonce() < 2**64 + n = generate_field_nonce() + assert n.endswith("field") and int(n.removesuffix("field")) < 2**248 + + +def test_parse_token_record_info(): + assert parse_token_record_info( + "{ owner: aleo1me.private, amount: 5000u128.private, _nonce: 1group.public }" + ) == {"amount": 5000} + info = parse_token_record_info( + "{ owner: aleo1me.private, amount: 7u128.private, token_id: 9field.private, " + "_nonce: 1group.public }") + assert info == {"amount": 7, "token_id": "9field"} + assert parse_token_record_info("{ owner: aleo1me.private, _nonce: 1group.public }") is None + assert parse_token_record_info("garbage {") is None + + +class _Programs: + def __init__(self): + self.fetches = 0 + + def get(self, pid): + self.fetches += 1 + prog = type("P", (), {"source": f"program {pid};"})() + return prog + + +class _Aleo: + network_name = "testnet" + + def __init__(self, records=()): + self.programs = _Programs() + recs = list(records) + + class _Provider: + def find(self, account=None, *, program=None, unspent=True, **_): + return recs + + self.record_provider = _Provider() + + +def test_resolve_imports_memoizes_and_overrides(): + aleo = _Aleo() + out = resolve_imports(aleo, ["a.aleo", "b.aleo", "a.aleo"]) + assert set(out) == {"a.aleo", "b.aleo"} and aleo.programs.fetches == 2 + out2 = resolve_imports(aleo, ["a.aleo"], overrides={"a.aleo": "override"}) + assert out2["a.aleo"] == "override" + resolve_imports(aleo, ["b.aleo"]) # cached — no new fetch + assert aleo.programs.fetches == 2 + + +def _rec(text): + return {"record_plaintext": text} + + +def test_select_token_record_picks_smallest_covering(): + small = _rec("{ owner: aleo1me.private, amount: 500u128.private, _nonce: 1group.public }") + big = _rec("{ owner: aleo1me.private, amount: 9000u128.private, _nonce: 2group.public }") + chosen = select_token_record(_Aleo([big, small]), program="tok.aleo", min_amount=400) + assert "500u128" in chosen # smallest covering record wins + + +def test_select_token_record_filters_token_id_and_raises(): + other = _rec("{ owner: aleo1me.private, amount: 9000u128.private, " + "token_id: 8field.private, _nonce: 2group.public }") + with pytest.raises(InsufficientRecordsError): + select_token_record(_Aleo([other]), program="tok.aleo", + min_amount=400, token_id="9field") + with pytest.raises(InsufficientRecordsError): + select_token_record(_Aleo([]), program="tok.aleo", min_amount=1) diff --git a/shield-swap-sdk/tests/test_derivations.py b/shield-swap-sdk/tests/test_derivations.py new file mode 100644 index 00000000..bbcf3681 --- /dev/null +++ b/shield-swap-sdk/tests/test_derivations.py @@ -0,0 +1,37 @@ +"""Pool/tick key derivations vs vectors from the TS SDK's keys.test.ts.""" +import pytest + +from aleo_shield_swap.derivations import derive_pool_key, derive_tick_key + +# Vectors copied verbatim from aleo-viem packages/shield-swap/test/keys.test.ts +TOKEN0 = "1234567890123456789field" +TOKEN1 = "9876543210987654321field" +POOL_KEY = "5004171258545595848890767719949996982906438837519254032156408929642095152812field" +TICK_KEY = "1831124990376748452345532981319547440239544385602656748610276036461414053413field" + + +def test_pool_key_vector(): + assert derive_pool_key(TOKEN0, TOKEN1, 3000) == POOL_KEY + + +def test_pool_key_is_order_independent(): + assert derive_pool_key(TOKEN1, TOKEN0, 3000) == POOL_KEY + + +def test_pool_key_accepts_bare_literals(): + assert derive_pool_key(TOKEN0.removesuffix("field"), + TOKEN1.removesuffix("field"), 3000) == POOL_KEY + + +def test_pool_key_fee_matters(): + assert derive_pool_key(TOKEN0, TOKEN1, 500) != POOL_KEY + with pytest.raises(ValueError): + derive_pool_key(TOKEN0, TOKEN1, 2**16) + + +def test_tick_key_vector(): + assert derive_tick_key(POOL_KEY, -600) == TICK_KEY + assert derive_tick_key(POOL_KEY.removesuffix("field"), -600) == TICK_KEY + assert derive_tick_key(POOL_KEY, 600) != TICK_KEY + with pytest.raises(ValueError): + derive_tick_key(POOL_KEY, 2**31) diff --git a/shield-swap-sdk/tests/test_errors.py b/shield-swap-sdk/tests/test_errors.py new file mode 100644 index 00000000..a04bb0fb --- /dev/null +++ b/shield-swap-sdk/tests/test_errors.py @@ -0,0 +1,27 @@ +from aleo import AleoError + +from aleo_shield_swap.errors import ( + DexApiError, + InsufficientRecordsError, + InvalidFeeTierError, + PoolNotFoundError, + PoolNotInitializedError, + ShieldSwapError, + SwapOutputNotFinalizedError, +) + + +def test_hierarchy(): + for exc in (SwapOutputNotFinalizedError("1field"), PoolNotFoundError("x"), + PoolNotInitializedError("x"), InsufficientRecordsError("x"), + InvalidFeeTierError("x"), DexApiError(500, "boom")): + assert isinstance(exc, ShieldSwapError) + assert isinstance(exc, AleoError) + + +def test_messages(): + e = SwapOutputNotFinalizedError("42field") + assert "42field" in str(e) and "finalized" in str(e) + assert e.swap_id == "42field" + d = DexApiError(404, "not found") + assert d.status == 404 and d.body == "not found" diff --git a/shield-swap-sdk/tests/test_generated.py b/shield-swap-sdk/tests/test_generated.py new file mode 100644 index 00000000..1fc01f90 --- /dev/null +++ b/shield-swap-sdk/tests/test_generated.py @@ -0,0 +1,42 @@ +"""Sanity tests for the committed aleo.codegen output (_generated.py).""" +from aleo_shield_swap import _generated as g + + +def test_program_id(): + assert g.PROGRAM_ID == "shield_swap_v3.aleo" + + +def test_slot_decode(): + slot = g.Slot.from_plaintext( + "{ tick: 4055i32, tick_spacing: 60i32, sqrt_price: 22526123159817891330747538u128, " + "fee_protocol: 0u8, liquidity: 183051202759u128, fee_growth_global0_x_64: 0u128, " + "fee_growth_global1_x_64: 0u128, fee_residual0_x_64: 0u128, fee_residual1_x_64: 0u128, " + "max_liquidity_per_tick: 1000u128, protocol_fees0: 0u128, protocol_fees1: 0u128, " + "next_init_below: 3960i32, next_init_above: 4080i32 }") + assert slot.tick == 4055 and slot.tick_spacing == 60 + assert slot.sqrt_price == 22526123159817891330747538 + + +def test_mapping_decoder_table_covers_key_mappings(): + for name in ("slots", "pools", "swap_outputs", "fee_tiers", "used_blinded_addresses"): + assert name in g.MAPPING_VALUE_DECODERS, name + + +def test_abi_constant_carries_key_types(): + assert g.ABI["program"] == "shield_swap_v3.aleo" + slots = next(m for m in g.ABI["mappings"] if m["name"] == "slots") + assert slots["key"] == {"Primitive": "Field"} + + +def test_mint_request_encodes(): + req_kwargs = {} + for f in g.MintPositionRequest.__dataclass_fields__.values(): + if f.type is bool: + req_kwargs[f.name] = True + elif f.type is int: + req_kwargs[f.name] = 1 + else: + req_kwargs[f.name] = "1field" + text = g.MintPositionRequest(**req_kwargs).to_plaintext() + assert text.startswith("{ ") and text.endswith(" }") + assert g.MintPositionRequest.from_plaintext(text) == g.MintPositionRequest(**req_kwargs) diff --git a/shield-swap-sdk/tests/test_liquidity.py b/shield-swap-sdk/tests/test_liquidity.py new file mode 100644 index 00000000..b71f404a --- /dev/null +++ b/shield-swap-sdk/tests/test_liquidity.py @@ -0,0 +1,141 @@ +"""Liquidity verbs — exact input orders per the TS actions: +create_pool: [token0, token1, fee u16, sqrt_price u128, spacing u32, tick i32] +mint: [nonce field, record0, record1, recipient, MintPositionRequest, token0, token1] +increase: [position, record0, record1, a0 u128, a1 u128, a0min u128, a1min u128, + token0, token1, lo_hint i32, hi_hint i32] +decrease: [position, liquidity u128, a0min u128, a1min u128] +collect: [position, a0req u128, a1req u128, token0, token1, recipient] +burn: [position]""" +import pytest + +from aleo_shield_swap.client import ShieldSwap +from aleo_shield_swap.errors import InsufficientRecordsError, InvalidFeeTierError +from aleo_shield_swap.tick_math import get_sqrt_price_at_tick + +from .conftest import POOL_TEXT, SIGNER, SLOT_TEXT, StubAleo + +POSITION_TEXT = ("{ owner: aleo1me.private, token_id: 42field.private, " + "token0_id: 1field.private, token1_id: 2field.private, " + "pool: 5field.private, tick_lower: -4080i32.private, " + "tick_upper: 4080i32.private, liquidity: 500u128.private, " + "_nonce: 3group.public }") + +TOKEN0_RECORD = "{ owner: aleo1me.private, amount: 2000000000u128.private, _nonce: 7group.public }" + + +def _stub(**over): + mappings = { + "pools": {"5field": POOL_TEXT}, + "slots": {"5field": SLOT_TEXT}, + "fee_tiers": {"3000u16": "true"}, + "fee_to_tick_spacing": {"3000u16": "60u32"}, + "used_blinded_addresses": {}, + } + mappings.update(over.pop("mappings", {})) + records = over.pop("records", [{"record_plaintext": TOKEN0_RECORD}, + {"record_plaintext": POSITION_TEXT}]) + return StubAleo(mappings=mappings, records=records) + + +def test_create_pool_inputs_and_validation(): + stub = _stub() + dex = ShieldSwap(stub) + result = dex.create_pool(token0_id="1field", token1_id="2field", + fee=3000, initial_tick=0).transact() + fn, args = stub.last_call + assert fn == "create_pool" + assert args == ["1field", "2field", "3000u16", + f"{get_sqrt_price_at_tick(0)}u128", "60u32", "0i32"] + assert result.transaction_id == "at1stubtx" + + with pytest.raises(InvalidFeeTierError): + dex.create_pool(token0_id="1field", token1_id="2field", + fee=123, initial_tick=0) + assert stub.last_call[0] == "create_pool" # no new call was prepared + + +def test_create_pool_rejects_disabled_fee_tier(): + # Registered-then-disabled tier: present in the mapping with value false. + stub = _stub(mappings={"fee_tiers": {"3000u16": "false"}}) + with pytest.raises(InvalidFeeTierError): + ShieldSwap(stub).create_pool(token0_id="1field", token1_id="2field", + fee=3000, initial_tick=0) + + +def test_mint_inputs_rounding_and_request(): + stub = _stub() + dex = ShieldSwap(stub) + dex.mint(pool_key="5field", tick_lower=-4055, tick_upper=4055, + amount0_desired=10**9, amount1_desired=100, + token0_program="tok0.aleo", token1_program="tok1.aleo", + nonce="9field") + fn, args = stub.last_call + assert fn == "mint" + assert len(args) == 7 + assert args[0] == "9field" + assert args[1] == TOKEN0_RECORD and args[2] == TOKEN0_RECORD + assert args[3] == SIGNER # recipient defaults to signer + # ticks rounded to spacing 60: -4055 -> -4080, 4055 -> 4020 + assert "tick_lower: -4080i32" in args[4] + assert "tick_upper: 4020i32" in args[4] + assert "amount0_desired: 1000000000u128" in args[4] + # slot neighbors: below=3960, above=4080; lower hint for -4080 (< tick) is 3960? + # pick_insert_hint(-4080 <= 4055) -> next_init_below = 3960 + assert "tick_lower_hint: 3960i32" in args[4] + assert args[5] == "1field" and args[6] == "2field" + + +def test_mint_default_nonce_is_generated(): + stub = _stub() + ShieldSwap(stub).mint(pool_key="5field", tick_lower=-4080, tick_upper=4080, + amount0_desired=10**9, amount1_desired=100, + token0_program="tok0.aleo", token1_program="tok1.aleo") + _, args = stub.last_call + assert args[0].endswith("field") and args[0] != "9field" # random field nonce + + +def test_mint_empty_range_raises(): + dex = ShieldSwap(_stub()) + with pytest.raises(ValueError, match="Empty tick range"): + dex.mint(pool_key="5field", tick_lower=10, tick_upper=50, # both round to 0 + amount0_desired=1, amount1_desired=1, + token0_program="tok0.aleo", token1_program="tok1.aleo") + + +def test_increase_liquidity_inputs(): + stub = _stub() + ShieldSwap(stub).increase_liquidity( + pool_key="5field", amount0_desired=10**9, amount1_desired=100, + token0_program="tok0.aleo", token1_program="tok1.aleo") + fn, args = stub.last_call + assert fn == "increase_liquidity" + assert args[0] == POSITION_TEXT # auto-selected by pool + assert args[3] == f"{10**9}u128" and args[4] == "100u128" + assert args[5] == "0u128" and args[6] == "0u128" + assert args[7] == "1field" and args[8] == "2field" + assert args[9].endswith("i32") and args[10].endswith("i32") + assert len(args) == 11 + + +def test_decrease_collect_burn_inputs(): + stub = _stub() + dex = ShieldSwap(stub) + dex.decrease_liquidity(pool_key="5field", liquidity_to_remove=500) + assert stub.last_call == ("decrease_liquidity", + [POSITION_TEXT, "500u128", "0u128", "0u128"]) + + result = dex.collect(pool_key="5field", amount0_requested=7, + amount1_requested=8).transact() + fn, args = stub.last_call + assert (fn, args) == ("collect", [POSITION_TEXT, "7u128", "8u128", + "1field", "2field", SIGNER]) + assert result.position_token_id is None # collect re-issues privately + + dex.burn(pool_key="5field") + assert stub.last_call == ("burn", [POSITION_TEXT]) + + +def test_position_auto_select_requires_matching_pool(): + stub = _stub(records=[{"record_plaintext": TOKEN0_RECORD}]) # no position + with pytest.raises(InsufficientRecordsError, match="PositionNFT"): + ShieldSwap(stub).burn(pool_key="5field") diff --git a/shield-swap-sdk/tests/test_mcp.py b/shield-swap-sdk/tests/test_mcp.py new file mode 100644 index 00000000..d81d04c6 --- /dev/null +++ b/shield-swap-sdk/tests/test_mcp.py @@ -0,0 +1,31 @@ +import json + +import pytest + +mcp = pytest.importorskip("mcp") + +from aleo_shield_swap.agent import shield_swap_tools # noqa: E402 +from aleo_shield_swap.client import ShieldSwap # noqa: E402 +from aleo_shield_swap.mcp import build_server, call_tool, tool_definitions # noqa: E402 + + +def test_tool_definitions_carry_exact_schemas(): + tools = tool_definitions() + by_name = {t.name: t for t in tools} + expected = {t["name"]: t for t in shield_swap_tools()} + assert set(by_name) == set(expected) + # The precise agent schema must survive — not FastMCP signature inference. + swap = by_name["swap"] + assert swap.inputSchema == expected["swap"]["input_schema"] + assert "pool_key" in swap.inputSchema["properties"] + assert "amount_in" in swap.inputSchema["required"] + + +def test_build_server_constructs(): + assert build_server(dex=None).name == "shield-swap" + + +async def test_call_tool_dispatches_and_serializes(stub_aleo): + out = await call_tool(ShieldSwap(stub_aleo), "get_slot", {"pool_key": "5field"}) + assert out[0].type == "text" + assert json.loads(out[0].text)["tick"] == 4055 diff --git a/shield-swap-sdk/tests/test_package.py b/shield-swap-sdk/tests/test_package.py new file mode 100644 index 00000000..fa78ce38 --- /dev/null +++ b/shield-swap-sdk/tests/test_package.py @@ -0,0 +1,5 @@ +import aleo_shield_swap + + +def test_version(): + assert aleo_shield_swap.__version__ == "0.2.0" diff --git a/shield-swap-sdk/tests/test_swap.py b/shield-swap-sdk/tests/test_swap.py new file mode 100644 index 00000000..8089fae9 --- /dev/null +++ b/shield-swap-sdk/tests/test_swap.py @@ -0,0 +1,95 @@ +"""swap() against the stubbed facade — asserts the exact positional input +list (order from the TS reference src/actions/swap/swap.ts): +[record, blinding_factor, blinded_address, pool_key, zero_for_one, + amount_in u128, amount_out_min u128, sqrt_price_limit u128, nonce u64, + deadline u32, token0, token1]""" +import pytest + +from aleo_shield_swap.client import ShieldSwap +from aleo_shield_swap.errors import InsufficientRecordsError +from aleo_shield_swap.tick_math import MIN_SQRT_PRICE +from aleo_shield_swap.types import SwapHandle + +from .conftest import ( + BLINDED_ADDRESS_0, + BLINDING_FACTOR_0, + POOL_TEXT, + RECORD_TEXT, + SLOT_TEXT, + StubAleo, +) + + +def _swap_call(stub_aleo, **over): + dex = ShieldSwap(stub_aleo) + kwargs = dict(pool_key="5field", token_in_id="1field", amount_in=10**9, + slippage_bps=50, nonce=123, token_in_program="tok.aleo", + expected_out=1_000_000) + kwargs.update(over) + return dex.swap(**kwargs) + + +def test_swap_builds_exact_inputs(stub_aleo): + call = _swap_call(stub_aleo) + fn, args = stub_aleo.last_call + assert fn == "swap" + assert args[0] == RECORD_TEXT # auto-selected record + assert args[1] == BLINDING_FACTOR_0 # counter-0 identity + assert args[2] == BLINDED_ADDRESS_0 + assert args[3] == "5field" + assert args[4] is True # zero_for_one + assert args[5] == f"{10**9}u128" + assert args[6] == f"{1_000_000 * 9950 // 10000}u128" # slippage applied + assert args[7] == f"{MIN_SQRT_PRICE}u128" # directional default + assert args[8] == "123u64" + assert args[9] == "1100u32" # height 1000 + 100 + assert args[10] == "1field" and args[11] == "2field" + assert len(args) == 12 + # Dynamic dispatch: the DEX program and the token wrapper program must be + # registered with the process before authorization. + assert "shield_swap_v3.aleo" in stub_aleo.registered_programs + assert "tok.aleo" in stub_aleo.registered_programs + + +def test_swap_transact_returns_complete_handle(stub_aleo): + handle = _swap_call(stub_aleo).transact() + assert isinstance(handle, SwapHandle) + assert handle.swap_id == "77field" # first field output + assert handle.transaction_id == "at1stubtx" + assert handle.blinding_factor == BLINDING_FACTOR_0 + assert handle.blinded_address == BLINDED_ADDRESS_0 + assert handle.token_out_id == "2field" + assert handle.amount_in == 10**9 + assert stub_aleo.submitted # broadcast happened + assert SwapHandle.from_json(handle.to_json()) == handle + + +def test_swap_delegate_recovers_swap_id_from_confirmed_tx(stub_aleo): + handle = _swap_call(stub_aleo).delegate() + assert handle.transaction_id == "at1delegated" + assert handle.swap_id == "77field" # from decode_transition + assert stub_aleo.waited == ["at1delegated"] + + +def test_swap_simulate_passthrough(stub_aleo): + assert _swap_call(stub_aleo).simulate() == "simulated" + + +def test_swap_explicit_record_skips_selection(stub_aleo): + explicit = "{ owner: aleo1me.private, amount: 5000000000u128.private, _nonce: 9group.public }" + _swap_call(stub_aleo, token_record=explicit) + _, args = stub_aleo.last_call + assert args[0] == explicit + + +def test_swap_no_covering_record_raises(): + stub = StubAleo( + mappings={ + "pools": {"5field": POOL_TEXT}, + "slots": {"5field": SLOT_TEXT}, + "used_blinded_addresses": {}, + }, + records=[], + ) + with pytest.raises(InsufficientRecordsError): + _swap_call(stub) diff --git a/shield-swap-sdk/tests/test_tick_math.py b/shield-swap-sdk/tests/test_tick_math.py new file mode 100644 index 00000000..2c2497be --- /dev/null +++ b/shield-swap-sdk/tests/test_tick_math.py @@ -0,0 +1,47 @@ +import pytest + +from aleo_shield_swap.tick_math import ( + MAX_SQRT_PRICE, + MAX_TICK, + MIN_SQRT_PRICE, + MIN_TICK, + Q64, + dust_scale, + get_sqrt_price_at_tick, + round_tick_to_spacing, +) + + +def test_constants(): + assert Q64 == 9223372036854775808 == 2**63 + assert (MIN_TICK, MAX_TICK) == (-400000, 400000) + assert MIN_SQRT_PRICE == 19029805711 + assert MAX_SQRT_PRICE == 4470386772317930780047134862 + + +def test_sqrt_price_boundaries(): + assert get_sqrt_price_at_tick(0) == Q64 + assert get_sqrt_price_at_tick(MIN_TICK) == MIN_SQRT_PRICE + assert get_sqrt_price_at_tick(MAX_TICK) == MAX_SQRT_PRICE + with pytest.raises(ValueError): + get_sqrt_price_at_tick(MAX_TICK + 1) + with pytest.raises(ValueError): + get_sqrt_price_at_tick(MIN_TICK - 1) + + +def test_sqrt_price_symmetry(): + # positive ticks invert the negative-tick table entry + neg = get_sqrt_price_at_tick(-600) + pos = get_sqrt_price_at_tick(600) + assert pos == (Q64 * Q64) // neg + # monotonic: higher tick, higher price + assert get_sqrt_price_at_tick(600) > get_sqrt_price_at_tick(0) > neg + + +def test_rounding_and_dust(): + assert round_tick_to_spacing(-62215, 200) == -62400 + assert round_tick_to_spacing(199, 200) == 0 + assert round_tick_to_spacing(-1, 200) == -200 + assert dust_scale(18) == 10**9 + assert dust_scale(9) == 1 + assert dust_scale(6) == 1 diff --git a/shield-swap-sdk/tests/test_types.py b/shield-swap-sdk/tests/test_types.py new file mode 100644 index 00000000..11834e2b --- /dev/null +++ b/shield-swap-sdk/tests/test_types.py @@ -0,0 +1,37 @@ +from decimal import Decimal + +from aleo_shield_swap._generated import Slot +from aleo_shield_swap.tick_math import Q64 +from aleo_shield_swap.types import SlotView, SwapHandle + + +def _slot(**over): + base = dict(tick=4055, tick_spacing=60, sqrt_price=Q64, fee_protocol=0, + liquidity=0, fee_growth_global0_x_64=0, fee_growth_global1_x_64=0, + fee_residual0_x_64=0, fee_residual1_x_64=0, max_liquidity_per_tick=0, + protocol_fees0=0, protocol_fees1=0, next_init_below=0, next_init_above=0) + base.update(over) + return Slot(**base) + + +def test_swap_handle_json_roundtrip(): + h = SwapHandle(swap_id="1field", blinding_factor="2field", blinded_address="aleo1x", + token_in_id="3field", token_out_id="4field", pool_key="5field", + amount_in=10**18, transaction_id="at1abc", program="shield_swap_v3.aleo") + assert SwapHandle.from_json(h.to_json()) == h + + +def test_slot_price_at_q64_is_one(): + v = SlotView(_slot()) + assert v.price(9, 9) == Decimal(1) + assert v.price(6, 6) == Decimal(1) # equal decimals cancel + assert v.price(18, 6) == Decimal(1000) # norm-capped: min(18,9)-min(6,9) = 3 + assert v.tick == 4055 # attribute delegation + assert v.raw is v._slot + + +def test_tick_range_alignment(): + v = SlotView(_slot(tick=4055, tick_spacing=60)) + lo, hi = v.tick_range(10) + assert lo % 60 == 0 and hi % 60 == 0 + assert lo < 4055 < hi