From 4c1e773b1b150931aeab6d5ead044737490ed6bb Mon Sep 17 00:00:00 2001 From: Zizou <111426680+zizou0x@users.noreply.github.com> Date: Mon, 17 Mar 2025 13:39:05 +0100 Subject: [PATCH] feat: add Pancakeswap v3 Substreams module (#178) * feat: Add Pancakeswap V3 Substreams module At this point it's just hard copy of Uniswap V3. It will be adapted in the following commits to make reviewing easier. * refactor: adapt uniswapv3 module logic for pancakeswap v3 The main change is how they handle protocol fees. Protocol fees are set by default depending on the fee of the pool. * refactor: use new protobuf structs The "EntityChanges" got deprecated in favor of the hybrid messages. This commit makes PancakeswapV3 module use the new structs. * fix: set correct factory address --------- Co-authored-by: zizou <111426680+flopell@users.noreply.github.com> Co-authored-by: Louise Poole --- substreams/Cargo.lock | 20 + substreams/Cargo.toml | 1 + substreams/ethereum-pancakeswap-v3/Cargo.toml | 30 + substreams/ethereum-pancakeswap-v3/Makefile | 2 + .../ethereum-pancakeswap-v3/abi/Factory.json | 300 + .../ethereum-pancakeswap-v3/abi/Pool.json | 739 +++ .../ethereum-pancakeswap-v3/buf.gen.yaml | 12 + substreams/ethereum-pancakeswap-v3/build.rs | 12 + .../ethereum-pancakeswap-v3.yaml | 125 + .../proto/v1/pancakeswap.proto | 179 + .../rust-toolchain.toml | 4 + .../src/abi/factory.rs | 2157 +++++++ .../ethereum-pancakeswap-v3/src/abi/mod.rs | 4 + .../ethereum-pancakeswap-v3/src/abi/pool.rs | 5168 +++++++++++++++++ substreams/ethereum-pancakeswap-v3/src/lib.rs | 7 + .../src/modules/1_map_pool_created.rs | 115 + .../src/modules/2_store_pools.rs | 36 + .../src/modules/3_map_events.rs | 195 + .../4_map_and_store_balance_changes.rs | 163 + .../src/modules/4_map_and_store_liquidity.rs | 137 + .../src/modules/4_map_and_store_ticks.rs | 91 + .../src/modules/5_map_protocol_changes.rs | 287 + .../src/modules/mod.rs | 61 + .../ethereum-pancakeswap-v3/src/pb/mod.rs | 8 + .../src/pb/pancakeswap.v3.rs | 302 + substreams/rustfmt.toml | 1 + 26 files changed, 10156 insertions(+) create mode 100644 substreams/ethereum-pancakeswap-v3/Cargo.toml create mode 100644 substreams/ethereum-pancakeswap-v3/Makefile create mode 100644 substreams/ethereum-pancakeswap-v3/abi/Factory.json create mode 100644 substreams/ethereum-pancakeswap-v3/abi/Pool.json create mode 100644 substreams/ethereum-pancakeswap-v3/buf.gen.yaml create mode 100644 substreams/ethereum-pancakeswap-v3/build.rs create mode 100644 substreams/ethereum-pancakeswap-v3/ethereum-pancakeswap-v3.yaml create mode 100644 substreams/ethereum-pancakeswap-v3/proto/v1/pancakeswap.proto create mode 100644 substreams/ethereum-pancakeswap-v3/rust-toolchain.toml create mode 100644 substreams/ethereum-pancakeswap-v3/src/abi/factory.rs create mode 100644 substreams/ethereum-pancakeswap-v3/src/abi/mod.rs create mode 100644 substreams/ethereum-pancakeswap-v3/src/abi/pool.rs create mode 100644 substreams/ethereum-pancakeswap-v3/src/lib.rs create mode 100644 substreams/ethereum-pancakeswap-v3/src/modules/1_map_pool_created.rs create mode 100644 substreams/ethereum-pancakeswap-v3/src/modules/2_store_pools.rs create mode 100644 substreams/ethereum-pancakeswap-v3/src/modules/3_map_events.rs create mode 100644 substreams/ethereum-pancakeswap-v3/src/modules/4_map_and_store_balance_changes.rs create mode 100644 substreams/ethereum-pancakeswap-v3/src/modules/4_map_and_store_liquidity.rs create mode 100644 substreams/ethereum-pancakeswap-v3/src/modules/4_map_and_store_ticks.rs create mode 100644 substreams/ethereum-pancakeswap-v3/src/modules/5_map_protocol_changes.rs create mode 100644 substreams/ethereum-pancakeswap-v3/src/modules/mod.rs create mode 100644 substreams/ethereum-pancakeswap-v3/src/pb/mod.rs create mode 100644 substreams/ethereum-pancakeswap-v3/src/pb/pancakeswap.v3.rs diff --git a/substreams/Cargo.lock b/substreams/Cargo.lock index 230d7db..799c22d 100644 --- a/substreams/Cargo.lock +++ b/substreams/Cargo.lock @@ -260,6 +260,26 @@ dependencies = [ "tycho-substreams 0.2.0 (git+https://github.com/propeller-heads/tycho-protocol-sdk.git?rev=b8aeaa3)", ] +[[package]] +name = "ethereum-pancakeswap-v3" +version = "0.1.0" +dependencies = [ + "anyhow", + "ethabi 18.0.0", + "getrandom", + "hex", + "hex-literal 0.4.1", + "itertools 0.13.0", + "num-bigint", + "prost 0.11.9", + "substreams", + "substreams-entity-change", + "substreams-ethereum", + "substreams-helper 0.0.2 (git+https://github.com/propeller-heads/tycho-protocol-sdk.git?rev=b8aeaa3)", + "tiny-keccak", + "tycho-substreams 0.2.0 (git+https://github.com/propeller-heads/tycho-protocol-sdk.git?rev=b8aeaa3)", +] + [[package]] name = "ethereum-sfrax" version = "0.1.0" diff --git a/substreams/Cargo.toml b/substreams/Cargo.toml index c0e3e97..583e627 100644 --- a/substreams/Cargo.toml +++ b/substreams/Cargo.toml @@ -7,6 +7,7 @@ members = [ "ethereum-ambient", "ethereum-uniswap-v2", "ethereum-uniswap-v3", + "ethereum-pancakeswap-v3", "ethereum-sfrax", "ethereum-sfraxeth", "ethereum-uniswap-v3-logs-only", diff --git a/substreams/ethereum-pancakeswap-v3/Cargo.toml b/substreams/ethereum-pancakeswap-v3/Cargo.toml new file mode 100644 index 0000000..d79a5f3 --- /dev/null +++ b/substreams/ethereum-pancakeswap-v3/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "ethereum-pancakeswap-v3" +version = "0.1.0" +edition = "2021" + +[lib] +name = "ethereum_pancakeswap_v3" +crate-type = ["cdylib"] + +[dependencies] +substreams = "0.5.22" +substreams-ethereum = "0.9.9" +prost = "0.11" +ethabi = "18.0.0" +anyhow = "1.0.75" +hex-literal = "0.4.1" +substreams-helper = { git = "https://github.com/propeller-heads/tycho-protocol-sdk.git", rev = "b8aeaa3" } +tycho-substreams = { git = "https://github.com/propeller-heads/tycho-protocol-sdk.git", rev = "b8aeaa3" } +num-bigint = "0.4.4" +hex = "0.4.3" +tiny-keccak = "2.0" +substreams-entity-change = "1.3" +itertools = "0.13.0" + +[target.wasm32-unknown-unknown.dependencies] +getrandom = { version = "0.2", features = ["custom"] } + +[build-dependencies] +anyhow = "1.0.75" +substreams-ethereum = "0.9.9" diff --git a/substreams/ethereum-pancakeswap-v3/Makefile b/substreams/ethereum-pancakeswap-v3/Makefile new file mode 100644 index 0000000..a6fcb34 --- /dev/null +++ b/substreams/ethereum-pancakeswap-v3/Makefile @@ -0,0 +1,2 @@ +build: + cargo build --target wasm32-unknown-unknown --profile substreams \ No newline at end of file diff --git a/substreams/ethereum-pancakeswap-v3/abi/Factory.json b/substreams/ethereum-pancakeswap-v3/abi/Factory.json new file mode 100644 index 0000000..aaaddbd --- /dev/null +++ b/substreams/ethereum-pancakeswap-v3/abi/Factory.json @@ -0,0 +1,300 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "_poolDeployer", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickSpacing", + "type": "int24" + } + ], + "name": "FeeAmountEnabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "indexed": false, + "internalType": "bool", + "name": "whitelistRequested", + "type": "bool" + }, + { + "indexed": false, + "internalType": "bool", + "name": "enabled", + "type": "bool" + } + ], + "name": "FeeAmountExtraInfoUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnerChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tickSpacing", + "type": "int24" + }, + { + "indexed": false, + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "PoolCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "lmPoolDeployer", + "type": "address" + } + ], + "name": "SetLmPoolDeployer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "verified", + "type": "bool" + } + ], + "name": "WhiteListAdded", + "type": "event" + }, + { + "inputs": [ + { "internalType": "address", "name": "pool", "type": "address" }, + { "internalType": "address", "name": "recipient", "type": "address" }, + { + "internalType": "uint128", + "name": "amount0Requested", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1Requested", + "type": "uint128" + } + ], + "name": "collectProtocol", + "outputs": [ + { "internalType": "uint128", "name": "amount0", "type": "uint128" }, + { "internalType": "uint128", "name": "amount1", "type": "uint128" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenA", "type": "address" }, + { "internalType": "address", "name": "tokenB", "type": "address" }, + { "internalType": "uint24", "name": "fee", "type": "uint24" } + ], + "name": "createPool", + "outputs": [ + { "internalType": "address", "name": "pool", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint24", "name": "fee", "type": "uint24" }, + { "internalType": "int24", "name": "tickSpacing", "type": "int24" } + ], + "name": "enableFeeAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint24", "name": "", "type": "uint24" }], + "name": "feeAmountTickSpacing", + "outputs": [{ "internalType": "int24", "name": "", "type": "int24" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint24", "name": "", "type": "uint24" }], + "name": "feeAmountTickSpacingExtraInfo", + "outputs": [ + { "internalType": "bool", "name": "whitelistRequested", "type": "bool" }, + { "internalType": "bool", "name": "enabled", "type": "bool" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "uint24", "name": "", "type": "uint24" } + ], + "name": "getPool", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lmPoolDeployer", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolDeployer", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint24", "name": "fee", "type": "uint24" }, + { "internalType": "bool", "name": "whitelistRequested", "type": "bool" }, + { "internalType": "bool", "name": "enabled", "type": "bool" } + ], + "name": "setFeeAmountExtraInfo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "pool", "type": "address" }, + { "internalType": "uint32", "name": "feeProtocol0", "type": "uint32" }, + { "internalType": "uint32", "name": "feeProtocol1", "type": "uint32" } + ], + "name": "setFeeProtocol", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "pool", "type": "address" }, + { "internalType": "address", "name": "lmPool", "type": "address" } + ], + "name": "setLmPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_lmPoolDeployer", + "type": "address" + } + ], + "name": "setLmPoolDeployer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_owner", "type": "address" } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "user", "type": "address" }, + { "internalType": "bool", "name": "verified", "type": "bool" } + ], + "name": "setWhiteListAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/substreams/ethereum-pancakeswap-v3/abi/Pool.json b/substreams/ethereum-pancakeswap-v3/abi/Pool.json new file mode 100644 index 0000000..e5f45c1 --- /dev/null +++ b/substreams/ethereum-pancakeswap-v3/abi/Pool.json @@ -0,0 +1,739 @@ +[ + { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "name": "Collect", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "name": "CollectProtocol", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "paid0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "paid1", + "type": "uint256" + } + ], + "name": "Flash", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "observationCardinalityNextOld", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "observationCardinalityNextNew", + "type": "uint16" + } + ], + "name": "IncreaseObservationCardinalityNext", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "name": "Initialize", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint32", + "name": "feeProtocol0Old", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "feeProtocol1Old", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "feeProtocol0New", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "feeProtocol1New", + "type": "uint32" + } + ], + "name": "SetFeeProtocol", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "SetLmPoolEvent", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "int256", + "name": "amount0", + "type": "int256" + }, + { + "indexed": false, + "internalType": "int256", + "name": "amount1", + "type": "int256" + }, + { + "indexed": false, + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tick", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "protocolFeesToken0", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "protocolFeesToken1", + "type": "uint128" + } + ], + "name": "Swap", + "type": "event" + }, + { + "inputs": [ + { "internalType": "int24", "name": "tickLower", "type": "int24" }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" }, + { "internalType": "uint128", "name": "amount", "type": "uint128" } + ], + "name": "burn", + "outputs": [ + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "recipient", "type": "address" }, + { "internalType": "int24", "name": "tickLower", "type": "int24" }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" }, + { + "internalType": "uint128", + "name": "amount0Requested", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1Requested", + "type": "uint128" + } + ], + "name": "collect", + "outputs": [ + { "internalType": "uint128", "name": "amount0", "type": "uint128" }, + { "internalType": "uint128", "name": "amount1", "type": "uint128" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "recipient", "type": "address" }, + { + "internalType": "uint128", + "name": "amount0Requested", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1Requested", + "type": "uint128" + } + ], + "name": "collectProtocol", + "outputs": [ + { "internalType": "uint128", "name": "amount0", "type": "uint128" }, + { "internalType": "uint128", "name": "amount1", "type": "uint128" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fee", + "outputs": [{ "internalType": "uint24", "name": "", "type": "uint24" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeGrowthGlobal0X128", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeGrowthGlobal1X128", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "recipient", "type": "address" }, + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" }, + { "internalType": "bytes", "name": "data", "type": "bytes" } + ], + "name": "flash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "observationCardinalityNext", + "type": "uint16" + } + ], + "name": "increaseObservationCardinalityNext", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint160", "name": "sqrtPriceX96", "type": "uint160" } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "liquidity", + "outputs": [{ "internalType": "uint128", "name": "", "type": "uint128" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lmPool", + "outputs": [ + { + "internalType": "contract IPancakeV3LmPool", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxLiquidityPerTick", + "outputs": [{ "internalType": "uint128", "name": "", "type": "uint128" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "recipient", "type": "address" }, + { "internalType": "int24", "name": "tickLower", "type": "int24" }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" }, + { "internalType": "uint128", "name": "amount", "type": "uint128" }, + { "internalType": "bytes", "name": "data", "type": "bytes" } + ], + "name": "mint", + "outputs": [ + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "observations", + "outputs": [ + { "internalType": "uint32", "name": "blockTimestamp", "type": "uint32" }, + { "internalType": "int56", "name": "tickCumulative", "type": "int56" }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityCumulativeX128", + "type": "uint160" + }, + { "internalType": "bool", "name": "initialized", "type": "bool" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint32[]", "name": "secondsAgos", "type": "uint32[]" } + ], + "name": "observe", + "outputs": [ + { + "internalType": "int56[]", + "name": "tickCumulatives", + "type": "int56[]" + }, + { + "internalType": "uint160[]", + "name": "secondsPerLiquidityCumulativeX128s", + "type": "uint160[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "name": "positions", + "outputs": [ + { "internalType": "uint128", "name": "liquidity", "type": "uint128" }, + { + "internalType": "uint256", + "name": "feeGrowthInside0LastX128", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside1LastX128", + "type": "uint256" + }, + { "internalType": "uint128", "name": "tokensOwed0", "type": "uint128" }, + { "internalType": "uint128", "name": "tokensOwed1", "type": "uint128" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolFees", + "outputs": [ + { "internalType": "uint128", "name": "token0", "type": "uint128" }, + { "internalType": "uint128", "name": "token1", "type": "uint128" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint32", "name": "feeProtocol0", "type": "uint32" }, + { "internalType": "uint32", "name": "feeProtocol1", "type": "uint32" } + ], + "name": "setFeeProtocol", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_lmPool", "type": "address" } + ], + "name": "setLmPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "slot0", + "outputs": [ + { "internalType": "uint160", "name": "sqrtPriceX96", "type": "uint160" }, + { "internalType": "int24", "name": "tick", "type": "int24" }, + { + "internalType": "uint16", + "name": "observationIndex", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "observationCardinality", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "observationCardinalityNext", + "type": "uint16" + }, + { "internalType": "uint32", "name": "feeProtocol", "type": "uint32" }, + { "internalType": "bool", "name": "unlocked", "type": "bool" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "int24", "name": "tickLower", "type": "int24" }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" } + ], + "name": "snapshotCumulativesInside", + "outputs": [ + { + "internalType": "int56", + "name": "tickCumulativeInside", + "type": "int56" + }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityInsideX128", + "type": "uint160" + }, + { "internalType": "uint32", "name": "secondsInside", "type": "uint32" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "recipient", "type": "address" }, + { "internalType": "bool", "name": "zeroForOne", "type": "bool" }, + { "internalType": "int256", "name": "amountSpecified", "type": "int256" }, + { + "internalType": "uint160", + "name": "sqrtPriceLimitX96", + "type": "uint160" + }, + { "internalType": "bytes", "name": "data", "type": "bytes" } + ], + "name": "swap", + "outputs": [ + { "internalType": "int256", "name": "amount0", "type": "int256" }, + { "internalType": "int256", "name": "amount1", "type": "int256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "int16", "name": "", "type": "int16" }], + "name": "tickBitmap", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tickSpacing", + "outputs": [{ "internalType": "int24", "name": "", "type": "int24" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "int24", "name": "", "type": "int24" }], + "name": "ticks", + "outputs": [ + { + "internalType": "uint128", + "name": "liquidityGross", + "type": "uint128" + }, + { "internalType": "int128", "name": "liquidityNet", "type": "int128" }, + { + "internalType": "uint256", + "name": "feeGrowthOutside0X128", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthOutside1X128", + "type": "uint256" + }, + { + "internalType": "int56", + "name": "tickCumulativeOutside", + "type": "int56" + }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityOutsideX128", + "type": "uint160" + }, + { "internalType": "uint32", "name": "secondsOutside", "type": "uint32" }, + { "internalType": "bool", "name": "initialized", "type": "bool" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token0", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token1", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + } +] diff --git a/substreams/ethereum-pancakeswap-v3/buf.gen.yaml b/substreams/ethereum-pancakeswap-v3/buf.gen.yaml new file mode 100644 index 0000000..d2e6544 --- /dev/null +++ b/substreams/ethereum-pancakeswap-v3/buf.gen.yaml @@ -0,0 +1,12 @@ + +version: v1 +plugins: +- plugin: buf.build/community/neoeinstein-prost:v0.2.2 + out: src/pb + opt: + - file_descriptor_set=false + +- plugin: buf.build/community/neoeinstein-prost-crate:v0.3.1 + out: src/pb + opt: + - no_features diff --git a/substreams/ethereum-pancakeswap-v3/build.rs b/substreams/ethereum-pancakeswap-v3/build.rs new file mode 100644 index 0000000..7992bb0 --- /dev/null +++ b/substreams/ethereum-pancakeswap-v3/build.rs @@ -0,0 +1,12 @@ +use anyhow::{Ok, Result}; +use substreams_ethereum::Abigen; + +fn main() -> Result<(), anyhow::Error> { + Abigen::new("Factory", "abi/Factory.json")? + .generate()? + .write_to_file("src/abi/factory.rs")?; + Abigen::new("Pool", "abi/Pool.json")? + .generate()? + .write_to_file("src/abi/pool.rs")?; + Ok(()) +} diff --git a/substreams/ethereum-pancakeswap-v3/ethereum-pancakeswap-v3.yaml b/substreams/ethereum-pancakeswap-v3/ethereum-pancakeswap-v3.yaml new file mode 100644 index 0000000..e8a8beb --- /dev/null +++ b/substreams/ethereum-pancakeswap-v3/ethereum-pancakeswap-v3.yaml @@ -0,0 +1,125 @@ +specVersion: v0.1.0 +package: + name: "ethereum_pancakeswap_v3" + version: v0.1.1 + +protobuf: + files: + - tycho/evm/v1/entity.proto + - tycho/evm/v1/common.proto + - tycho/evm/v1/utils.proto + - pancakeswap.proto + importPaths: + - ./proto/v1 + - ../../proto/ + +binaries: + default: + type: wasm/rust-v1 + file: ../target/wasm32-unknown-unknown/release/ethereum_pancakeswap_v3.wasm + +modules: + - name: map_pools_created + kind: map + initialBlock: 16950686 + inputs: + - params: string + - source: sf.ethereum.type.v2.Block + output: + type: proto:tycho.evm.v1.BlockChanges + + - name: store_pools + kind: store + initialBlock: 16950686 + updatePolicy: set_if_not_exists + valueType: proto:pancakeswap.v3.Pool + inputs: + - map: map_pools_created + + - name: map_events + kind: map + initialBlock: 16950686 + inputs: + - source: sf.ethereum.type.v2.Block + - store: store_pools + output: + type: proto:pancakeswap.v3.Events + + - name: map_balance_changes + kind: map + initialBlock: 16950686 + inputs: + - map: map_events + output: + type: proto:tycho.evm.v1.BlockBalanceDeltas + + - name: store_pools_balances + kind: store + initialBlock: 16950686 + updatePolicy: add + valueType: bigint + inputs: + - map: map_balance_changes + + - name: map_ticks_changes + kind: map + initialBlock: 16950686 + inputs: + - map: map_events + output: + type: proto:pancakeswap.v3.TickDeltas + + - name: store_ticks_liquidity + kind: store + initialBlock: 16950686 + updatePolicy: add + valueType: bigint + inputs: + - map: map_ticks_changes + + - name: store_pool_current_tick + kind: store + initialBlock: 16950686 + updatePolicy: set + valueType: int64 + inputs: + - map: map_events + + - name: map_liquidity_changes + kind: map + initialBlock: 16950686 + inputs: + - map: map_events + - store: store_pool_current_tick + output: + type: proto:pancakeswap.v3.LiquidityChanges + + - name: store_liquidity + kind: store + initialBlock: 16950686 + updatePolicy: set_sum + valueType: bigint + inputs: + - map: map_liquidity_changes + + - name: map_protocol_changes + kind: map + initialBlock: 16950686 + inputs: + - source: sf.ethereum.type.v2.Block + - map: map_pools_created + - map: map_events + - map: map_balance_changes + - store: store_pools_balances + mode: deltas + - map: map_ticks_changes + - store: store_ticks_liquidity + mode: deltas + - map: map_liquidity_changes + - store: store_liquidity + mode: deltas + output: + type: proto:tycho.evm.v1.BlockChanges + +params: + map_pools_created: "0BFbCF9fa4f9C56B0F40a671Ad40E0805A091865" diff --git a/substreams/ethereum-pancakeswap-v3/proto/v1/pancakeswap.proto b/substreams/ethereum-pancakeswap-v3/proto/v1/pancakeswap.proto new file mode 100644 index 0000000..35daa44 --- /dev/null +++ b/substreams/ethereum-pancakeswap-v3/proto/v1/pancakeswap.proto @@ -0,0 +1,179 @@ +syntax = "proto3"; + +package pancakeswap.v3; + +message Pool { + bytes address = 1; + bytes token0 = 2; + bytes token1 = 3; + uint64 fee = 4; + bytes created_tx_hash = 5; +} + +// A struct describing a transaction. +message Transaction { + // The transaction hash. + bytes hash = 1; + // The sender of the transaction. + bytes from = 2; + // The receiver of the transaction. + bytes to = 3; + // The transactions index within the block. + uint64 index = 4; +} + +// A change to a pool's tick. +message TickDelta { + // The address of the pool. + bytes pool_address = 1; + // The index of the tick. + int32 tick_index = 2; + // The liquidity net delta of this tick. Bigint encoded as signed little endian bytes. + bytes liquidity_net_delta = 3; + // Used to determine the order of the balance changes. Necessary for the balance store. + uint64 ordinal = 4; + Transaction transaction = 5; +} + +// A group of TickDelta +message TickDeltas { + repeated TickDelta deltas = 1; +} + +// A change to a pool's liquidity. +message LiquidityChange { + // The address of the pool. + bytes pool_address = 1; + // The liquidity changed amount. Bigint encoded as signed little endian bytes. + bytes value = 2; + // The type of update, can be absolute or delta. + LiquidityChangeType change_type = 3; + // Used to determine the order of the balance changes. Necessary for the balance store. + uint64 ordinal = 4; + Transaction transaction = 5; +} + +// A group of LiquidityChange +message LiquidityChanges { + repeated LiquidityChange changes = 1; +} + + +enum LiquidityChangeType { + DELTA = 0; + ABSOLUTE = 1; +} + +message Events { + repeated PoolEvent pool_events = 3; + + message PoolEvent { + oneof type { + Initialize initialize = 1; + Mint mint = 2; + Collect collect = 3; + Burn burn = 4; + Swap swap = 5; + Flash flash = 6; + SetFeeProtocol set_fee_protocol = 7; + CollectProtocol collect_protocol = 8; + } + uint64 log_ordinal = 100; + string pool_address = 102; + string token0 = 103; + string token1 = 104; + uint64 fee = 105; + Transaction transaction = 106; + + message Initialize { + // Unsigned + string sqrt_price = 1; + int32 tick = 2; + } + + message Mint { + string sender = 1; + string owner = 2; + // Signed + int32 tick_lower = 3; + // Signed + int32 tick_upper = 4; + // Unsigned + string amount = 5; + // Unsigned + string amount_0 = 6; + // Unsigned + string amount_1 = 7; + } + + message Collect { + string owner = 1; + string recipient = 2; + int32 tick_lower = 3; + int32 tick_upper = 4; + // Unsigned + string amount_0 = 5; + // Unsigned + string amount_1 = 6; + } + + message Burn { + string owner = 1; + int32 tick_lower = 2; + int32 tick_upper = 3; + // Unsigned + string amount = 4; + // Unsigned + string amount_0 = 5; + // Unsigned + string amount_1 = 6; + } + + message Swap { + string sender = 1; + string recipient = 2; + // Signed + string amount_0 = 3; + // Signed + string amount_1 = 4; + // Unsigned + string sqrt_price = 6; + // Unsigned + string liquidity = 7; + int32 tick = 8; + } + + message Flash { + string sender = 1; + string recipient = 2; + // Unsigned + string amount_0 = 3; + // Unsigned + string amount_1 = 4; + // Unsigned + string paid_0 = 5; + // Unsigned + string paid_1 = 6; + } + + message SetFeeProtocol { + // Unsigned + uint64 fee_protocol_0_old = 1; + // Unsigned + uint64 fee_protocol_1_old = 2; + // Unsigned + uint64 fee_protocol_0_new = 3; + // Unsigned + uint64 fee_protocol_1_new = 4; + } + + message CollectProtocol { + string sender = 1; + string recipient = 2; + // Unsigned + string amount_0 = 3; + // Unsigned + string amount_1 = 4; + } + } +} \ No newline at end of file diff --git a/substreams/ethereum-pancakeswap-v3/rust-toolchain.toml b/substreams/ethereum-pancakeswap-v3/rust-toolchain.toml new file mode 100644 index 0000000..15b4897 --- /dev/null +++ b/substreams/ethereum-pancakeswap-v3/rust-toolchain.toml @@ -0,0 +1,4 @@ +[toolchain] +channel = "1.83.0" +components = [ "rustfmt" ] +targets = [ "wasm32-unknown-unknown" ] diff --git a/substreams/ethereum-pancakeswap-v3/src/abi/factory.rs b/substreams/ethereum-pancakeswap-v3/src/abi/factory.rs new file mode 100644 index 0000000..3ee44b4 --- /dev/null +++ b/substreams/ethereum-pancakeswap-v3/src/abi/factory.rs @@ -0,0 +1,2157 @@ +const INTERNAL_ERR: &'static str = "`ethabi_derive` internal error"; +/// Contract's functions. +#[allow(dead_code, unused_imports, unused_variables)] +pub mod functions { + use super::INTERNAL_ERR; + #[derive(Debug, Clone, PartialEq)] + pub struct CollectProtocol { + pub pool: Vec, + pub recipient: Vec, + pub amount0_requested: substreams::scalar::BigInt, + pub amount1_requested: substreams::scalar::BigInt, + } + impl CollectProtocol { + const METHOD_ID: [u8; 4] = [67u8, 219u8, 135u8, 218u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + let maybe_data = call.input.get(4..); + if maybe_data.is_none() { + return Err("no data to decode".to_string()); + } + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Address, + ethabi::ParamType::Address, + ethabi::ParamType::Uint(128usize), + ethabi::ParamType::Uint(128usize), + ], + maybe_data.unwrap(), + ) + .map_err(|e| format!("unable to decode call.input: {:?}", e))?; + values.reverse(); + Ok(Self { + pool: values + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + recipient: values + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + amount0_requested: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + amount1_requested: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + }) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode( + &[ + ethabi::Token::Address(ethabi::Address::from_slice(&self.pool)), + ethabi::Token::Address(ethabi::Address::from_slice(&self.recipient)), + ethabi::Token::Uint( + ethabi::Uint::from_big_endian( + match self.amount0_requested.clone().to_bytes_be() { + (num_bigint::Sign::Plus, bytes) => bytes, + (num_bigint::Sign::NoSign, bytes) => bytes, + (num_bigint::Sign::Minus, _) => { + panic!("negative numbers are not supported") + } + } + .as_slice(), + ), + ), + ethabi::Token::Uint( + ethabi::Uint::from_big_endian( + match self.amount1_requested.clone().to_bytes_be() { + (num_bigint::Sign::Plus, bytes) => bytes, + (num_bigint::Sign::NoSign, bytes) => bytes, + (num_bigint::Sign::Minus, _) => { + panic!("negative numbers are not supported") + } + } + .as_slice(), + ), + ), + ], + ); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn output_call( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result<(substreams::scalar::BigInt, substreams::scalar::BigInt), String> { + Self::output(call.return_data.as_ref()) + } + pub fn output( + data: &[u8], + ) -> Result<(substreams::scalar::BigInt, substreams::scalar::BigInt), String> { + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Uint(128usize), + ethabi::ParamType::Uint(128usize), + ], + data.as_ref(), + ) + .map_err(|e| format!("unable to decode output data: {:?}", e))?; + values.reverse(); + Ok(( + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + )) + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + pub fn call( + &self, + address: Vec, + ) -> Option<(substreams::scalar::BigInt, substreams::scalar::BigInt)> { + use substreams_ethereum::pb::eth::rpc; + let rpc_calls = rpc::RpcCalls { + calls: vec![rpc::RpcCall { to_addr : address, data : self.encode(), }], + }; + let responses = substreams_ethereum::rpc::eth_call(&rpc_calls).responses; + let response = responses.get(0).expect("one response should have existed"); + if response.failed { + return None; + } + match Self::output(response.raw.as_ref()) { + Ok(data) => Some(data), + Err(err) => { + use substreams_ethereum::Function; + substreams::log::info!( + "Call output for function `{}` failed to decode with error: {}", + Self::NAME, err + ); + None + } + } + } + } + impl substreams_ethereum::Function for CollectProtocol { + const NAME: &'static str = "collectProtocol"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + impl substreams_ethereum::rpc::RPCDecodable< + (substreams::scalar::BigInt, substreams::scalar::BigInt), + > for CollectProtocol { + fn output( + data: &[u8], + ) -> Result<(substreams::scalar::BigInt, substreams::scalar::BigInt), String> { + Self::output(data) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct CreatePool { + pub token_a: Vec, + pub token_b: Vec, + pub fee: substreams::scalar::BigInt, + } + impl CreatePool { + const METHOD_ID: [u8; 4] = [161u8, 103u8, 18u8, 149u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + let maybe_data = call.input.get(4..); + if maybe_data.is_none() { + return Err("no data to decode".to_string()); + } + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Address, + ethabi::ParamType::Address, + ethabi::ParamType::Uint(24usize), + ], + maybe_data.unwrap(), + ) + .map_err(|e| format!("unable to decode call.input: {:?}", e))?; + values.reverse(); + Ok(Self { + token_a: values + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + token_b: values + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + fee: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + }) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode( + &[ + ethabi::Token::Address(ethabi::Address::from_slice(&self.token_a)), + ethabi::Token::Address(ethabi::Address::from_slice(&self.token_b)), + ethabi::Token::Uint( + ethabi::Uint::from_big_endian( + match self.fee.clone().to_bytes_be() { + (num_bigint::Sign::Plus, bytes) => bytes, + (num_bigint::Sign::NoSign, bytes) => bytes, + (num_bigint::Sign::Minus, _) => { + panic!("negative numbers are not supported") + } + } + .as_slice(), + ), + ), + ], + ); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn output_call( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result, String> { + Self::output(call.return_data.as_ref()) + } + pub fn output(data: &[u8]) -> Result, String> { + let mut values = ethabi::decode(&[ethabi::ParamType::Address], data.as_ref()) + .map_err(|e| format!("unable to decode output data: {:?}", e))?; + Ok( + values + .pop() + .expect("one output data should have existed") + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + ) + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + pub fn call(&self, address: Vec) -> Option> { + use substreams_ethereum::pb::eth::rpc; + let rpc_calls = rpc::RpcCalls { + calls: vec![rpc::RpcCall { to_addr : address, data : self.encode(), }], + }; + let responses = substreams_ethereum::rpc::eth_call(&rpc_calls).responses; + let response = responses.get(0).expect("one response should have existed"); + if response.failed { + return None; + } + match Self::output(response.raw.as_ref()) { + Ok(data) => Some(data), + Err(err) => { + use substreams_ethereum::Function; + substreams::log::info!( + "Call output for function `{}` failed to decode with error: {}", + Self::NAME, err + ); + None + } + } + } + } + impl substreams_ethereum::Function for CreatePool { + const NAME: &'static str = "createPool"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + impl substreams_ethereum::rpc::RPCDecodable> for CreatePool { + fn output(data: &[u8]) -> Result, String> { + Self::output(data) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct EnableFeeAmount { + pub fee: substreams::scalar::BigInt, + pub tick_spacing: substreams::scalar::BigInt, + } + impl EnableFeeAmount { + const METHOD_ID: [u8; 4] = [138u8, 124u8, 25u8, 95u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + let maybe_data = call.input.get(4..); + if maybe_data.is_none() { + return Err("no data to decode".to_string()); + } + let mut values = ethabi::decode( + &[ethabi::ParamType::Uint(24usize), ethabi::ParamType::Int(24usize)], + maybe_data.unwrap(), + ) + .map_err(|e| format!("unable to decode call.input: {:?}", e))?; + values.reverse(); + Ok(Self { + fee: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + tick_spacing: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_int() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_signed_bytes_be(&v) + }, + }) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode( + &[ + ethabi::Token::Uint( + ethabi::Uint::from_big_endian( + match self.fee.clone().to_bytes_be() { + (num_bigint::Sign::Plus, bytes) => bytes, + (num_bigint::Sign::NoSign, bytes) => bytes, + (num_bigint::Sign::Minus, _) => { + panic!("negative numbers are not supported") + } + } + .as_slice(), + ), + ), + { + let non_full_signed_bytes = self + .tick_spacing + .to_signed_bytes_be(); + let full_signed_bytes_init = if non_full_signed_bytes[0] & 0x80 + == 0x80 + { + 0xff + } else { + 0x00 + }; + let mut full_signed_bytes = [full_signed_bytes_init as u8; 32]; + non_full_signed_bytes + .into_iter() + .rev() + .enumerate() + .for_each(|(i, byte)| full_signed_bytes[31 - i] = byte); + ethabi::Token::Int( + ethabi::Int::from_big_endian(full_signed_bytes.as_ref()), + ) + }, + ], + ); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + } + impl substreams_ethereum::Function for EnableFeeAmount { + const NAME: &'static str = "enableFeeAmount"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct FeeAmountTickSpacing { + pub param0: substreams::scalar::BigInt, + } + impl FeeAmountTickSpacing { + const METHOD_ID: [u8; 4] = [34u8, 175u8, 204u8, 203u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + let maybe_data = call.input.get(4..); + if maybe_data.is_none() { + return Err("no data to decode".to_string()); + } + let mut values = ethabi::decode( + &[ethabi::ParamType::Uint(24usize)], + maybe_data.unwrap(), + ) + .map_err(|e| format!("unable to decode call.input: {:?}", e))?; + values.reverse(); + Ok(Self { + param0: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + }) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode( + &[ + ethabi::Token::Uint( + ethabi::Uint::from_big_endian( + match self.param0.clone().to_bytes_be() { + (num_bigint::Sign::Plus, bytes) => bytes, + (num_bigint::Sign::NoSign, bytes) => bytes, + (num_bigint::Sign::Minus, _) => { + panic!("negative numbers are not supported") + } + } + .as_slice(), + ), + ), + ], + ); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn output_call( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::output(call.return_data.as_ref()) + } + pub fn output(data: &[u8]) -> Result { + let mut values = ethabi::decode( + &[ethabi::ParamType::Int(24usize)], + data.as_ref(), + ) + .map_err(|e| format!("unable to decode output data: {:?}", e))?; + Ok({ + let mut v = [0 as u8; 32]; + values + .pop() + .expect("one output data should have existed") + .into_int() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_signed_bytes_be(&v) + }) + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + pub fn call(&self, address: Vec) -> Option { + use substreams_ethereum::pb::eth::rpc; + let rpc_calls = rpc::RpcCalls { + calls: vec![rpc::RpcCall { to_addr : address, data : self.encode(), }], + }; + let responses = substreams_ethereum::rpc::eth_call(&rpc_calls).responses; + let response = responses.get(0).expect("one response should have existed"); + if response.failed { + return None; + } + match Self::output(response.raw.as_ref()) { + Ok(data) => Some(data), + Err(err) => { + use substreams_ethereum::Function; + substreams::log::info!( + "Call output for function `{}` failed to decode with error: {}", + Self::NAME, err + ); + None + } + } + } + } + impl substreams_ethereum::Function for FeeAmountTickSpacing { + const NAME: &'static str = "feeAmountTickSpacing"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + impl substreams_ethereum::rpc::RPCDecodable + for FeeAmountTickSpacing { + fn output(data: &[u8]) -> Result { + Self::output(data) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct FeeAmountTickSpacingExtraInfo { + pub param0: substreams::scalar::BigInt, + } + impl FeeAmountTickSpacingExtraInfo { + const METHOD_ID: [u8; 4] = [136u8, 232u8, 0u8, 109u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + let maybe_data = call.input.get(4..); + if maybe_data.is_none() { + return Err("no data to decode".to_string()); + } + let mut values = ethabi::decode( + &[ethabi::ParamType::Uint(24usize)], + maybe_data.unwrap(), + ) + .map_err(|e| format!("unable to decode call.input: {:?}", e))?; + values.reverse(); + Ok(Self { + param0: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + }) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode( + &[ + ethabi::Token::Uint( + ethabi::Uint::from_big_endian( + match self.param0.clone().to_bytes_be() { + (num_bigint::Sign::Plus, bytes) => bytes, + (num_bigint::Sign::NoSign, bytes) => bytes, + (num_bigint::Sign::Minus, _) => { + panic!("negative numbers are not supported") + } + } + .as_slice(), + ), + ), + ], + ); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn output_call( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result<(bool, bool), String> { + Self::output(call.return_data.as_ref()) + } + pub fn output(data: &[u8]) -> Result<(bool, bool), String> { + let mut values = ethabi::decode( + &[ethabi::ParamType::Bool, ethabi::ParamType::Bool], + data.as_ref(), + ) + .map_err(|e| format!("unable to decode output data: {:?}", e))?; + values.reverse(); + Ok(( + values.pop().expect(INTERNAL_ERR).into_bool().expect(INTERNAL_ERR), + values.pop().expect(INTERNAL_ERR).into_bool().expect(INTERNAL_ERR), + )) + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + pub fn call(&self, address: Vec) -> Option<(bool, bool)> { + use substreams_ethereum::pb::eth::rpc; + let rpc_calls = rpc::RpcCalls { + calls: vec![rpc::RpcCall { to_addr : address, data : self.encode(), }], + }; + let responses = substreams_ethereum::rpc::eth_call(&rpc_calls).responses; + let response = responses.get(0).expect("one response should have existed"); + if response.failed { + return None; + } + match Self::output(response.raw.as_ref()) { + Ok(data) => Some(data), + Err(err) => { + use substreams_ethereum::Function; + substreams::log::info!( + "Call output for function `{}` failed to decode with error: {}", + Self::NAME, err + ); + None + } + } + } + } + impl substreams_ethereum::Function for FeeAmountTickSpacingExtraInfo { + const NAME: &'static str = "feeAmountTickSpacingExtraInfo"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + impl substreams_ethereum::rpc::RPCDecodable<(bool, bool)> + for FeeAmountTickSpacingExtraInfo { + fn output(data: &[u8]) -> Result<(bool, bool), String> { + Self::output(data) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct GetPool { + pub param0: Vec, + pub param1: Vec, + pub param2: substreams::scalar::BigInt, + } + impl GetPool { + const METHOD_ID: [u8; 4] = [22u8, 152u8, 238u8, 130u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + let maybe_data = call.input.get(4..); + if maybe_data.is_none() { + return Err("no data to decode".to_string()); + } + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Address, + ethabi::ParamType::Address, + ethabi::ParamType::Uint(24usize), + ], + maybe_data.unwrap(), + ) + .map_err(|e| format!("unable to decode call.input: {:?}", e))?; + values.reverse(); + Ok(Self { + param0: values + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + param1: values + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + param2: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + }) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode( + &[ + ethabi::Token::Address(ethabi::Address::from_slice(&self.param0)), + ethabi::Token::Address(ethabi::Address::from_slice(&self.param1)), + ethabi::Token::Uint( + ethabi::Uint::from_big_endian( + match self.param2.clone().to_bytes_be() { + (num_bigint::Sign::Plus, bytes) => bytes, + (num_bigint::Sign::NoSign, bytes) => bytes, + (num_bigint::Sign::Minus, _) => { + panic!("negative numbers are not supported") + } + } + .as_slice(), + ), + ), + ], + ); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn output_call( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result, String> { + Self::output(call.return_data.as_ref()) + } + pub fn output(data: &[u8]) -> Result, String> { + let mut values = ethabi::decode(&[ethabi::ParamType::Address], data.as_ref()) + .map_err(|e| format!("unable to decode output data: {:?}", e))?; + Ok( + values + .pop() + .expect("one output data should have existed") + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + ) + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + pub fn call(&self, address: Vec) -> Option> { + use substreams_ethereum::pb::eth::rpc; + let rpc_calls = rpc::RpcCalls { + calls: vec![rpc::RpcCall { to_addr : address, data : self.encode(), }], + }; + let responses = substreams_ethereum::rpc::eth_call(&rpc_calls).responses; + let response = responses.get(0).expect("one response should have existed"); + if response.failed { + return None; + } + match Self::output(response.raw.as_ref()) { + Ok(data) => Some(data), + Err(err) => { + use substreams_ethereum::Function; + substreams::log::info!( + "Call output for function `{}` failed to decode with error: {}", + Self::NAME, err + ); + None + } + } + } + } + impl substreams_ethereum::Function for GetPool { + const NAME: &'static str = "getPool"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + impl substreams_ethereum::rpc::RPCDecodable> for GetPool { + fn output(data: &[u8]) -> Result, String> { + Self::output(data) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct LmPoolDeployer {} + impl LmPoolDeployer { + const METHOD_ID: [u8; 4] = [94u8, 73u8, 42u8, 200u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Ok(Self {}) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode(&[]); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn output_call( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result, String> { + Self::output(call.return_data.as_ref()) + } + pub fn output(data: &[u8]) -> Result, String> { + let mut values = ethabi::decode(&[ethabi::ParamType::Address], data.as_ref()) + .map_err(|e| format!("unable to decode output data: {:?}", e))?; + Ok( + values + .pop() + .expect("one output data should have existed") + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + ) + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + pub fn call(&self, address: Vec) -> Option> { + use substreams_ethereum::pb::eth::rpc; + let rpc_calls = rpc::RpcCalls { + calls: vec![rpc::RpcCall { to_addr : address, data : self.encode(), }], + }; + let responses = substreams_ethereum::rpc::eth_call(&rpc_calls).responses; + let response = responses.get(0).expect("one response should have existed"); + if response.failed { + return None; + } + match Self::output(response.raw.as_ref()) { + Ok(data) => Some(data), + Err(err) => { + use substreams_ethereum::Function; + substreams::log::info!( + "Call output for function `{}` failed to decode with error: {}", + Self::NAME, err + ); + None + } + } + } + } + impl substreams_ethereum::Function for LmPoolDeployer { + const NAME: &'static str = "lmPoolDeployer"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + impl substreams_ethereum::rpc::RPCDecodable> for LmPoolDeployer { + fn output(data: &[u8]) -> Result, String> { + Self::output(data) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct Owner {} + impl Owner { + const METHOD_ID: [u8; 4] = [141u8, 165u8, 203u8, 91u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Ok(Self {}) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode(&[]); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn output_call( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result, String> { + Self::output(call.return_data.as_ref()) + } + pub fn output(data: &[u8]) -> Result, String> { + let mut values = ethabi::decode(&[ethabi::ParamType::Address], data.as_ref()) + .map_err(|e| format!("unable to decode output data: {:?}", e))?; + Ok( + values + .pop() + .expect("one output data should have existed") + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + ) + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + pub fn call(&self, address: Vec) -> Option> { + use substreams_ethereum::pb::eth::rpc; + let rpc_calls = rpc::RpcCalls { + calls: vec![rpc::RpcCall { to_addr : address, data : self.encode(), }], + }; + let responses = substreams_ethereum::rpc::eth_call(&rpc_calls).responses; + let response = responses.get(0).expect("one response should have existed"); + if response.failed { + return None; + } + match Self::output(response.raw.as_ref()) { + Ok(data) => Some(data), + Err(err) => { + use substreams_ethereum::Function; + substreams::log::info!( + "Call output for function `{}` failed to decode with error: {}", + Self::NAME, err + ); + None + } + } + } + } + impl substreams_ethereum::Function for Owner { + const NAME: &'static str = "owner"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + impl substreams_ethereum::rpc::RPCDecodable> for Owner { + fn output(data: &[u8]) -> Result, String> { + Self::output(data) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct PoolDeployer {} + impl PoolDeployer { + const METHOD_ID: [u8; 4] = [49u8, 25u8, 4u8, 154u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Ok(Self {}) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode(&[]); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn output_call( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result, String> { + Self::output(call.return_data.as_ref()) + } + pub fn output(data: &[u8]) -> Result, String> { + let mut values = ethabi::decode(&[ethabi::ParamType::Address], data.as_ref()) + .map_err(|e| format!("unable to decode output data: {:?}", e))?; + Ok( + values + .pop() + .expect("one output data should have existed") + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + ) + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + pub fn call(&self, address: Vec) -> Option> { + use substreams_ethereum::pb::eth::rpc; + let rpc_calls = rpc::RpcCalls { + calls: vec![rpc::RpcCall { to_addr : address, data : self.encode(), }], + }; + let responses = substreams_ethereum::rpc::eth_call(&rpc_calls).responses; + let response = responses.get(0).expect("one response should have existed"); + if response.failed { + return None; + } + match Self::output(response.raw.as_ref()) { + Ok(data) => Some(data), + Err(err) => { + use substreams_ethereum::Function; + substreams::log::info!( + "Call output for function `{}` failed to decode with error: {}", + Self::NAME, err + ); + None + } + } + } + } + impl substreams_ethereum::Function for PoolDeployer { + const NAME: &'static str = "poolDeployer"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + impl substreams_ethereum::rpc::RPCDecodable> for PoolDeployer { + fn output(data: &[u8]) -> Result, String> { + Self::output(data) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct SetFeeAmountExtraInfo { + pub fee: substreams::scalar::BigInt, + pub whitelist_requested: bool, + pub enabled: bool, + } + impl SetFeeAmountExtraInfo { + const METHOD_ID: [u8; 4] = [143u8, 243u8, 142u8, 128u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + let maybe_data = call.input.get(4..); + if maybe_data.is_none() { + return Err("no data to decode".to_string()); + } + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Uint(24usize), + ethabi::ParamType::Bool, + ethabi::ParamType::Bool, + ], + maybe_data.unwrap(), + ) + .map_err(|e| format!("unable to decode call.input: {:?}", e))?; + values.reverse(); + Ok(Self { + fee: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + whitelist_requested: values + .pop() + .expect(INTERNAL_ERR) + .into_bool() + .expect(INTERNAL_ERR), + enabled: values + .pop() + .expect(INTERNAL_ERR) + .into_bool() + .expect(INTERNAL_ERR), + }) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode( + &[ + ethabi::Token::Uint( + ethabi::Uint::from_big_endian( + match self.fee.clone().to_bytes_be() { + (num_bigint::Sign::Plus, bytes) => bytes, + (num_bigint::Sign::NoSign, bytes) => bytes, + (num_bigint::Sign::Minus, _) => { + panic!("negative numbers are not supported") + } + } + .as_slice(), + ), + ), + ethabi::Token::Bool(self.whitelist_requested.clone()), + ethabi::Token::Bool(self.enabled.clone()), + ], + ); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + } + impl substreams_ethereum::Function for SetFeeAmountExtraInfo { + const NAME: &'static str = "setFeeAmountExtraInfo"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct SetFeeProtocol { + pub pool: Vec, + pub fee_protocol0: substreams::scalar::BigInt, + pub fee_protocol1: substreams::scalar::BigInt, + } + impl SetFeeProtocol { + const METHOD_ID: [u8; 4] = [126u8, 132u8, 53u8, 230u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + let maybe_data = call.input.get(4..); + if maybe_data.is_none() { + return Err("no data to decode".to_string()); + } + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Address, + ethabi::ParamType::Uint(32usize), + ethabi::ParamType::Uint(32usize), + ], + maybe_data.unwrap(), + ) + .map_err(|e| format!("unable to decode call.input: {:?}", e))?; + values.reverse(); + Ok(Self { + pool: values + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + fee_protocol0: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + fee_protocol1: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + }) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode( + &[ + ethabi::Token::Address(ethabi::Address::from_slice(&self.pool)), + ethabi::Token::Uint( + ethabi::Uint::from_big_endian( + match self.fee_protocol0.clone().to_bytes_be() { + (num_bigint::Sign::Plus, bytes) => bytes, + (num_bigint::Sign::NoSign, bytes) => bytes, + (num_bigint::Sign::Minus, _) => { + panic!("negative numbers are not supported") + } + } + .as_slice(), + ), + ), + ethabi::Token::Uint( + ethabi::Uint::from_big_endian( + match self.fee_protocol1.clone().to_bytes_be() { + (num_bigint::Sign::Plus, bytes) => bytes, + (num_bigint::Sign::NoSign, bytes) => bytes, + (num_bigint::Sign::Minus, _) => { + panic!("negative numbers are not supported") + } + } + .as_slice(), + ), + ), + ], + ); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + } + impl substreams_ethereum::Function for SetFeeProtocol { + const NAME: &'static str = "setFeeProtocol"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct SetLmPool { + pub pool: Vec, + pub lm_pool: Vec, + } + impl SetLmPool { + const METHOD_ID: [u8; 4] = [17u8, 255u8, 94u8, 141u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + let maybe_data = call.input.get(4..); + if maybe_data.is_none() { + return Err("no data to decode".to_string()); + } + let mut values = ethabi::decode( + &[ethabi::ParamType::Address, ethabi::ParamType::Address], + maybe_data.unwrap(), + ) + .map_err(|e| format!("unable to decode call.input: {:?}", e))?; + values.reverse(); + Ok(Self { + pool: values + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + lm_pool: values + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + }) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode( + &[ + ethabi::Token::Address(ethabi::Address::from_slice(&self.pool)), + ethabi::Token::Address(ethabi::Address::from_slice(&self.lm_pool)), + ], + ); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + } + impl substreams_ethereum::Function for SetLmPool { + const NAME: &'static str = "setLmPool"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct SetLmPoolDeployer { + pub lm_pool_deployer: Vec, + } + impl SetLmPoolDeployer { + const METHOD_ID: [u8; 4] = [128u8, 214u8, 167u8, 146u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + let maybe_data = call.input.get(4..); + if maybe_data.is_none() { + return Err("no data to decode".to_string()); + } + let mut values = ethabi::decode( + &[ethabi::ParamType::Address], + maybe_data.unwrap(), + ) + .map_err(|e| format!("unable to decode call.input: {:?}", e))?; + values.reverse(); + Ok(Self { + lm_pool_deployer: values + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + }) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode( + &[ + ethabi::Token::Address( + ethabi::Address::from_slice(&self.lm_pool_deployer), + ), + ], + ); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + } + impl substreams_ethereum::Function for SetLmPoolDeployer { + const NAME: &'static str = "setLmPoolDeployer"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct SetOwner { + pub owner: Vec, + } + impl SetOwner { + const METHOD_ID: [u8; 4] = [19u8, 175u8, 64u8, 53u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + let maybe_data = call.input.get(4..); + if maybe_data.is_none() { + return Err("no data to decode".to_string()); + } + let mut values = ethabi::decode( + &[ethabi::ParamType::Address], + maybe_data.unwrap(), + ) + .map_err(|e| format!("unable to decode call.input: {:?}", e))?; + values.reverse(); + Ok(Self { + owner: values + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + }) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode( + &[ethabi::Token::Address(ethabi::Address::from_slice(&self.owner))], + ); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + } + impl substreams_ethereum::Function for SetOwner { + const NAME: &'static str = "setOwner"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct SetWhiteListAddress { + pub user: Vec, + pub verified: bool, + } + impl SetWhiteListAddress { + const METHOD_ID: [u8; 4] = [228u8, 168u8, 106u8, 153u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + let maybe_data = call.input.get(4..); + if maybe_data.is_none() { + return Err("no data to decode".to_string()); + } + let mut values = ethabi::decode( + &[ethabi::ParamType::Address, ethabi::ParamType::Bool], + maybe_data.unwrap(), + ) + .map_err(|e| format!("unable to decode call.input: {:?}", e))?; + values.reverse(); + Ok(Self { + user: values + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + verified: values + .pop() + .expect(INTERNAL_ERR) + .into_bool() + .expect(INTERNAL_ERR), + }) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode( + &[ + ethabi::Token::Address(ethabi::Address::from_slice(&self.user)), + ethabi::Token::Bool(self.verified.clone()), + ], + ); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + } + impl substreams_ethereum::Function for SetWhiteListAddress { + const NAME: &'static str = "setWhiteListAddress"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } +} +/// Contract's events. +#[allow(dead_code, unused_imports, unused_variables)] +pub mod events { + use super::INTERNAL_ERR; + #[derive(Debug, Clone, PartialEq)] + pub struct FeeAmountEnabled { + pub fee: substreams::scalar::BigInt, + pub tick_spacing: substreams::scalar::BigInt, + } + impl FeeAmountEnabled { + const TOPIC_ID: [u8; 32] = [ + 198u8, + 106u8, + 63u8, + 223u8, + 7u8, + 35u8, + 44u8, + 221u8, + 24u8, + 95u8, + 235u8, + 204u8, + 101u8, + 121u8, + 212u8, + 8u8, + 194u8, + 65u8, + 180u8, + 122u8, + 226u8, + 249u8, + 144u8, + 125u8, + 132u8, + 190u8, + 101u8, + 81u8, + 65u8, + 238u8, + 174u8, + 204u8, + ]; + pub fn match_log(log: &substreams_ethereum::pb::eth::v2::Log) -> bool { + if log.topics.len() != 3usize { + return false; + } + if log.data.len() != 0usize { + return false; + } + return log.topics.get(0).expect("bounds already checked").as_ref() + == Self::TOPIC_ID; + } + pub fn decode( + log: &substreams_ethereum::pb::eth::v2::Log, + ) -> Result { + Ok(Self { + fee: { + let mut v = [0 as u8; 32]; + ethabi::decode( + &[ethabi::ParamType::Uint(24usize)], + log.topics[1usize].as_ref(), + ) + .map_err(|e| { + format!( + "unable to decode param 'fee' from topic of type 'uint24': {:?}", + e + ) + })? + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + tick_spacing: substreams::scalar::BigInt::from_signed_bytes_be( + log.topics[2usize].as_ref(), + ), + }) + } + } + impl substreams_ethereum::Event for FeeAmountEnabled { + const NAME: &'static str = "FeeAmountEnabled"; + fn match_log(log: &substreams_ethereum::pb::eth::v2::Log) -> bool { + Self::match_log(log) + } + fn decode(log: &substreams_ethereum::pb::eth::v2::Log) -> Result { + Self::decode(log) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct FeeAmountExtraInfoUpdated { + pub fee: substreams::scalar::BigInt, + pub whitelist_requested: bool, + pub enabled: bool, + } + impl FeeAmountExtraInfoUpdated { + const TOPIC_ID: [u8; 32] = [ + 237u8, + 133u8, + 182u8, + 22u8, + 219u8, + 251u8, + 197u8, + 77u8, + 15u8, + 17u8, + 128u8, + 167u8, + 189u8, + 15u8, + 110u8, + 59u8, + 182u8, + 69u8, + 178u8, + 105u8, + 178u8, + 52u8, + 231u8, + 169u8, + 237u8, + 204u8, + 38u8, + 158u8, + 241u8, + 68u8, + 61u8, + 136u8, + ]; + pub fn match_log(log: &substreams_ethereum::pb::eth::v2::Log) -> bool { + if log.topics.len() != 2usize { + return false; + } + if log.data.len() != 64usize { + return false; + } + return log.topics.get(0).expect("bounds already checked").as_ref() + == Self::TOPIC_ID; + } + pub fn decode( + log: &substreams_ethereum::pb::eth::v2::Log, + ) -> Result { + let mut values = ethabi::decode( + &[ethabi::ParamType::Bool, ethabi::ParamType::Bool], + log.data.as_ref(), + ) + .map_err(|e| format!("unable to decode log.data: {:?}", e))?; + values.reverse(); + Ok(Self { + fee: { + let mut v = [0 as u8; 32]; + ethabi::decode( + &[ethabi::ParamType::Uint(24usize)], + log.topics[1usize].as_ref(), + ) + .map_err(|e| { + format!( + "unable to decode param 'fee' from topic of type 'uint24': {:?}", + e + ) + })? + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + whitelist_requested: values + .pop() + .expect(INTERNAL_ERR) + .into_bool() + .expect(INTERNAL_ERR), + enabled: values + .pop() + .expect(INTERNAL_ERR) + .into_bool() + .expect(INTERNAL_ERR), + }) + } + } + impl substreams_ethereum::Event for FeeAmountExtraInfoUpdated { + const NAME: &'static str = "FeeAmountExtraInfoUpdated"; + fn match_log(log: &substreams_ethereum::pb::eth::v2::Log) -> bool { + Self::match_log(log) + } + fn decode(log: &substreams_ethereum::pb::eth::v2::Log) -> Result { + Self::decode(log) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct OwnerChanged { + pub old_owner: Vec, + pub new_owner: Vec, + } + impl OwnerChanged { + const TOPIC_ID: [u8; 32] = [ + 181u8, + 50u8, + 7u8, + 59u8, + 56u8, + 200u8, + 49u8, + 69u8, + 227u8, + 229u8, + 19u8, + 83u8, + 119u8, + 160u8, + 139u8, + 249u8, + 170u8, + 181u8, + 91u8, + 192u8, + 253u8, + 124u8, + 17u8, + 121u8, + 205u8, + 79u8, + 185u8, + 149u8, + 210u8, + 165u8, + 21u8, + 156u8, + ]; + pub fn match_log(log: &substreams_ethereum::pb::eth::v2::Log) -> bool { + if log.topics.len() != 3usize { + return false; + } + if log.data.len() != 0usize { + return false; + } + return log.topics.get(0).expect("bounds already checked").as_ref() + == Self::TOPIC_ID; + } + pub fn decode( + log: &substreams_ethereum::pb::eth::v2::Log, + ) -> Result { + Ok(Self { + old_owner: ethabi::decode( + &[ethabi::ParamType::Address], + log.topics[1usize].as_ref(), + ) + .map_err(|e| { + format!( + "unable to decode param 'old_owner' from topic of type 'address': {:?}", + e + ) + })? + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + new_owner: ethabi::decode( + &[ethabi::ParamType::Address], + log.topics[2usize].as_ref(), + ) + .map_err(|e| { + format!( + "unable to decode param 'new_owner' from topic of type 'address': {:?}", + e + ) + })? + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + }) + } + } + impl substreams_ethereum::Event for OwnerChanged { + const NAME: &'static str = "OwnerChanged"; + fn match_log(log: &substreams_ethereum::pb::eth::v2::Log) -> bool { + Self::match_log(log) + } + fn decode(log: &substreams_ethereum::pb::eth::v2::Log) -> Result { + Self::decode(log) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct PoolCreated { + pub token0: Vec, + pub token1: Vec, + pub fee: substreams::scalar::BigInt, + pub tick_spacing: substreams::scalar::BigInt, + pub pool: Vec, + } + impl PoolCreated { + const TOPIC_ID: [u8; 32] = [ + 120u8, + 60u8, + 202u8, + 28u8, + 4u8, + 18u8, + 221u8, + 13u8, + 105u8, + 94u8, + 120u8, + 69u8, + 104u8, + 201u8, + 109u8, + 162u8, + 233u8, + 194u8, + 47u8, + 249u8, + 137u8, + 53u8, + 122u8, + 46u8, + 139u8, + 29u8, + 155u8, + 43u8, + 78u8, + 107u8, + 113u8, + 24u8, + ]; + pub fn match_log(log: &substreams_ethereum::pb::eth::v2::Log) -> bool { + if log.topics.len() != 4usize { + return false; + } + if log.data.len() != 64usize { + return false; + } + return log.topics.get(0).expect("bounds already checked").as_ref() + == Self::TOPIC_ID; + } + pub fn decode( + log: &substreams_ethereum::pb::eth::v2::Log, + ) -> Result { + let mut values = ethabi::decode( + &[ethabi::ParamType::Int(24usize), ethabi::ParamType::Address], + log.data.as_ref(), + ) + .map_err(|e| format!("unable to decode log.data: {:?}", e))?; + values.reverse(); + Ok(Self { + token0: ethabi::decode( + &[ethabi::ParamType::Address], + log.topics[1usize].as_ref(), + ) + .map_err(|e| { + format!( + "unable to decode param 'token0' from topic of type 'address': {:?}", + e + ) + })? + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + token1: ethabi::decode( + &[ethabi::ParamType::Address], + log.topics[2usize].as_ref(), + ) + .map_err(|e| { + format!( + "unable to decode param 'token1' from topic of type 'address': {:?}", + e + ) + })? + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + fee: { + let mut v = [0 as u8; 32]; + ethabi::decode( + &[ethabi::ParamType::Uint(24usize)], + log.topics[3usize].as_ref(), + ) + .map_err(|e| { + format!( + "unable to decode param 'fee' from topic of type 'uint24': {:?}", + e + ) + })? + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + tick_spacing: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_int() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_signed_bytes_be(&v) + }, + pool: values + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + }) + } + } + impl substreams_ethereum::Event for PoolCreated { + const NAME: &'static str = "PoolCreated"; + fn match_log(log: &substreams_ethereum::pb::eth::v2::Log) -> bool { + Self::match_log(log) + } + fn decode(log: &substreams_ethereum::pb::eth::v2::Log) -> Result { + Self::decode(log) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct SetLmPoolDeployer { + pub lm_pool_deployer: Vec, + } + impl SetLmPoolDeployer { + const TOPIC_ID: [u8; 32] = [ + 76u8, + 145u8, + 34u8, + 128u8, + 205u8, + 164u8, + 123u8, + 237u8, + 50u8, + 77u8, + 225u8, + 79u8, + 96u8, + 29u8, + 63u8, + 18u8, + 90u8, + 152u8, + 37u8, + 70u8, + 113u8, + 119u8, + 47u8, + 63u8, + 31u8, + 73u8, + 30u8, + 80u8, + 250u8, + 12u8, + 164u8, + 7u8, + ]; + pub fn match_log(log: &substreams_ethereum::pb::eth::v2::Log) -> bool { + if log.topics.len() != 2usize { + return false; + } + if log.data.len() != 0usize { + return false; + } + return log.topics.get(0).expect("bounds already checked").as_ref() + == Self::TOPIC_ID; + } + pub fn decode( + log: &substreams_ethereum::pb::eth::v2::Log, + ) -> Result { + Ok(Self { + lm_pool_deployer: ethabi::decode( + &[ethabi::ParamType::Address], + log.topics[1usize].as_ref(), + ) + .map_err(|e| { + format!( + "unable to decode param 'lm_pool_deployer' from topic of type 'address': {:?}", + e + ) + })? + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + }) + } + } + impl substreams_ethereum::Event for SetLmPoolDeployer { + const NAME: &'static str = "SetLmPoolDeployer"; + fn match_log(log: &substreams_ethereum::pb::eth::v2::Log) -> bool { + Self::match_log(log) + } + fn decode(log: &substreams_ethereum::pb::eth::v2::Log) -> Result { + Self::decode(log) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct WhiteListAdded { + pub user: Vec, + pub verified: bool, + } + impl WhiteListAdded { + const TOPIC_ID: [u8; 32] = [ + 174u8, + 196u8, + 42u8, + 199u8, + 241u8, + 187u8, + 134u8, + 81u8, + 144u8, + 106u8, + 230u8, + 82u8, + 47u8, + 80u8, + 161u8, + 148u8, + 41u8, + 225u8, + 36u8, + 232u8, + 234u8, + 103u8, + 142u8, + 245u8, + 159u8, + 210u8, + 119u8, + 80u8, + 117u8, + 146u8, + 136u8, + 162u8, + ]; + pub fn match_log(log: &substreams_ethereum::pb::eth::v2::Log) -> bool { + if log.topics.len() != 2usize { + return false; + } + if log.data.len() != 32usize { + return false; + } + return log.topics.get(0).expect("bounds already checked").as_ref() + == Self::TOPIC_ID; + } + pub fn decode( + log: &substreams_ethereum::pb::eth::v2::Log, + ) -> Result { + let mut values = ethabi::decode( + &[ethabi::ParamType::Bool], + log.data.as_ref(), + ) + .map_err(|e| format!("unable to decode log.data: {:?}", e))?; + values.reverse(); + Ok(Self { + user: ethabi::decode( + &[ethabi::ParamType::Address], + log.topics[1usize].as_ref(), + ) + .map_err(|e| { + format!( + "unable to decode param 'user' from topic of type 'address': {:?}", + e + ) + })? + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + verified: values + .pop() + .expect(INTERNAL_ERR) + .into_bool() + .expect(INTERNAL_ERR), + }) + } + } + impl substreams_ethereum::Event for WhiteListAdded { + const NAME: &'static str = "WhiteListAdded"; + fn match_log(log: &substreams_ethereum::pb::eth::v2::Log) -> bool { + Self::match_log(log) + } + fn decode(log: &substreams_ethereum::pb::eth::v2::Log) -> Result { + Self::decode(log) + } + } +} \ No newline at end of file diff --git a/substreams/ethereum-pancakeswap-v3/src/abi/mod.rs b/substreams/ethereum-pancakeswap-v3/src/abi/mod.rs new file mode 100644 index 0000000..f743394 --- /dev/null +++ b/substreams/ethereum-pancakeswap-v3/src/abi/mod.rs @@ -0,0 +1,4 @@ +#![allow(clippy::all, clippy::pedantic, clippy::nursery)] + +pub mod factory; +pub mod pool; diff --git a/substreams/ethereum-pancakeswap-v3/src/abi/pool.rs b/substreams/ethereum-pancakeswap-v3/src/abi/pool.rs new file mode 100644 index 0000000..586a96a --- /dev/null +++ b/substreams/ethereum-pancakeswap-v3/src/abi/pool.rs @@ -0,0 +1,5168 @@ +const INTERNAL_ERR: &'static str = "`ethabi_derive` internal error"; +/// Contract's functions. +#[allow(dead_code, unused_imports, unused_variables)] +pub mod functions { + use super::INTERNAL_ERR; + #[derive(Debug, Clone, PartialEq)] + pub struct Burn { + pub tick_lower: substreams::scalar::BigInt, + pub tick_upper: substreams::scalar::BigInt, + pub amount: substreams::scalar::BigInt, + } + impl Burn { + const METHOD_ID: [u8; 4] = [163u8, 65u8, 35u8, 167u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + let maybe_data = call.input.get(4..); + if maybe_data.is_none() { + return Err("no data to decode".to_string()); + } + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Int(24usize), + ethabi::ParamType::Int(24usize), + ethabi::ParamType::Uint(128usize), + ], + maybe_data.unwrap(), + ) + .map_err(|e| format!("unable to decode call.input: {:?}", e))?; + values.reverse(); + Ok(Self { + tick_lower: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_int() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_signed_bytes_be(&v) + }, + tick_upper: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_int() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_signed_bytes_be(&v) + }, + amount: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + }) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode( + &[ + { + let non_full_signed_bytes = self.tick_lower.to_signed_bytes_be(); + let full_signed_bytes_init = if non_full_signed_bytes[0] & 0x80 + == 0x80 + { + 0xff + } else { + 0x00 + }; + let mut full_signed_bytes = [full_signed_bytes_init as u8; 32]; + non_full_signed_bytes + .into_iter() + .rev() + .enumerate() + .for_each(|(i, byte)| full_signed_bytes[31 - i] = byte); + ethabi::Token::Int( + ethabi::Int::from_big_endian(full_signed_bytes.as_ref()), + ) + }, + { + let non_full_signed_bytes = self.tick_upper.to_signed_bytes_be(); + let full_signed_bytes_init = if non_full_signed_bytes[0] & 0x80 + == 0x80 + { + 0xff + } else { + 0x00 + }; + let mut full_signed_bytes = [full_signed_bytes_init as u8; 32]; + non_full_signed_bytes + .into_iter() + .rev() + .enumerate() + .for_each(|(i, byte)| full_signed_bytes[31 - i] = byte); + ethabi::Token::Int( + ethabi::Int::from_big_endian(full_signed_bytes.as_ref()), + ) + }, + ethabi::Token::Uint( + ethabi::Uint::from_big_endian( + match self.amount.clone().to_bytes_be() { + (num_bigint::Sign::Plus, bytes) => bytes, + (num_bigint::Sign::NoSign, bytes) => bytes, + (num_bigint::Sign::Minus, _) => { + panic!("negative numbers are not supported") + } + } + .as_slice(), + ), + ), + ], + ); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn output_call( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result<(substreams::scalar::BigInt, substreams::scalar::BigInt), String> { + Self::output(call.return_data.as_ref()) + } + pub fn output( + data: &[u8], + ) -> Result<(substreams::scalar::BigInt, substreams::scalar::BigInt), String> { + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Uint(256usize), + ethabi::ParamType::Uint(256usize), + ], + data.as_ref(), + ) + .map_err(|e| format!("unable to decode output data: {:?}", e))?; + values.reverse(); + Ok(( + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + )) + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + pub fn call( + &self, + address: Vec, + ) -> Option<(substreams::scalar::BigInt, substreams::scalar::BigInt)> { + use substreams_ethereum::pb::eth::rpc; + let rpc_calls = rpc::RpcCalls { + calls: vec![rpc::RpcCall { to_addr : address, data : self.encode(), }], + }; + let responses = substreams_ethereum::rpc::eth_call(&rpc_calls).responses; + let response = responses.get(0).expect("one response should have existed"); + if response.failed { + return None; + } + match Self::output(response.raw.as_ref()) { + Ok(data) => Some(data), + Err(err) => { + use substreams_ethereum::Function; + substreams::log::info!( + "Call output for function `{}` failed to decode with error: {}", + Self::NAME, err + ); + None + } + } + } + } + impl substreams_ethereum::Function for Burn { + const NAME: &'static str = "burn"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + impl substreams_ethereum::rpc::RPCDecodable< + (substreams::scalar::BigInt, substreams::scalar::BigInt), + > for Burn { + fn output( + data: &[u8], + ) -> Result<(substreams::scalar::BigInt, substreams::scalar::BigInt), String> { + Self::output(data) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct Collect { + pub recipient: Vec, + pub tick_lower: substreams::scalar::BigInt, + pub tick_upper: substreams::scalar::BigInt, + pub amount0_requested: substreams::scalar::BigInt, + pub amount1_requested: substreams::scalar::BigInt, + } + impl Collect { + const METHOD_ID: [u8; 4] = [79u8, 30u8, 179u8, 216u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + let maybe_data = call.input.get(4..); + if maybe_data.is_none() { + return Err("no data to decode".to_string()); + } + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Address, + ethabi::ParamType::Int(24usize), + ethabi::ParamType::Int(24usize), + ethabi::ParamType::Uint(128usize), + ethabi::ParamType::Uint(128usize), + ], + maybe_data.unwrap(), + ) + .map_err(|e| format!("unable to decode call.input: {:?}", e))?; + values.reverse(); + Ok(Self { + recipient: values + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + tick_lower: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_int() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_signed_bytes_be(&v) + }, + tick_upper: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_int() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_signed_bytes_be(&v) + }, + amount0_requested: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + amount1_requested: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + }) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode( + &[ + ethabi::Token::Address(ethabi::Address::from_slice(&self.recipient)), + { + let non_full_signed_bytes = self.tick_lower.to_signed_bytes_be(); + let full_signed_bytes_init = if non_full_signed_bytes[0] & 0x80 + == 0x80 + { + 0xff + } else { + 0x00 + }; + let mut full_signed_bytes = [full_signed_bytes_init as u8; 32]; + non_full_signed_bytes + .into_iter() + .rev() + .enumerate() + .for_each(|(i, byte)| full_signed_bytes[31 - i] = byte); + ethabi::Token::Int( + ethabi::Int::from_big_endian(full_signed_bytes.as_ref()), + ) + }, + { + let non_full_signed_bytes = self.tick_upper.to_signed_bytes_be(); + let full_signed_bytes_init = if non_full_signed_bytes[0] & 0x80 + == 0x80 + { + 0xff + } else { + 0x00 + }; + let mut full_signed_bytes = [full_signed_bytes_init as u8; 32]; + non_full_signed_bytes + .into_iter() + .rev() + .enumerate() + .for_each(|(i, byte)| full_signed_bytes[31 - i] = byte); + ethabi::Token::Int( + ethabi::Int::from_big_endian(full_signed_bytes.as_ref()), + ) + }, + ethabi::Token::Uint( + ethabi::Uint::from_big_endian( + match self.amount0_requested.clone().to_bytes_be() { + (num_bigint::Sign::Plus, bytes) => bytes, + (num_bigint::Sign::NoSign, bytes) => bytes, + (num_bigint::Sign::Minus, _) => { + panic!("negative numbers are not supported") + } + } + .as_slice(), + ), + ), + ethabi::Token::Uint( + ethabi::Uint::from_big_endian( + match self.amount1_requested.clone().to_bytes_be() { + (num_bigint::Sign::Plus, bytes) => bytes, + (num_bigint::Sign::NoSign, bytes) => bytes, + (num_bigint::Sign::Minus, _) => { + panic!("negative numbers are not supported") + } + } + .as_slice(), + ), + ), + ], + ); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn output_call( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result<(substreams::scalar::BigInt, substreams::scalar::BigInt), String> { + Self::output(call.return_data.as_ref()) + } + pub fn output( + data: &[u8], + ) -> Result<(substreams::scalar::BigInt, substreams::scalar::BigInt), String> { + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Uint(128usize), + ethabi::ParamType::Uint(128usize), + ], + data.as_ref(), + ) + .map_err(|e| format!("unable to decode output data: {:?}", e))?; + values.reverse(); + Ok(( + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + )) + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + pub fn call( + &self, + address: Vec, + ) -> Option<(substreams::scalar::BigInt, substreams::scalar::BigInt)> { + use substreams_ethereum::pb::eth::rpc; + let rpc_calls = rpc::RpcCalls { + calls: vec![rpc::RpcCall { to_addr : address, data : self.encode(), }], + }; + let responses = substreams_ethereum::rpc::eth_call(&rpc_calls).responses; + let response = responses.get(0).expect("one response should have existed"); + if response.failed { + return None; + } + match Self::output(response.raw.as_ref()) { + Ok(data) => Some(data), + Err(err) => { + use substreams_ethereum::Function; + substreams::log::info!( + "Call output for function `{}` failed to decode with error: {}", + Self::NAME, err + ); + None + } + } + } + } + impl substreams_ethereum::Function for Collect { + const NAME: &'static str = "collect"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + impl substreams_ethereum::rpc::RPCDecodable< + (substreams::scalar::BigInt, substreams::scalar::BigInt), + > for Collect { + fn output( + data: &[u8], + ) -> Result<(substreams::scalar::BigInt, substreams::scalar::BigInt), String> { + Self::output(data) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct CollectProtocol { + pub recipient: Vec, + pub amount0_requested: substreams::scalar::BigInt, + pub amount1_requested: substreams::scalar::BigInt, + } + impl CollectProtocol { + const METHOD_ID: [u8; 4] = [133u8, 182u8, 103u8, 41u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + let maybe_data = call.input.get(4..); + if maybe_data.is_none() { + return Err("no data to decode".to_string()); + } + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Address, + ethabi::ParamType::Uint(128usize), + ethabi::ParamType::Uint(128usize), + ], + maybe_data.unwrap(), + ) + .map_err(|e| format!("unable to decode call.input: {:?}", e))?; + values.reverse(); + Ok(Self { + recipient: values + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + amount0_requested: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + amount1_requested: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + }) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode( + &[ + ethabi::Token::Address(ethabi::Address::from_slice(&self.recipient)), + ethabi::Token::Uint( + ethabi::Uint::from_big_endian( + match self.amount0_requested.clone().to_bytes_be() { + (num_bigint::Sign::Plus, bytes) => bytes, + (num_bigint::Sign::NoSign, bytes) => bytes, + (num_bigint::Sign::Minus, _) => { + panic!("negative numbers are not supported") + } + } + .as_slice(), + ), + ), + ethabi::Token::Uint( + ethabi::Uint::from_big_endian( + match self.amount1_requested.clone().to_bytes_be() { + (num_bigint::Sign::Plus, bytes) => bytes, + (num_bigint::Sign::NoSign, bytes) => bytes, + (num_bigint::Sign::Minus, _) => { + panic!("negative numbers are not supported") + } + } + .as_slice(), + ), + ), + ], + ); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn output_call( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result<(substreams::scalar::BigInt, substreams::scalar::BigInt), String> { + Self::output(call.return_data.as_ref()) + } + pub fn output( + data: &[u8], + ) -> Result<(substreams::scalar::BigInt, substreams::scalar::BigInt), String> { + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Uint(128usize), + ethabi::ParamType::Uint(128usize), + ], + data.as_ref(), + ) + .map_err(|e| format!("unable to decode output data: {:?}", e))?; + values.reverse(); + Ok(( + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + )) + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + pub fn call( + &self, + address: Vec, + ) -> Option<(substreams::scalar::BigInt, substreams::scalar::BigInt)> { + use substreams_ethereum::pb::eth::rpc; + let rpc_calls = rpc::RpcCalls { + calls: vec![rpc::RpcCall { to_addr : address, data : self.encode(), }], + }; + let responses = substreams_ethereum::rpc::eth_call(&rpc_calls).responses; + let response = responses.get(0).expect("one response should have existed"); + if response.failed { + return None; + } + match Self::output(response.raw.as_ref()) { + Ok(data) => Some(data), + Err(err) => { + use substreams_ethereum::Function; + substreams::log::info!( + "Call output for function `{}` failed to decode with error: {}", + Self::NAME, err + ); + None + } + } + } + } + impl substreams_ethereum::Function for CollectProtocol { + const NAME: &'static str = "collectProtocol"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + impl substreams_ethereum::rpc::RPCDecodable< + (substreams::scalar::BigInt, substreams::scalar::BigInt), + > for CollectProtocol { + fn output( + data: &[u8], + ) -> Result<(substreams::scalar::BigInt, substreams::scalar::BigInt), String> { + Self::output(data) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct Factory {} + impl Factory { + const METHOD_ID: [u8; 4] = [196u8, 90u8, 1u8, 85u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Ok(Self {}) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode(&[]); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn output_call( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result, String> { + Self::output(call.return_data.as_ref()) + } + pub fn output(data: &[u8]) -> Result, String> { + let mut values = ethabi::decode(&[ethabi::ParamType::Address], data.as_ref()) + .map_err(|e| format!("unable to decode output data: {:?}", e))?; + Ok( + values + .pop() + .expect("one output data should have existed") + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + ) + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + pub fn call(&self, address: Vec) -> Option> { + use substreams_ethereum::pb::eth::rpc; + let rpc_calls = rpc::RpcCalls { + calls: vec![rpc::RpcCall { to_addr : address, data : self.encode(), }], + }; + let responses = substreams_ethereum::rpc::eth_call(&rpc_calls).responses; + let response = responses.get(0).expect("one response should have existed"); + if response.failed { + return None; + } + match Self::output(response.raw.as_ref()) { + Ok(data) => Some(data), + Err(err) => { + use substreams_ethereum::Function; + substreams::log::info!( + "Call output for function `{}` failed to decode with error: {}", + Self::NAME, err + ); + None + } + } + } + } + impl substreams_ethereum::Function for Factory { + const NAME: &'static str = "factory"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + impl substreams_ethereum::rpc::RPCDecodable> for Factory { + fn output(data: &[u8]) -> Result, String> { + Self::output(data) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct Fee {} + impl Fee { + const METHOD_ID: [u8; 4] = [221u8, 202u8, 63u8, 67u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Ok(Self {}) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode(&[]); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn output_call( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::output(call.return_data.as_ref()) + } + pub fn output(data: &[u8]) -> Result { + let mut values = ethabi::decode( + &[ethabi::ParamType::Uint(24usize)], + data.as_ref(), + ) + .map_err(|e| format!("unable to decode output data: {:?}", e))?; + Ok({ + let mut v = [0 as u8; 32]; + values + .pop() + .expect("one output data should have existed") + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }) + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + pub fn call(&self, address: Vec) -> Option { + use substreams_ethereum::pb::eth::rpc; + let rpc_calls = rpc::RpcCalls { + calls: vec![rpc::RpcCall { to_addr : address, data : self.encode(), }], + }; + let responses = substreams_ethereum::rpc::eth_call(&rpc_calls).responses; + let response = responses.get(0).expect("one response should have existed"); + if response.failed { + return None; + } + match Self::output(response.raw.as_ref()) { + Ok(data) => Some(data), + Err(err) => { + use substreams_ethereum::Function; + substreams::log::info!( + "Call output for function `{}` failed to decode with error: {}", + Self::NAME, err + ); + None + } + } + } + } + impl substreams_ethereum::Function for Fee { + const NAME: &'static str = "fee"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + impl substreams_ethereum::rpc::RPCDecodable for Fee { + fn output(data: &[u8]) -> Result { + Self::output(data) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct FeeGrowthGlobal0X128 {} + impl FeeGrowthGlobal0X128 { + const METHOD_ID: [u8; 4] = [243u8, 5u8, 131u8, 153u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Ok(Self {}) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode(&[]); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn output_call( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::output(call.return_data.as_ref()) + } + pub fn output(data: &[u8]) -> Result { + let mut values = ethabi::decode( + &[ethabi::ParamType::Uint(256usize)], + data.as_ref(), + ) + .map_err(|e| format!("unable to decode output data: {:?}", e))?; + Ok({ + let mut v = [0 as u8; 32]; + values + .pop() + .expect("one output data should have existed") + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }) + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + pub fn call(&self, address: Vec) -> Option { + use substreams_ethereum::pb::eth::rpc; + let rpc_calls = rpc::RpcCalls { + calls: vec![rpc::RpcCall { to_addr : address, data : self.encode(), }], + }; + let responses = substreams_ethereum::rpc::eth_call(&rpc_calls).responses; + let response = responses.get(0).expect("one response should have existed"); + if response.failed { + return None; + } + match Self::output(response.raw.as_ref()) { + Ok(data) => Some(data), + Err(err) => { + use substreams_ethereum::Function; + substreams::log::info!( + "Call output for function `{}` failed to decode with error: {}", + Self::NAME, err + ); + None + } + } + } + } + impl substreams_ethereum::Function for FeeGrowthGlobal0X128 { + const NAME: &'static str = "feeGrowthGlobal0X128"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + impl substreams_ethereum::rpc::RPCDecodable + for FeeGrowthGlobal0X128 { + fn output(data: &[u8]) -> Result { + Self::output(data) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct FeeGrowthGlobal1X128 {} + impl FeeGrowthGlobal1X128 { + const METHOD_ID: [u8; 4] = [70u8, 20u8, 19u8, 25u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Ok(Self {}) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode(&[]); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn output_call( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::output(call.return_data.as_ref()) + } + pub fn output(data: &[u8]) -> Result { + let mut values = ethabi::decode( + &[ethabi::ParamType::Uint(256usize)], + data.as_ref(), + ) + .map_err(|e| format!("unable to decode output data: {:?}", e))?; + Ok({ + let mut v = [0 as u8; 32]; + values + .pop() + .expect("one output data should have existed") + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }) + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + pub fn call(&self, address: Vec) -> Option { + use substreams_ethereum::pb::eth::rpc; + let rpc_calls = rpc::RpcCalls { + calls: vec![rpc::RpcCall { to_addr : address, data : self.encode(), }], + }; + let responses = substreams_ethereum::rpc::eth_call(&rpc_calls).responses; + let response = responses.get(0).expect("one response should have existed"); + if response.failed { + return None; + } + match Self::output(response.raw.as_ref()) { + Ok(data) => Some(data), + Err(err) => { + use substreams_ethereum::Function; + substreams::log::info!( + "Call output for function `{}` failed to decode with error: {}", + Self::NAME, err + ); + None + } + } + } + } + impl substreams_ethereum::Function for FeeGrowthGlobal1X128 { + const NAME: &'static str = "feeGrowthGlobal1X128"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + impl substreams_ethereum::rpc::RPCDecodable + for FeeGrowthGlobal1X128 { + fn output(data: &[u8]) -> Result { + Self::output(data) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct Flash { + pub recipient: Vec, + pub amount0: substreams::scalar::BigInt, + pub amount1: substreams::scalar::BigInt, + pub data: Vec, + } + impl Flash { + const METHOD_ID: [u8; 4] = [73u8, 14u8, 108u8, 188u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + let maybe_data = call.input.get(4..); + if maybe_data.is_none() { + return Err("no data to decode".to_string()); + } + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Address, + ethabi::ParamType::Uint(256usize), + ethabi::ParamType::Uint(256usize), + ethabi::ParamType::Bytes, + ], + maybe_data.unwrap(), + ) + .map_err(|e| format!("unable to decode call.input: {:?}", e))?; + values.reverse(); + Ok(Self { + recipient: values + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + amount0: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + amount1: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + data: values.pop().expect(INTERNAL_ERR).into_bytes().expect(INTERNAL_ERR), + }) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode( + &[ + ethabi::Token::Address(ethabi::Address::from_slice(&self.recipient)), + ethabi::Token::Uint( + ethabi::Uint::from_big_endian( + match self.amount0.clone().to_bytes_be() { + (num_bigint::Sign::Plus, bytes) => bytes, + (num_bigint::Sign::NoSign, bytes) => bytes, + (num_bigint::Sign::Minus, _) => { + panic!("negative numbers are not supported") + } + } + .as_slice(), + ), + ), + ethabi::Token::Uint( + ethabi::Uint::from_big_endian( + match self.amount1.clone().to_bytes_be() { + (num_bigint::Sign::Plus, bytes) => bytes, + (num_bigint::Sign::NoSign, bytes) => bytes, + (num_bigint::Sign::Minus, _) => { + panic!("negative numbers are not supported") + } + } + .as_slice(), + ), + ), + ethabi::Token::Bytes(self.data.clone()), + ], + ); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + } + impl substreams_ethereum::Function for Flash { + const NAME: &'static str = "flash"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct IncreaseObservationCardinalityNext { + pub observation_cardinality_next: substreams::scalar::BigInt, + } + impl IncreaseObservationCardinalityNext { + const METHOD_ID: [u8; 4] = [50u8, 20u8, 143u8, 103u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + let maybe_data = call.input.get(4..); + if maybe_data.is_none() { + return Err("no data to decode".to_string()); + } + let mut values = ethabi::decode( + &[ethabi::ParamType::Uint(16usize)], + maybe_data.unwrap(), + ) + .map_err(|e| format!("unable to decode call.input: {:?}", e))?; + values.reverse(); + Ok(Self { + observation_cardinality_next: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + }) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode( + &[ + ethabi::Token::Uint( + ethabi::Uint::from_big_endian( + match self.observation_cardinality_next.clone().to_bytes_be() + { + (num_bigint::Sign::Plus, bytes) => bytes, + (num_bigint::Sign::NoSign, bytes) => bytes, + (num_bigint::Sign::Minus, _) => { + panic!("negative numbers are not supported") + } + } + .as_slice(), + ), + ), + ], + ); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + } + impl substreams_ethereum::Function for IncreaseObservationCardinalityNext { + const NAME: &'static str = "increaseObservationCardinalityNext"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct Initialize { + pub sqrt_price_x96: substreams::scalar::BigInt, + } + impl Initialize { + const METHOD_ID: [u8; 4] = [246u8, 55u8, 115u8, 29u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + let maybe_data = call.input.get(4..); + if maybe_data.is_none() { + return Err("no data to decode".to_string()); + } + let mut values = ethabi::decode( + &[ethabi::ParamType::Uint(160usize)], + maybe_data.unwrap(), + ) + .map_err(|e| format!("unable to decode call.input: {:?}", e))?; + values.reverse(); + Ok(Self { + sqrt_price_x96: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + }) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode( + &[ + ethabi::Token::Uint( + ethabi::Uint::from_big_endian( + match self.sqrt_price_x96.clone().to_bytes_be() { + (num_bigint::Sign::Plus, bytes) => bytes, + (num_bigint::Sign::NoSign, bytes) => bytes, + (num_bigint::Sign::Minus, _) => { + panic!("negative numbers are not supported") + } + } + .as_slice(), + ), + ), + ], + ); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + } + impl substreams_ethereum::Function for Initialize { + const NAME: &'static str = "initialize"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct Liquidity {} + impl Liquidity { + const METHOD_ID: [u8; 4] = [26u8, 104u8, 101u8, 2u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Ok(Self {}) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode(&[]); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn output_call( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::output(call.return_data.as_ref()) + } + pub fn output(data: &[u8]) -> Result { + let mut values = ethabi::decode( + &[ethabi::ParamType::Uint(128usize)], + data.as_ref(), + ) + .map_err(|e| format!("unable to decode output data: {:?}", e))?; + Ok({ + let mut v = [0 as u8; 32]; + values + .pop() + .expect("one output data should have existed") + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }) + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + pub fn call(&self, address: Vec) -> Option { + use substreams_ethereum::pb::eth::rpc; + let rpc_calls = rpc::RpcCalls { + calls: vec![rpc::RpcCall { to_addr : address, data : self.encode(), }], + }; + let responses = substreams_ethereum::rpc::eth_call(&rpc_calls).responses; + let response = responses.get(0).expect("one response should have existed"); + if response.failed { + return None; + } + match Self::output(response.raw.as_ref()) { + Ok(data) => Some(data), + Err(err) => { + use substreams_ethereum::Function; + substreams::log::info!( + "Call output for function `{}` failed to decode with error: {}", + Self::NAME, err + ); + None + } + } + } + } + impl substreams_ethereum::Function for Liquidity { + const NAME: &'static str = "liquidity"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + impl substreams_ethereum::rpc::RPCDecodable + for Liquidity { + fn output(data: &[u8]) -> Result { + Self::output(data) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct LmPool {} + impl LmPool { + const METHOD_ID: [u8; 4] = [84u8, 13u8, 73u8, 24u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Ok(Self {}) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode(&[]); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn output_call( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result, String> { + Self::output(call.return_data.as_ref()) + } + pub fn output(data: &[u8]) -> Result, String> { + let mut values = ethabi::decode(&[ethabi::ParamType::Address], data.as_ref()) + .map_err(|e| format!("unable to decode output data: {:?}", e))?; + Ok( + values + .pop() + .expect("one output data should have existed") + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + ) + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + pub fn call(&self, address: Vec) -> Option> { + use substreams_ethereum::pb::eth::rpc; + let rpc_calls = rpc::RpcCalls { + calls: vec![rpc::RpcCall { to_addr : address, data : self.encode(), }], + }; + let responses = substreams_ethereum::rpc::eth_call(&rpc_calls).responses; + let response = responses.get(0).expect("one response should have existed"); + if response.failed { + return None; + } + match Self::output(response.raw.as_ref()) { + Ok(data) => Some(data), + Err(err) => { + use substreams_ethereum::Function; + substreams::log::info!( + "Call output for function `{}` failed to decode with error: {}", + Self::NAME, err + ); + None + } + } + } + } + impl substreams_ethereum::Function for LmPool { + const NAME: &'static str = "lmPool"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + impl substreams_ethereum::rpc::RPCDecodable> for LmPool { + fn output(data: &[u8]) -> Result, String> { + Self::output(data) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct MaxLiquidityPerTick {} + impl MaxLiquidityPerTick { + const METHOD_ID: [u8; 4] = [112u8, 207u8, 117u8, 74u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Ok(Self {}) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode(&[]); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn output_call( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::output(call.return_data.as_ref()) + } + pub fn output(data: &[u8]) -> Result { + let mut values = ethabi::decode( + &[ethabi::ParamType::Uint(128usize)], + data.as_ref(), + ) + .map_err(|e| format!("unable to decode output data: {:?}", e))?; + Ok({ + let mut v = [0 as u8; 32]; + values + .pop() + .expect("one output data should have existed") + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }) + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + pub fn call(&self, address: Vec) -> Option { + use substreams_ethereum::pb::eth::rpc; + let rpc_calls = rpc::RpcCalls { + calls: vec![rpc::RpcCall { to_addr : address, data : self.encode(), }], + }; + let responses = substreams_ethereum::rpc::eth_call(&rpc_calls).responses; + let response = responses.get(0).expect("one response should have existed"); + if response.failed { + return None; + } + match Self::output(response.raw.as_ref()) { + Ok(data) => Some(data), + Err(err) => { + use substreams_ethereum::Function; + substreams::log::info!( + "Call output for function `{}` failed to decode with error: {}", + Self::NAME, err + ); + None + } + } + } + } + impl substreams_ethereum::Function for MaxLiquidityPerTick { + const NAME: &'static str = "maxLiquidityPerTick"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + impl substreams_ethereum::rpc::RPCDecodable + for MaxLiquidityPerTick { + fn output(data: &[u8]) -> Result { + Self::output(data) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct Mint { + pub recipient: Vec, + pub tick_lower: substreams::scalar::BigInt, + pub tick_upper: substreams::scalar::BigInt, + pub amount: substreams::scalar::BigInt, + pub data: Vec, + } + impl Mint { + const METHOD_ID: [u8; 4] = [60u8, 138u8, 125u8, 141u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + let maybe_data = call.input.get(4..); + if maybe_data.is_none() { + return Err("no data to decode".to_string()); + } + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Address, + ethabi::ParamType::Int(24usize), + ethabi::ParamType::Int(24usize), + ethabi::ParamType::Uint(128usize), + ethabi::ParamType::Bytes, + ], + maybe_data.unwrap(), + ) + .map_err(|e| format!("unable to decode call.input: {:?}", e))?; + values.reverse(); + Ok(Self { + recipient: values + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + tick_lower: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_int() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_signed_bytes_be(&v) + }, + tick_upper: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_int() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_signed_bytes_be(&v) + }, + amount: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + data: values.pop().expect(INTERNAL_ERR).into_bytes().expect(INTERNAL_ERR), + }) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode( + &[ + ethabi::Token::Address(ethabi::Address::from_slice(&self.recipient)), + { + let non_full_signed_bytes = self.tick_lower.to_signed_bytes_be(); + let full_signed_bytes_init = if non_full_signed_bytes[0] & 0x80 + == 0x80 + { + 0xff + } else { + 0x00 + }; + let mut full_signed_bytes = [full_signed_bytes_init as u8; 32]; + non_full_signed_bytes + .into_iter() + .rev() + .enumerate() + .for_each(|(i, byte)| full_signed_bytes[31 - i] = byte); + ethabi::Token::Int( + ethabi::Int::from_big_endian(full_signed_bytes.as_ref()), + ) + }, + { + let non_full_signed_bytes = self.tick_upper.to_signed_bytes_be(); + let full_signed_bytes_init = if non_full_signed_bytes[0] & 0x80 + == 0x80 + { + 0xff + } else { + 0x00 + }; + let mut full_signed_bytes = [full_signed_bytes_init as u8; 32]; + non_full_signed_bytes + .into_iter() + .rev() + .enumerate() + .for_each(|(i, byte)| full_signed_bytes[31 - i] = byte); + ethabi::Token::Int( + ethabi::Int::from_big_endian(full_signed_bytes.as_ref()), + ) + }, + ethabi::Token::Uint( + ethabi::Uint::from_big_endian( + match self.amount.clone().to_bytes_be() { + (num_bigint::Sign::Plus, bytes) => bytes, + (num_bigint::Sign::NoSign, bytes) => bytes, + (num_bigint::Sign::Minus, _) => { + panic!("negative numbers are not supported") + } + } + .as_slice(), + ), + ), + ethabi::Token::Bytes(self.data.clone()), + ], + ); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn output_call( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result<(substreams::scalar::BigInt, substreams::scalar::BigInt), String> { + Self::output(call.return_data.as_ref()) + } + pub fn output( + data: &[u8], + ) -> Result<(substreams::scalar::BigInt, substreams::scalar::BigInt), String> { + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Uint(256usize), + ethabi::ParamType::Uint(256usize), + ], + data.as_ref(), + ) + .map_err(|e| format!("unable to decode output data: {:?}", e))?; + values.reverse(); + Ok(( + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + )) + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + pub fn call( + &self, + address: Vec, + ) -> Option<(substreams::scalar::BigInt, substreams::scalar::BigInt)> { + use substreams_ethereum::pb::eth::rpc; + let rpc_calls = rpc::RpcCalls { + calls: vec![rpc::RpcCall { to_addr : address, data : self.encode(), }], + }; + let responses = substreams_ethereum::rpc::eth_call(&rpc_calls).responses; + let response = responses.get(0).expect("one response should have existed"); + if response.failed { + return None; + } + match Self::output(response.raw.as_ref()) { + Ok(data) => Some(data), + Err(err) => { + use substreams_ethereum::Function; + substreams::log::info!( + "Call output for function `{}` failed to decode with error: {}", + Self::NAME, err + ); + None + } + } + } + } + impl substreams_ethereum::Function for Mint { + const NAME: &'static str = "mint"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + impl substreams_ethereum::rpc::RPCDecodable< + (substreams::scalar::BigInt, substreams::scalar::BigInt), + > for Mint { + fn output( + data: &[u8], + ) -> Result<(substreams::scalar::BigInt, substreams::scalar::BigInt), String> { + Self::output(data) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct Observations { + pub param0: substreams::scalar::BigInt, + } + impl Observations { + const METHOD_ID: [u8; 4] = [37u8, 44u8, 9u8, 215u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + let maybe_data = call.input.get(4..); + if maybe_data.is_none() { + return Err("no data to decode".to_string()); + } + let mut values = ethabi::decode( + &[ethabi::ParamType::Uint(256usize)], + maybe_data.unwrap(), + ) + .map_err(|e| format!("unable to decode call.input: {:?}", e))?; + values.reverse(); + Ok(Self { + param0: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + }) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode( + &[ + ethabi::Token::Uint( + ethabi::Uint::from_big_endian( + match self.param0.clone().to_bytes_be() { + (num_bigint::Sign::Plus, bytes) => bytes, + (num_bigint::Sign::NoSign, bytes) => bytes, + (num_bigint::Sign::Minus, _) => { + panic!("negative numbers are not supported") + } + } + .as_slice(), + ), + ), + ], + ); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn output_call( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result< + ( + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + bool, + ), + String, + > { + Self::output(call.return_data.as_ref()) + } + pub fn output( + data: &[u8], + ) -> Result< + ( + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + bool, + ), + String, + > { + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Uint(32usize), + ethabi::ParamType::Int(56usize), + ethabi::ParamType::Uint(160usize), + ethabi::ParamType::Bool, + ], + data.as_ref(), + ) + .map_err(|e| format!("unable to decode output data: {:?}", e))?; + values.reverse(); + Ok(( + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_int() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_signed_bytes_be(&v) + }, + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + values.pop().expect(INTERNAL_ERR).into_bool().expect(INTERNAL_ERR), + )) + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + pub fn call( + &self, + address: Vec, + ) -> Option< + ( + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + bool, + ), + > { + use substreams_ethereum::pb::eth::rpc; + let rpc_calls = rpc::RpcCalls { + calls: vec![rpc::RpcCall { to_addr : address, data : self.encode(), }], + }; + let responses = substreams_ethereum::rpc::eth_call(&rpc_calls).responses; + let response = responses.get(0).expect("one response should have existed"); + if response.failed { + return None; + } + match Self::output(response.raw.as_ref()) { + Ok(data) => Some(data), + Err(err) => { + use substreams_ethereum::Function; + substreams::log::info!( + "Call output for function `{}` failed to decode with error: {}", + Self::NAME, err + ); + None + } + } + } + } + impl substreams_ethereum::Function for Observations { + const NAME: &'static str = "observations"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + impl substreams_ethereum::rpc::RPCDecodable< + ( + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + bool, + ), + > for Observations { + fn output( + data: &[u8], + ) -> Result< + ( + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + bool, + ), + String, + > { + Self::output(data) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct Observe { + pub seconds_agos: Vec, + } + impl Observe { + const METHOD_ID: [u8; 4] = [136u8, 59u8, 219u8, 253u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + let maybe_data = call.input.get(4..); + if maybe_data.is_none() { + return Err("no data to decode".to_string()); + } + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Array( + Box::new(ethabi::ParamType::Uint(32usize)), + ), + ], + maybe_data.unwrap(), + ) + .map_err(|e| format!("unable to decode call.input: {:?}", e))?; + values.reverse(); + Ok(Self { + seconds_agos: values + .pop() + .expect(INTERNAL_ERR) + .into_array() + .expect(INTERNAL_ERR) + .into_iter() + .map(|inner| { + let mut v = [0 as u8; 32]; + inner + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }) + .collect(), + }) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode( + &[ + { + let v = self + .seconds_agos + .iter() + .map(|inner| ethabi::Token::Uint( + ethabi::Uint::from_big_endian( + match inner.clone().to_bytes_be() { + (num_bigint::Sign::Plus, bytes) => bytes, + (num_bigint::Sign::NoSign, bytes) => bytes, + (num_bigint::Sign::Minus, _) => { + panic!("negative numbers are not supported") + } + } + .as_slice(), + ), + )) + .collect(); + ethabi::Token::Array(v) + }, + ], + ); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn output_call( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result< + (Vec, Vec), + String, + > { + Self::output(call.return_data.as_ref()) + } + pub fn output( + data: &[u8], + ) -> Result< + (Vec, Vec), + String, + > { + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Array( + Box::new(ethabi::ParamType::Int(56usize)), + ), + ethabi::ParamType::Array( + Box::new(ethabi::ParamType::Uint(160usize)), + ), + ], + data.as_ref(), + ) + .map_err(|e| format!("unable to decode output data: {:?}", e))?; + values.reverse(); + Ok(( + values + .pop() + .expect(INTERNAL_ERR) + .into_array() + .expect(INTERNAL_ERR) + .into_iter() + .map(|inner| { + let mut v = [0 as u8; 32]; + inner + .into_int() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_signed_bytes_be(&v) + }) + .collect(), + values + .pop() + .expect(INTERNAL_ERR) + .into_array() + .expect(INTERNAL_ERR) + .into_iter() + .map(|inner| { + let mut v = [0 as u8; 32]; + inner + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }) + .collect(), + )) + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + pub fn call( + &self, + address: Vec, + ) -> Option<(Vec, Vec)> { + use substreams_ethereum::pb::eth::rpc; + let rpc_calls = rpc::RpcCalls { + calls: vec![rpc::RpcCall { to_addr : address, data : self.encode(), }], + }; + let responses = substreams_ethereum::rpc::eth_call(&rpc_calls).responses; + let response = responses.get(0).expect("one response should have existed"); + if response.failed { + return None; + } + match Self::output(response.raw.as_ref()) { + Ok(data) => Some(data), + Err(err) => { + use substreams_ethereum::Function; + substreams::log::info!( + "Call output for function `{}` failed to decode with error: {}", + Self::NAME, err + ); + None + } + } + } + } + impl substreams_ethereum::Function for Observe { + const NAME: &'static str = "observe"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + impl substreams_ethereum::rpc::RPCDecodable< + (Vec, Vec), + > for Observe { + fn output( + data: &[u8], + ) -> Result< + (Vec, Vec), + String, + > { + Self::output(data) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct Positions { + pub param0: [u8; 32usize], + } + impl Positions { + const METHOD_ID: [u8; 4] = [81u8, 78u8, 164u8, 191u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + let maybe_data = call.input.get(4..); + if maybe_data.is_none() { + return Err("no data to decode".to_string()); + } + let mut values = ethabi::decode( + &[ethabi::ParamType::FixedBytes(32usize)], + maybe_data.unwrap(), + ) + .map_err(|e| format!("unable to decode call.input: {:?}", e))?; + values.reverse(); + Ok(Self { + param0: { + let mut result = [0u8; 32]; + let v = values + .pop() + .expect(INTERNAL_ERR) + .into_fixed_bytes() + .expect(INTERNAL_ERR); + result.copy_from_slice(&v); + result + }, + }) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode( + &[ethabi::Token::FixedBytes(self.param0.as_ref().to_vec())], + ); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn output_call( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result< + ( + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + ), + String, + > { + Self::output(call.return_data.as_ref()) + } + pub fn output( + data: &[u8], + ) -> Result< + ( + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + ), + String, + > { + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Uint(128usize), + ethabi::ParamType::Uint(256usize), + ethabi::ParamType::Uint(256usize), + ethabi::ParamType::Uint(128usize), + ethabi::ParamType::Uint(128usize), + ], + data.as_ref(), + ) + .map_err(|e| format!("unable to decode output data: {:?}", e))?; + values.reverse(); + Ok(( + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + )) + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + pub fn call( + &self, + address: Vec, + ) -> Option< + ( + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + ), + > { + use substreams_ethereum::pb::eth::rpc; + let rpc_calls = rpc::RpcCalls { + calls: vec![rpc::RpcCall { to_addr : address, data : self.encode(), }], + }; + let responses = substreams_ethereum::rpc::eth_call(&rpc_calls).responses; + let response = responses.get(0).expect("one response should have existed"); + if response.failed { + return None; + } + match Self::output(response.raw.as_ref()) { + Ok(data) => Some(data), + Err(err) => { + use substreams_ethereum::Function; + substreams::log::info!( + "Call output for function `{}` failed to decode with error: {}", + Self::NAME, err + ); + None + } + } + } + } + impl substreams_ethereum::Function for Positions { + const NAME: &'static str = "positions"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + impl substreams_ethereum::rpc::RPCDecodable< + ( + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + ), + > for Positions { + fn output( + data: &[u8], + ) -> Result< + ( + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + ), + String, + > { + Self::output(data) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct ProtocolFees {} + impl ProtocolFees { + const METHOD_ID: [u8; 4] = [26u8, 216u8, 176u8, 59u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Ok(Self {}) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode(&[]); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn output_call( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result<(substreams::scalar::BigInt, substreams::scalar::BigInt), String> { + Self::output(call.return_data.as_ref()) + } + pub fn output( + data: &[u8], + ) -> Result<(substreams::scalar::BigInt, substreams::scalar::BigInt), String> { + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Uint(128usize), + ethabi::ParamType::Uint(128usize), + ], + data.as_ref(), + ) + .map_err(|e| format!("unable to decode output data: {:?}", e))?; + values.reverse(); + Ok(( + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + )) + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + pub fn call( + &self, + address: Vec, + ) -> Option<(substreams::scalar::BigInt, substreams::scalar::BigInt)> { + use substreams_ethereum::pb::eth::rpc; + let rpc_calls = rpc::RpcCalls { + calls: vec![rpc::RpcCall { to_addr : address, data : self.encode(), }], + }; + let responses = substreams_ethereum::rpc::eth_call(&rpc_calls).responses; + let response = responses.get(0).expect("one response should have existed"); + if response.failed { + return None; + } + match Self::output(response.raw.as_ref()) { + Ok(data) => Some(data), + Err(err) => { + use substreams_ethereum::Function; + substreams::log::info!( + "Call output for function `{}` failed to decode with error: {}", + Self::NAME, err + ); + None + } + } + } + } + impl substreams_ethereum::Function for ProtocolFees { + const NAME: &'static str = "protocolFees"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + impl substreams_ethereum::rpc::RPCDecodable< + (substreams::scalar::BigInt, substreams::scalar::BigInt), + > for ProtocolFees { + fn output( + data: &[u8], + ) -> Result<(substreams::scalar::BigInt, substreams::scalar::BigInt), String> { + Self::output(data) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct SetFeeProtocol { + pub fee_protocol0: substreams::scalar::BigInt, + pub fee_protocol1: substreams::scalar::BigInt, + } + impl SetFeeProtocol { + const METHOD_ID: [u8; 4] = [176u8, 208u8, 210u8, 17u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + let maybe_data = call.input.get(4..); + if maybe_data.is_none() { + return Err("no data to decode".to_string()); + } + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Uint(32usize), + ethabi::ParamType::Uint(32usize), + ], + maybe_data.unwrap(), + ) + .map_err(|e| format!("unable to decode call.input: {:?}", e))?; + values.reverse(); + Ok(Self { + fee_protocol0: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + fee_protocol1: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + }) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode( + &[ + ethabi::Token::Uint( + ethabi::Uint::from_big_endian( + match self.fee_protocol0.clone().to_bytes_be() { + (num_bigint::Sign::Plus, bytes) => bytes, + (num_bigint::Sign::NoSign, bytes) => bytes, + (num_bigint::Sign::Minus, _) => { + panic!("negative numbers are not supported") + } + } + .as_slice(), + ), + ), + ethabi::Token::Uint( + ethabi::Uint::from_big_endian( + match self.fee_protocol1.clone().to_bytes_be() { + (num_bigint::Sign::Plus, bytes) => bytes, + (num_bigint::Sign::NoSign, bytes) => bytes, + (num_bigint::Sign::Minus, _) => { + panic!("negative numbers are not supported") + } + } + .as_slice(), + ), + ), + ], + ); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + } + impl substreams_ethereum::Function for SetFeeProtocol { + const NAME: &'static str = "setFeeProtocol"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct SetLmPool { + pub lm_pool: Vec, + } + impl SetLmPool { + const METHOD_ID: [u8; 4] = [204u8, 126u8, 127u8, 162u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + let maybe_data = call.input.get(4..); + if maybe_data.is_none() { + return Err("no data to decode".to_string()); + } + let mut values = ethabi::decode( + &[ethabi::ParamType::Address], + maybe_data.unwrap(), + ) + .map_err(|e| format!("unable to decode call.input: {:?}", e))?; + values.reverse(); + Ok(Self { + lm_pool: values + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + }) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode( + &[ethabi::Token::Address(ethabi::Address::from_slice(&self.lm_pool))], + ); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + } + impl substreams_ethereum::Function for SetLmPool { + const NAME: &'static str = "setLmPool"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct Slot0 {} + impl Slot0 { + const METHOD_ID: [u8; 4] = [56u8, 80u8, 199u8, 189u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Ok(Self {}) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode(&[]); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn output_call( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result< + ( + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + bool, + ), + String, + > { + Self::output(call.return_data.as_ref()) + } + pub fn output( + data: &[u8], + ) -> Result< + ( + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + bool, + ), + String, + > { + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Uint(160usize), + ethabi::ParamType::Int(24usize), + ethabi::ParamType::Uint(16usize), + ethabi::ParamType::Uint(16usize), + ethabi::ParamType::Uint(16usize), + ethabi::ParamType::Uint(32usize), + ethabi::ParamType::Bool, + ], + data.as_ref(), + ) + .map_err(|e| format!("unable to decode output data: {:?}", e))?; + values.reverse(); + Ok(( + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_int() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_signed_bytes_be(&v) + }, + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + values.pop().expect(INTERNAL_ERR).into_bool().expect(INTERNAL_ERR), + )) + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + pub fn call( + &self, + address: Vec, + ) -> Option< + ( + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + bool, + ), + > { + use substreams_ethereum::pb::eth::rpc; + let rpc_calls = rpc::RpcCalls { + calls: vec![rpc::RpcCall { to_addr : address, data : self.encode(), }], + }; + let responses = substreams_ethereum::rpc::eth_call(&rpc_calls).responses; + let response = responses.get(0).expect("one response should have existed"); + if response.failed { + return None; + } + match Self::output(response.raw.as_ref()) { + Ok(data) => Some(data), + Err(err) => { + use substreams_ethereum::Function; + substreams::log::info!( + "Call output for function `{}` failed to decode with error: {}", + Self::NAME, err + ); + None + } + } + } + } + impl substreams_ethereum::Function for Slot0 { + const NAME: &'static str = "slot0"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + impl substreams_ethereum::rpc::RPCDecodable< + ( + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + bool, + ), + > for Slot0 { + fn output( + data: &[u8], + ) -> Result< + ( + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + bool, + ), + String, + > { + Self::output(data) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct SnapshotCumulativesInside { + pub tick_lower: substreams::scalar::BigInt, + pub tick_upper: substreams::scalar::BigInt, + } + impl SnapshotCumulativesInside { + const METHOD_ID: [u8; 4] = [163u8, 136u8, 7u8, 242u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + let maybe_data = call.input.get(4..); + if maybe_data.is_none() { + return Err("no data to decode".to_string()); + } + let mut values = ethabi::decode( + &[ethabi::ParamType::Int(24usize), ethabi::ParamType::Int(24usize)], + maybe_data.unwrap(), + ) + .map_err(|e| format!("unable to decode call.input: {:?}", e))?; + values.reverse(); + Ok(Self { + tick_lower: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_int() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_signed_bytes_be(&v) + }, + tick_upper: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_int() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_signed_bytes_be(&v) + }, + }) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode( + &[ + { + let non_full_signed_bytes = self.tick_lower.to_signed_bytes_be(); + let full_signed_bytes_init = if non_full_signed_bytes[0] & 0x80 + == 0x80 + { + 0xff + } else { + 0x00 + }; + let mut full_signed_bytes = [full_signed_bytes_init as u8; 32]; + non_full_signed_bytes + .into_iter() + .rev() + .enumerate() + .for_each(|(i, byte)| full_signed_bytes[31 - i] = byte); + ethabi::Token::Int( + ethabi::Int::from_big_endian(full_signed_bytes.as_ref()), + ) + }, + { + let non_full_signed_bytes = self.tick_upper.to_signed_bytes_be(); + let full_signed_bytes_init = if non_full_signed_bytes[0] & 0x80 + == 0x80 + { + 0xff + } else { + 0x00 + }; + let mut full_signed_bytes = [full_signed_bytes_init as u8; 32]; + non_full_signed_bytes + .into_iter() + .rev() + .enumerate() + .for_each(|(i, byte)| full_signed_bytes[31 - i] = byte); + ethabi::Token::Int( + ethabi::Int::from_big_endian(full_signed_bytes.as_ref()), + ) + }, + ], + ); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn output_call( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result< + ( + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + ), + String, + > { + Self::output(call.return_data.as_ref()) + } + pub fn output( + data: &[u8], + ) -> Result< + ( + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + ), + String, + > { + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Int(56usize), + ethabi::ParamType::Uint(160usize), + ethabi::ParamType::Uint(32usize), + ], + data.as_ref(), + ) + .map_err(|e| format!("unable to decode output data: {:?}", e))?; + values.reverse(); + Ok(( + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_int() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_signed_bytes_be(&v) + }, + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + )) + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + pub fn call( + &self, + address: Vec, + ) -> Option< + ( + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + ), + > { + use substreams_ethereum::pb::eth::rpc; + let rpc_calls = rpc::RpcCalls { + calls: vec![rpc::RpcCall { to_addr : address, data : self.encode(), }], + }; + let responses = substreams_ethereum::rpc::eth_call(&rpc_calls).responses; + let response = responses.get(0).expect("one response should have existed"); + if response.failed { + return None; + } + match Self::output(response.raw.as_ref()) { + Ok(data) => Some(data), + Err(err) => { + use substreams_ethereum::Function; + substreams::log::info!( + "Call output for function `{}` failed to decode with error: {}", + Self::NAME, err + ); + None + } + } + } + } + impl substreams_ethereum::Function for SnapshotCumulativesInside { + const NAME: &'static str = "snapshotCumulativesInside"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + impl substreams_ethereum::rpc::RPCDecodable< + ( + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + ), + > for SnapshotCumulativesInside { + fn output( + data: &[u8], + ) -> Result< + ( + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + ), + String, + > { + Self::output(data) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct Swap { + pub recipient: Vec, + pub zero_for_one: bool, + pub amount_specified: substreams::scalar::BigInt, + pub sqrt_price_limit_x96: substreams::scalar::BigInt, + pub data: Vec, + } + impl Swap { + const METHOD_ID: [u8; 4] = [18u8, 138u8, 203u8, 8u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + let maybe_data = call.input.get(4..); + if maybe_data.is_none() { + return Err("no data to decode".to_string()); + } + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Address, + ethabi::ParamType::Bool, + ethabi::ParamType::Int(256usize), + ethabi::ParamType::Uint(160usize), + ethabi::ParamType::Bytes, + ], + maybe_data.unwrap(), + ) + .map_err(|e| format!("unable to decode call.input: {:?}", e))?; + values.reverse(); + Ok(Self { + recipient: values + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + zero_for_one: values + .pop() + .expect(INTERNAL_ERR) + .into_bool() + .expect(INTERNAL_ERR), + amount_specified: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_int() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_signed_bytes_be(&v) + }, + sqrt_price_limit_x96: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + data: values.pop().expect(INTERNAL_ERR).into_bytes().expect(INTERNAL_ERR), + }) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode( + &[ + ethabi::Token::Address(ethabi::Address::from_slice(&self.recipient)), + ethabi::Token::Bool(self.zero_for_one.clone()), + { + let non_full_signed_bytes = self + .amount_specified + .to_signed_bytes_be(); + let full_signed_bytes_init = if non_full_signed_bytes[0] & 0x80 + == 0x80 + { + 0xff + } else { + 0x00 + }; + let mut full_signed_bytes = [full_signed_bytes_init as u8; 32]; + non_full_signed_bytes + .into_iter() + .rev() + .enumerate() + .for_each(|(i, byte)| full_signed_bytes[31 - i] = byte); + ethabi::Token::Int( + ethabi::Int::from_big_endian(full_signed_bytes.as_ref()), + ) + }, + ethabi::Token::Uint( + ethabi::Uint::from_big_endian( + match self.sqrt_price_limit_x96.clone().to_bytes_be() { + (num_bigint::Sign::Plus, bytes) => bytes, + (num_bigint::Sign::NoSign, bytes) => bytes, + (num_bigint::Sign::Minus, _) => { + panic!("negative numbers are not supported") + } + } + .as_slice(), + ), + ), + ethabi::Token::Bytes(self.data.clone()), + ], + ); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn output_call( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result<(substreams::scalar::BigInt, substreams::scalar::BigInt), String> { + Self::output(call.return_data.as_ref()) + } + pub fn output( + data: &[u8], + ) -> Result<(substreams::scalar::BigInt, substreams::scalar::BigInt), String> { + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Int(256usize), + ethabi::ParamType::Int(256usize), + ], + data.as_ref(), + ) + .map_err(|e| format!("unable to decode output data: {:?}", e))?; + values.reverse(); + Ok(( + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_int() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_signed_bytes_be(&v) + }, + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_int() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_signed_bytes_be(&v) + }, + )) + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + pub fn call( + &self, + address: Vec, + ) -> Option<(substreams::scalar::BigInt, substreams::scalar::BigInt)> { + use substreams_ethereum::pb::eth::rpc; + let rpc_calls = rpc::RpcCalls { + calls: vec![rpc::RpcCall { to_addr : address, data : self.encode(), }], + }; + let responses = substreams_ethereum::rpc::eth_call(&rpc_calls).responses; + let response = responses.get(0).expect("one response should have existed"); + if response.failed { + return None; + } + match Self::output(response.raw.as_ref()) { + Ok(data) => Some(data), + Err(err) => { + use substreams_ethereum::Function; + substreams::log::info!( + "Call output for function `{}` failed to decode with error: {}", + Self::NAME, err + ); + None + } + } + } + } + impl substreams_ethereum::Function for Swap { + const NAME: &'static str = "swap"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + impl substreams_ethereum::rpc::RPCDecodable< + (substreams::scalar::BigInt, substreams::scalar::BigInt), + > for Swap { + fn output( + data: &[u8], + ) -> Result<(substreams::scalar::BigInt, substreams::scalar::BigInt), String> { + Self::output(data) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct TickBitmap { + pub param0: substreams::scalar::BigInt, + } + impl TickBitmap { + const METHOD_ID: [u8; 4] = [83u8, 57u8, 194u8, 150u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + let maybe_data = call.input.get(4..); + if maybe_data.is_none() { + return Err("no data to decode".to_string()); + } + let mut values = ethabi::decode( + &[ethabi::ParamType::Int(16usize)], + maybe_data.unwrap(), + ) + .map_err(|e| format!("unable to decode call.input: {:?}", e))?; + values.reverse(); + Ok(Self { + param0: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_int() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_signed_bytes_be(&v) + }, + }) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode( + &[ + { + let non_full_signed_bytes = self.param0.to_signed_bytes_be(); + let full_signed_bytes_init = if non_full_signed_bytes[0] & 0x80 + == 0x80 + { + 0xff + } else { + 0x00 + }; + let mut full_signed_bytes = [full_signed_bytes_init as u8; 32]; + non_full_signed_bytes + .into_iter() + .rev() + .enumerate() + .for_each(|(i, byte)| full_signed_bytes[31 - i] = byte); + ethabi::Token::Int( + ethabi::Int::from_big_endian(full_signed_bytes.as_ref()), + ) + }, + ], + ); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn output_call( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::output(call.return_data.as_ref()) + } + pub fn output(data: &[u8]) -> Result { + let mut values = ethabi::decode( + &[ethabi::ParamType::Uint(256usize)], + data.as_ref(), + ) + .map_err(|e| format!("unable to decode output data: {:?}", e))?; + Ok({ + let mut v = [0 as u8; 32]; + values + .pop() + .expect("one output data should have existed") + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }) + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + pub fn call(&self, address: Vec) -> Option { + use substreams_ethereum::pb::eth::rpc; + let rpc_calls = rpc::RpcCalls { + calls: vec![rpc::RpcCall { to_addr : address, data : self.encode(), }], + }; + let responses = substreams_ethereum::rpc::eth_call(&rpc_calls).responses; + let response = responses.get(0).expect("one response should have existed"); + if response.failed { + return None; + } + match Self::output(response.raw.as_ref()) { + Ok(data) => Some(data), + Err(err) => { + use substreams_ethereum::Function; + substreams::log::info!( + "Call output for function `{}` failed to decode with error: {}", + Self::NAME, err + ); + None + } + } + } + } + impl substreams_ethereum::Function for TickBitmap { + const NAME: &'static str = "tickBitmap"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + impl substreams_ethereum::rpc::RPCDecodable + for TickBitmap { + fn output(data: &[u8]) -> Result { + Self::output(data) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct TickSpacing {} + impl TickSpacing { + const METHOD_ID: [u8; 4] = [208u8, 201u8, 58u8, 124u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Ok(Self {}) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode(&[]); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn output_call( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::output(call.return_data.as_ref()) + } + pub fn output(data: &[u8]) -> Result { + let mut values = ethabi::decode( + &[ethabi::ParamType::Int(24usize)], + data.as_ref(), + ) + .map_err(|e| format!("unable to decode output data: {:?}", e))?; + Ok({ + let mut v = [0 as u8; 32]; + values + .pop() + .expect("one output data should have existed") + .into_int() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_signed_bytes_be(&v) + }) + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + pub fn call(&self, address: Vec) -> Option { + use substreams_ethereum::pb::eth::rpc; + let rpc_calls = rpc::RpcCalls { + calls: vec![rpc::RpcCall { to_addr : address, data : self.encode(), }], + }; + let responses = substreams_ethereum::rpc::eth_call(&rpc_calls).responses; + let response = responses.get(0).expect("one response should have existed"); + if response.failed { + return None; + } + match Self::output(response.raw.as_ref()) { + Ok(data) => Some(data), + Err(err) => { + use substreams_ethereum::Function; + substreams::log::info!( + "Call output for function `{}` failed to decode with error: {}", + Self::NAME, err + ); + None + } + } + } + } + impl substreams_ethereum::Function for TickSpacing { + const NAME: &'static str = "tickSpacing"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + impl substreams_ethereum::rpc::RPCDecodable + for TickSpacing { + fn output(data: &[u8]) -> Result { + Self::output(data) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct Ticks { + pub param0: substreams::scalar::BigInt, + } + impl Ticks { + const METHOD_ID: [u8; 4] = [243u8, 13u8, 186u8, 147u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + let maybe_data = call.input.get(4..); + if maybe_data.is_none() { + return Err("no data to decode".to_string()); + } + let mut values = ethabi::decode( + &[ethabi::ParamType::Int(24usize)], + maybe_data.unwrap(), + ) + .map_err(|e| format!("unable to decode call.input: {:?}", e))?; + values.reverse(); + Ok(Self { + param0: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_int() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_signed_bytes_be(&v) + }, + }) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode( + &[ + { + let non_full_signed_bytes = self.param0.to_signed_bytes_be(); + let full_signed_bytes_init = if non_full_signed_bytes[0] & 0x80 + == 0x80 + { + 0xff + } else { + 0x00 + }; + let mut full_signed_bytes = [full_signed_bytes_init as u8; 32]; + non_full_signed_bytes + .into_iter() + .rev() + .enumerate() + .for_each(|(i, byte)| full_signed_bytes[31 - i] = byte); + ethabi::Token::Int( + ethabi::Int::from_big_endian(full_signed_bytes.as_ref()), + ) + }, + ], + ); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn output_call( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result< + ( + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + bool, + ), + String, + > { + Self::output(call.return_data.as_ref()) + } + pub fn output( + data: &[u8], + ) -> Result< + ( + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + bool, + ), + String, + > { + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Uint(128usize), + ethabi::ParamType::Int(128usize), + ethabi::ParamType::Uint(256usize), + ethabi::ParamType::Uint(256usize), + ethabi::ParamType::Int(56usize), + ethabi::ParamType::Uint(160usize), + ethabi::ParamType::Uint(32usize), + ethabi::ParamType::Bool, + ], + data.as_ref(), + ) + .map_err(|e| format!("unable to decode output data: {:?}", e))?; + values.reverse(); + Ok(( + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_int() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_signed_bytes_be(&v) + }, + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_int() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_signed_bytes_be(&v) + }, + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + values.pop().expect(INTERNAL_ERR).into_bool().expect(INTERNAL_ERR), + )) + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + pub fn call( + &self, + address: Vec, + ) -> Option< + ( + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + bool, + ), + > { + use substreams_ethereum::pb::eth::rpc; + let rpc_calls = rpc::RpcCalls { + calls: vec![rpc::RpcCall { to_addr : address, data : self.encode(), }], + }; + let responses = substreams_ethereum::rpc::eth_call(&rpc_calls).responses; + let response = responses.get(0).expect("one response should have existed"); + if response.failed { + return None; + } + match Self::output(response.raw.as_ref()) { + Ok(data) => Some(data), + Err(err) => { + use substreams_ethereum::Function; + substreams::log::info!( + "Call output for function `{}` failed to decode with error: {}", + Self::NAME, err + ); + None + } + } + } + } + impl substreams_ethereum::Function for Ticks { + const NAME: &'static str = "ticks"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + impl substreams_ethereum::rpc::RPCDecodable< + ( + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + bool, + ), + > for Ticks { + fn output( + data: &[u8], + ) -> Result< + ( + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + substreams::scalar::BigInt, + bool, + ), + String, + > { + Self::output(data) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct Token0 {} + impl Token0 { + const METHOD_ID: [u8; 4] = [13u8, 254u8, 22u8, 129u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Ok(Self {}) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode(&[]); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn output_call( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result, String> { + Self::output(call.return_data.as_ref()) + } + pub fn output(data: &[u8]) -> Result, String> { + let mut values = ethabi::decode(&[ethabi::ParamType::Address], data.as_ref()) + .map_err(|e| format!("unable to decode output data: {:?}", e))?; + Ok( + values + .pop() + .expect("one output data should have existed") + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + ) + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + pub fn call(&self, address: Vec) -> Option> { + use substreams_ethereum::pb::eth::rpc; + let rpc_calls = rpc::RpcCalls { + calls: vec![rpc::RpcCall { to_addr : address, data : self.encode(), }], + }; + let responses = substreams_ethereum::rpc::eth_call(&rpc_calls).responses; + let response = responses.get(0).expect("one response should have existed"); + if response.failed { + return None; + } + match Self::output(response.raw.as_ref()) { + Ok(data) => Some(data), + Err(err) => { + use substreams_ethereum::Function; + substreams::log::info!( + "Call output for function `{}` failed to decode with error: {}", + Self::NAME, err + ); + None + } + } + } + } + impl substreams_ethereum::Function for Token0 { + const NAME: &'static str = "token0"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + impl substreams_ethereum::rpc::RPCDecodable> for Token0 { + fn output(data: &[u8]) -> Result, String> { + Self::output(data) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct Token1 {} + impl Token1 { + const METHOD_ID: [u8; 4] = [210u8, 18u8, 32u8, 167u8]; + pub fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Ok(Self {}) + } + pub fn encode(&self) -> Vec { + let data = ethabi::encode(&[]); + let mut encoded = Vec::with_capacity(4 + data.len()); + encoded.extend(Self::METHOD_ID); + encoded.extend(data); + encoded + } + pub fn output_call( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result, String> { + Self::output(call.return_data.as_ref()) + } + pub fn output(data: &[u8]) -> Result, String> { + let mut values = ethabi::decode(&[ethabi::ParamType::Address], data.as_ref()) + .map_err(|e| format!("unable to decode output data: {:?}", e))?; + Ok( + values + .pop() + .expect("one output data should have existed") + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + ) + } + pub fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + match call.input.get(0..4) { + Some(signature) => Self::METHOD_ID == signature, + None => false, + } + } + pub fn call(&self, address: Vec) -> Option> { + use substreams_ethereum::pb::eth::rpc; + let rpc_calls = rpc::RpcCalls { + calls: vec![rpc::RpcCall { to_addr : address, data : self.encode(), }], + }; + let responses = substreams_ethereum::rpc::eth_call(&rpc_calls).responses; + let response = responses.get(0).expect("one response should have existed"); + if response.failed { + return None; + } + match Self::output(response.raw.as_ref()) { + Ok(data) => Some(data), + Err(err) => { + use substreams_ethereum::Function; + substreams::log::info!( + "Call output for function `{}` failed to decode with error: {}", + Self::NAME, err + ); + None + } + } + } + } + impl substreams_ethereum::Function for Token1 { + const NAME: &'static str = "token1"; + fn match_call(call: &substreams_ethereum::pb::eth::v2::Call) -> bool { + Self::match_call(call) + } + fn decode( + call: &substreams_ethereum::pb::eth::v2::Call, + ) -> Result { + Self::decode(call) + } + fn encode(&self) -> Vec { + self.encode() + } + } + impl substreams_ethereum::rpc::RPCDecodable> for Token1 { + fn output(data: &[u8]) -> Result, String> { + Self::output(data) + } + } +} +/// Contract's events. +#[allow(dead_code, unused_imports, unused_variables)] +pub mod events { + use super::INTERNAL_ERR; + #[derive(Debug, Clone, PartialEq)] + pub struct Burn { + pub owner: Vec, + pub tick_lower: substreams::scalar::BigInt, + pub tick_upper: substreams::scalar::BigInt, + pub amount: substreams::scalar::BigInt, + pub amount0: substreams::scalar::BigInt, + pub amount1: substreams::scalar::BigInt, + } + impl Burn { + const TOPIC_ID: [u8; 32] = [ + 12u8, + 57u8, + 108u8, + 217u8, + 137u8, + 163u8, + 159u8, + 68u8, + 89u8, + 181u8, + 250u8, + 26u8, + 237u8, + 106u8, + 154u8, + 141u8, + 205u8, + 188u8, + 69u8, + 144u8, + 138u8, + 207u8, + 214u8, + 126u8, + 2u8, + 140u8, + 213u8, + 104u8, + 218u8, + 152u8, + 152u8, + 44u8, + ]; + pub fn match_log(log: &substreams_ethereum::pb::eth::v2::Log) -> bool { + if log.topics.len() != 4usize { + return false; + } + if log.data.len() != 96usize { + return false; + } + return log.topics.get(0).expect("bounds already checked").as_ref() + == Self::TOPIC_ID; + } + pub fn decode( + log: &substreams_ethereum::pb::eth::v2::Log, + ) -> Result { + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Uint(128usize), + ethabi::ParamType::Uint(256usize), + ethabi::ParamType::Uint(256usize), + ], + log.data.as_ref(), + ) + .map_err(|e| format!("unable to decode log.data: {:?}", e))?; + values.reverse(); + Ok(Self { + owner: ethabi::decode( + &[ethabi::ParamType::Address], + log.topics[1usize].as_ref(), + ) + .map_err(|e| { + format!( + "unable to decode param 'owner' from topic of type 'address': {:?}", + e + ) + })? + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + tick_lower: substreams::scalar::BigInt::from_signed_bytes_be( + log.topics[2usize].as_ref(), + ), + tick_upper: substreams::scalar::BigInt::from_signed_bytes_be( + log.topics[3usize].as_ref(), + ), + amount: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + amount0: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + amount1: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + }) + } + } + impl substreams_ethereum::Event for Burn { + const NAME: &'static str = "Burn"; + fn match_log(log: &substreams_ethereum::pb::eth::v2::Log) -> bool { + Self::match_log(log) + } + fn decode(log: &substreams_ethereum::pb::eth::v2::Log) -> Result { + Self::decode(log) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct Collect { + pub owner: Vec, + pub recipient: Vec, + pub tick_lower: substreams::scalar::BigInt, + pub tick_upper: substreams::scalar::BigInt, + pub amount0: substreams::scalar::BigInt, + pub amount1: substreams::scalar::BigInt, + } + impl Collect { + const TOPIC_ID: [u8; 32] = [ + 112u8, + 147u8, + 83u8, + 56u8, + 230u8, + 151u8, + 117u8, + 69u8, + 106u8, + 133u8, + 221u8, + 239u8, + 34u8, + 108u8, + 57u8, + 95u8, + 182u8, + 104u8, + 182u8, + 63u8, + 160u8, + 17u8, + 95u8, + 95u8, + 32u8, + 97u8, + 11u8, + 56u8, + 142u8, + 108u8, + 169u8, + 192u8, + ]; + pub fn match_log(log: &substreams_ethereum::pb::eth::v2::Log) -> bool { + if log.topics.len() != 4usize { + return false; + } + if log.data.len() != 96usize { + return false; + } + return log.topics.get(0).expect("bounds already checked").as_ref() + == Self::TOPIC_ID; + } + pub fn decode( + log: &substreams_ethereum::pb::eth::v2::Log, + ) -> Result { + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Address, + ethabi::ParamType::Uint(128usize), + ethabi::ParamType::Uint(128usize), + ], + log.data.as_ref(), + ) + .map_err(|e| format!("unable to decode log.data: {:?}", e))?; + values.reverse(); + Ok(Self { + owner: ethabi::decode( + &[ethabi::ParamType::Address], + log.topics[1usize].as_ref(), + ) + .map_err(|e| { + format!( + "unable to decode param 'owner' from topic of type 'address': {:?}", + e + ) + })? + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + tick_lower: substreams::scalar::BigInt::from_signed_bytes_be( + log.topics[2usize].as_ref(), + ), + tick_upper: substreams::scalar::BigInt::from_signed_bytes_be( + log.topics[3usize].as_ref(), + ), + recipient: values + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + amount0: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + amount1: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + }) + } + } + impl substreams_ethereum::Event for Collect { + const NAME: &'static str = "Collect"; + fn match_log(log: &substreams_ethereum::pb::eth::v2::Log) -> bool { + Self::match_log(log) + } + fn decode(log: &substreams_ethereum::pb::eth::v2::Log) -> Result { + Self::decode(log) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct CollectProtocol { + pub sender: Vec, + pub recipient: Vec, + pub amount0: substreams::scalar::BigInt, + pub amount1: substreams::scalar::BigInt, + } + impl CollectProtocol { + const TOPIC_ID: [u8; 32] = [ + 89u8, + 107u8, + 87u8, + 57u8, + 6u8, + 33u8, + 141u8, + 52u8, + 17u8, + 133u8, + 11u8, + 38u8, + 166u8, + 180u8, + 55u8, + 214u8, + 196u8, + 82u8, + 47u8, + 219u8, + 67u8, + 210u8, + 210u8, + 56u8, + 98u8, + 99u8, + 248u8, + 109u8, + 80u8, + 184u8, + 177u8, + 81u8, + ]; + pub fn match_log(log: &substreams_ethereum::pb::eth::v2::Log) -> bool { + if log.topics.len() != 3usize { + return false; + } + if log.data.len() != 64usize { + return false; + } + return log.topics.get(0).expect("bounds already checked").as_ref() + == Self::TOPIC_ID; + } + pub fn decode( + log: &substreams_ethereum::pb::eth::v2::Log, + ) -> Result { + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Uint(128usize), + ethabi::ParamType::Uint(128usize), + ], + log.data.as_ref(), + ) + .map_err(|e| format!("unable to decode log.data: {:?}", e))?; + values.reverse(); + Ok(Self { + sender: ethabi::decode( + &[ethabi::ParamType::Address], + log.topics[1usize].as_ref(), + ) + .map_err(|e| { + format!( + "unable to decode param 'sender' from topic of type 'address': {:?}", + e + ) + })? + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + recipient: ethabi::decode( + &[ethabi::ParamType::Address], + log.topics[2usize].as_ref(), + ) + .map_err(|e| { + format!( + "unable to decode param 'recipient' from topic of type 'address': {:?}", + e + ) + })? + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + amount0: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + amount1: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + }) + } + } + impl substreams_ethereum::Event for CollectProtocol { + const NAME: &'static str = "CollectProtocol"; + fn match_log(log: &substreams_ethereum::pb::eth::v2::Log) -> bool { + Self::match_log(log) + } + fn decode(log: &substreams_ethereum::pb::eth::v2::Log) -> Result { + Self::decode(log) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct Flash { + pub sender: Vec, + pub recipient: Vec, + pub amount0: substreams::scalar::BigInt, + pub amount1: substreams::scalar::BigInt, + pub paid0: substreams::scalar::BigInt, + pub paid1: substreams::scalar::BigInt, + } + impl Flash { + const TOPIC_ID: [u8; 32] = [ + 189u8, + 189u8, + 183u8, + 29u8, + 120u8, + 96u8, + 55u8, + 107u8, + 165u8, + 43u8, + 37u8, + 165u8, + 2u8, + 139u8, + 238u8, + 162u8, + 53u8, + 129u8, + 54u8, + 74u8, + 64u8, + 82u8, + 47u8, + 107u8, + 207u8, + 184u8, + 107u8, + 177u8, + 242u8, + 220u8, + 166u8, + 51u8, + ]; + pub fn match_log(log: &substreams_ethereum::pb::eth::v2::Log) -> bool { + if log.topics.len() != 3usize { + return false; + } + if log.data.len() != 128usize { + return false; + } + return log.topics.get(0).expect("bounds already checked").as_ref() + == Self::TOPIC_ID; + } + pub fn decode( + log: &substreams_ethereum::pb::eth::v2::Log, + ) -> Result { + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Uint(256usize), + ethabi::ParamType::Uint(256usize), + ethabi::ParamType::Uint(256usize), + ethabi::ParamType::Uint(256usize), + ], + log.data.as_ref(), + ) + .map_err(|e| format!("unable to decode log.data: {:?}", e))?; + values.reverse(); + Ok(Self { + sender: ethabi::decode( + &[ethabi::ParamType::Address], + log.topics[1usize].as_ref(), + ) + .map_err(|e| { + format!( + "unable to decode param 'sender' from topic of type 'address': {:?}", + e + ) + })? + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + recipient: ethabi::decode( + &[ethabi::ParamType::Address], + log.topics[2usize].as_ref(), + ) + .map_err(|e| { + format!( + "unable to decode param 'recipient' from topic of type 'address': {:?}", + e + ) + })? + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + amount0: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + amount1: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + paid0: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + paid1: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + }) + } + } + impl substreams_ethereum::Event for Flash { + const NAME: &'static str = "Flash"; + fn match_log(log: &substreams_ethereum::pb::eth::v2::Log) -> bool { + Self::match_log(log) + } + fn decode(log: &substreams_ethereum::pb::eth::v2::Log) -> Result { + Self::decode(log) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct IncreaseObservationCardinalityNext { + pub observation_cardinality_next_old: substreams::scalar::BigInt, + pub observation_cardinality_next_new: substreams::scalar::BigInt, + } + impl IncreaseObservationCardinalityNext { + const TOPIC_ID: [u8; 32] = [ + 172u8, + 73u8, + 229u8, + 24u8, + 249u8, + 10u8, + 53u8, + 143u8, + 101u8, + 46u8, + 68u8, + 0u8, + 22u8, + 79u8, + 5u8, + 165u8, + 216u8, + 247u8, + 227u8, + 94u8, + 119u8, + 71u8, + 39u8, + 155u8, + 195u8, + 169u8, + 61u8, + 191u8, + 88u8, + 78u8, + 18u8, + 90u8, + ]; + pub fn match_log(log: &substreams_ethereum::pb::eth::v2::Log) -> bool { + if log.topics.len() != 1usize { + return false; + } + if log.data.len() != 64usize { + return false; + } + return log.topics.get(0).expect("bounds already checked").as_ref() + == Self::TOPIC_ID; + } + pub fn decode( + log: &substreams_ethereum::pb::eth::v2::Log, + ) -> Result { + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Uint(16usize), + ethabi::ParamType::Uint(16usize), + ], + log.data.as_ref(), + ) + .map_err(|e| format!("unable to decode log.data: {:?}", e))?; + values.reverse(); + Ok(Self { + observation_cardinality_next_old: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + observation_cardinality_next_new: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + }) + } + } + impl substreams_ethereum::Event for IncreaseObservationCardinalityNext { + const NAME: &'static str = "IncreaseObservationCardinalityNext"; + fn match_log(log: &substreams_ethereum::pb::eth::v2::Log) -> bool { + Self::match_log(log) + } + fn decode(log: &substreams_ethereum::pb::eth::v2::Log) -> Result { + Self::decode(log) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct Initialize { + pub sqrt_price_x96: substreams::scalar::BigInt, + pub tick: substreams::scalar::BigInt, + } + impl Initialize { + const TOPIC_ID: [u8; 32] = [ + 152u8, + 99u8, + 96u8, + 54u8, + 203u8, + 102u8, + 169u8, + 193u8, + 154u8, + 55u8, + 67u8, + 94u8, + 252u8, + 30u8, + 144u8, + 20u8, + 33u8, + 144u8, + 33u8, + 78u8, + 138u8, + 190u8, + 184u8, + 33u8, + 189u8, + 186u8, + 63u8, + 41u8, + 144u8, + 221u8, + 76u8, + 149u8, + ]; + pub fn match_log(log: &substreams_ethereum::pb::eth::v2::Log) -> bool { + if log.topics.len() != 1usize { + return false; + } + if log.data.len() != 64usize { + return false; + } + return log.topics.get(0).expect("bounds already checked").as_ref() + == Self::TOPIC_ID; + } + pub fn decode( + log: &substreams_ethereum::pb::eth::v2::Log, + ) -> Result { + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Uint(160usize), + ethabi::ParamType::Int(24usize), + ], + log.data.as_ref(), + ) + .map_err(|e| format!("unable to decode log.data: {:?}", e))?; + values.reverse(); + Ok(Self { + sqrt_price_x96: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + tick: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_int() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_signed_bytes_be(&v) + }, + }) + } + } + impl substreams_ethereum::Event for Initialize { + const NAME: &'static str = "Initialize"; + fn match_log(log: &substreams_ethereum::pb::eth::v2::Log) -> bool { + Self::match_log(log) + } + fn decode(log: &substreams_ethereum::pb::eth::v2::Log) -> Result { + Self::decode(log) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct Mint { + pub sender: Vec, + pub owner: Vec, + pub tick_lower: substreams::scalar::BigInt, + pub tick_upper: substreams::scalar::BigInt, + pub amount: substreams::scalar::BigInt, + pub amount0: substreams::scalar::BigInt, + pub amount1: substreams::scalar::BigInt, + } + impl Mint { + const TOPIC_ID: [u8; 32] = [ + 122u8, + 83u8, + 8u8, + 11u8, + 164u8, + 20u8, + 21u8, + 139u8, + 231u8, + 236u8, + 105u8, + 185u8, + 135u8, + 181u8, + 251u8, + 125u8, + 7u8, + 222u8, + 225u8, + 1u8, + 254u8, + 133u8, + 72u8, + 143u8, + 8u8, + 83u8, + 174u8, + 22u8, + 35u8, + 157u8, + 11u8, + 222u8, + ]; + pub fn match_log(log: &substreams_ethereum::pb::eth::v2::Log) -> bool { + if log.topics.len() != 4usize { + return false; + } + if log.data.len() != 128usize { + return false; + } + return log.topics.get(0).expect("bounds already checked").as_ref() + == Self::TOPIC_ID; + } + pub fn decode( + log: &substreams_ethereum::pb::eth::v2::Log, + ) -> Result { + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Address, + ethabi::ParamType::Uint(128usize), + ethabi::ParamType::Uint(256usize), + ethabi::ParamType::Uint(256usize), + ], + log.data.as_ref(), + ) + .map_err(|e| format!("unable to decode log.data: {:?}", e))?; + values.reverse(); + Ok(Self { + owner: ethabi::decode( + &[ethabi::ParamType::Address], + log.topics[1usize].as_ref(), + ) + .map_err(|e| { + format!( + "unable to decode param 'owner' from topic of type 'address': {:?}", + e + ) + })? + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + tick_lower: substreams::scalar::BigInt::from_signed_bytes_be( + log.topics[2usize].as_ref(), + ), + tick_upper: substreams::scalar::BigInt::from_signed_bytes_be( + log.topics[3usize].as_ref(), + ), + sender: values + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + amount: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + amount0: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + amount1: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + }) + } + } + impl substreams_ethereum::Event for Mint { + const NAME: &'static str = "Mint"; + fn match_log(log: &substreams_ethereum::pb::eth::v2::Log) -> bool { + Self::match_log(log) + } + fn decode(log: &substreams_ethereum::pb::eth::v2::Log) -> Result { + Self::decode(log) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct SetFeeProtocol { + pub fee_protocol0_old: substreams::scalar::BigInt, + pub fee_protocol1_old: substreams::scalar::BigInt, + pub fee_protocol0_new: substreams::scalar::BigInt, + pub fee_protocol1_new: substreams::scalar::BigInt, + } + impl SetFeeProtocol { + const TOPIC_ID: [u8; 32] = [ + 179u8, + 21u8, + 159u8, + 237u8, + 61u8, + 223u8, + 186u8, + 103u8, + 186u8, + 226u8, + 148u8, + 89u8, + 158u8, + 175u8, + 226u8, + 208u8, + 236u8, + 152u8, + 192u8, + 139u8, + 179u8, + 142u8, + 14u8, + 95u8, + 184u8, + 125u8, + 51u8, + 21u8, + 75u8, + 110u8, + 5u8, + 170u8, + ]; + pub fn match_log(log: &substreams_ethereum::pb::eth::v2::Log) -> bool { + if log.topics.len() != 1usize { + return false; + } + if log.data.len() != 128usize { + return false; + } + return log.topics.get(0).expect("bounds already checked").as_ref() + == Self::TOPIC_ID; + } + pub fn decode( + log: &substreams_ethereum::pb::eth::v2::Log, + ) -> Result { + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Uint(32usize), + ethabi::ParamType::Uint(32usize), + ethabi::ParamType::Uint(32usize), + ethabi::ParamType::Uint(32usize), + ], + log.data.as_ref(), + ) + .map_err(|e| format!("unable to decode log.data: {:?}", e))?; + values.reverse(); + Ok(Self { + fee_protocol0_old: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + fee_protocol1_old: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + fee_protocol0_new: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + fee_protocol1_new: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + }) + } + } + impl substreams_ethereum::Event for SetFeeProtocol { + const NAME: &'static str = "SetFeeProtocol"; + fn match_log(log: &substreams_ethereum::pb::eth::v2::Log) -> bool { + Self::match_log(log) + } + fn decode(log: &substreams_ethereum::pb::eth::v2::Log) -> Result { + Self::decode(log) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct SetLmPoolEvent { + pub addr: Vec, + } + impl SetLmPoolEvent { + const TOPIC_ID: [u8; 32] = [ + 41u8, + 152u8, + 54u8, + 144u8, + 168u8, + 90u8, + 17u8, + 105u8, + 108u8, + 232u8, + 163u8, + 87u8, + 153u8, + 55u8, + 68u8, + 248u8, + 213u8, + 167u8, + 79u8, + 222u8, + 20u8, + 101u8, + 62u8, + 81u8, + 124u8, + 194u8, + 248u8, + 96u8, + 138u8, + 114u8, + 53u8, + 233u8, + ]; + pub fn match_log(log: &substreams_ethereum::pb::eth::v2::Log) -> bool { + if log.topics.len() != 1usize { + return false; + } + if log.data.len() != 32usize { + return false; + } + return log.topics.get(0).expect("bounds already checked").as_ref() + == Self::TOPIC_ID; + } + pub fn decode( + log: &substreams_ethereum::pb::eth::v2::Log, + ) -> Result { + let mut values = ethabi::decode( + &[ethabi::ParamType::Address], + log.data.as_ref(), + ) + .map_err(|e| format!("unable to decode log.data: {:?}", e))?; + values.reverse(); + Ok(Self { + addr: values + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + }) + } + } + impl substreams_ethereum::Event for SetLmPoolEvent { + const NAME: &'static str = "SetLmPoolEvent"; + fn match_log(log: &substreams_ethereum::pb::eth::v2::Log) -> bool { + Self::match_log(log) + } + fn decode(log: &substreams_ethereum::pb::eth::v2::Log) -> Result { + Self::decode(log) + } + } + #[derive(Debug, Clone, PartialEq)] + pub struct Swap { + pub sender: Vec, + pub recipient: Vec, + pub amount0: substreams::scalar::BigInt, + pub amount1: substreams::scalar::BigInt, + pub sqrt_price_x96: substreams::scalar::BigInt, + pub liquidity: substreams::scalar::BigInt, + pub tick: substreams::scalar::BigInt, + pub protocol_fees_token0: substreams::scalar::BigInt, + pub protocol_fees_token1: substreams::scalar::BigInt, + } + impl Swap { + const TOPIC_ID: [u8; 32] = [ + 25u8, + 180u8, + 114u8, + 121u8, + 37u8, + 107u8, + 42u8, + 35u8, + 161u8, + 102u8, + 92u8, + 129u8, + 12u8, + 141u8, + 85u8, + 161u8, + 117u8, + 137u8, + 64u8, + 238u8, + 9u8, + 55u8, + 125u8, + 79u8, + 141u8, + 38u8, + 73u8, + 122u8, + 53u8, + 119u8, + 220u8, + 131u8, + ]; + pub fn match_log(log: &substreams_ethereum::pb::eth::v2::Log) -> bool { + if log.topics.len() != 3usize { + return false; + } + if log.data.len() != 224usize { + return false; + } + return log.topics.get(0).expect("bounds already checked").as_ref() + == Self::TOPIC_ID; + } + pub fn decode( + log: &substreams_ethereum::pb::eth::v2::Log, + ) -> Result { + let mut values = ethabi::decode( + &[ + ethabi::ParamType::Int(256usize), + ethabi::ParamType::Int(256usize), + ethabi::ParamType::Uint(160usize), + ethabi::ParamType::Uint(128usize), + ethabi::ParamType::Int(24usize), + ethabi::ParamType::Uint(128usize), + ethabi::ParamType::Uint(128usize), + ], + log.data.as_ref(), + ) + .map_err(|e| format!("unable to decode log.data: {:?}", e))?; + values.reverse(); + Ok(Self { + sender: ethabi::decode( + &[ethabi::ParamType::Address], + log.topics[1usize].as_ref(), + ) + .map_err(|e| { + format!( + "unable to decode param 'sender' from topic of type 'address': {:?}", + e + ) + })? + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + recipient: ethabi::decode( + &[ethabi::ParamType::Address], + log.topics[2usize].as_ref(), + ) + .map_err(|e| { + format!( + "unable to decode param 'recipient' from topic of type 'address': {:?}", + e + ) + })? + .pop() + .expect(INTERNAL_ERR) + .into_address() + .expect(INTERNAL_ERR) + .as_bytes() + .to_vec(), + amount0: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_int() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_signed_bytes_be(&v) + }, + amount1: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_int() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_signed_bytes_be(&v) + }, + sqrt_price_x96: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + liquidity: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + tick: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_int() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_signed_bytes_be(&v) + }, + protocol_fees_token0: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + protocol_fees_token1: { + let mut v = [0 as u8; 32]; + values + .pop() + .expect(INTERNAL_ERR) + .into_uint() + .expect(INTERNAL_ERR) + .to_big_endian(v.as_mut_slice()); + substreams::scalar::BigInt::from_unsigned_bytes_be(&v) + }, + }) + } + } + impl substreams_ethereum::Event for Swap { + const NAME: &'static str = "Swap"; + fn match_log(log: &substreams_ethereum::pb::eth::v2::Log) -> bool { + Self::match_log(log) + } + fn decode(log: &substreams_ethereum::pb::eth::v2::Log) -> Result { + Self::decode(log) + } + } +} \ No newline at end of file diff --git a/substreams/ethereum-pancakeswap-v3/src/lib.rs b/substreams/ethereum-pancakeswap-v3/src/lib.rs new file mode 100644 index 0000000..dc70218 --- /dev/null +++ b/substreams/ethereum-pancakeswap-v3/src/lib.rs @@ -0,0 +1,7 @@ +#![allow(clippy::not_unsafe_ptr_arg_deref)] + +mod abi; +mod modules; +mod pb; + +pub use modules::*; diff --git a/substreams/ethereum-pancakeswap-v3/src/modules/1_map_pool_created.rs b/substreams/ethereum-pancakeswap-v3/src/modules/1_map_pool_created.rs new file mode 100644 index 0000000..0e3acc0 --- /dev/null +++ b/substreams/ethereum-pancakeswap-v3/src/modules/1_map_pool_created.rs @@ -0,0 +1,115 @@ +use std::str::FromStr; + +use ethabi::ethereum_types::Address; +use substreams::scalar::BigInt; +use substreams_ethereum::pb::eth::v2::{self as eth}; + +use substreams_helper::{event_handler::EventHandler, hex::Hexable}; + +use crate::abi::factory::events::PoolCreated; + +use tycho_substreams::prelude::*; + +#[substreams::handlers::map] +pub fn map_pools_created( + params: String, + block: eth::Block, +) -> Result { + let mut new_pools: Vec = vec![]; + let factory_address = params.as_str(); + + get_new_pools(&block, &mut new_pools, factory_address); + + Ok(BlockChanges { block: None, changes: new_pools }) +} + +// Extract new pools from PoolCreated events +fn get_new_pools( + block: ð::Block, + new_pools: &mut Vec, + factory_address: &str, +) { + // Extract new pools from PoolCreated events + let mut on_pool_created = |event: PoolCreated, _tx: ð::TransactionTrace, _log: ð::Log| { + let tycho_tx: Transaction = _tx.into(); + + new_pools.push(TransactionChanges { + tx: Some(tycho_tx.clone()), + entity_changes: vec![EntityChanges { + component_id: event.pool.clone().to_hex(), + attributes: vec![ + Attribute { + name: "liquidity".to_string(), + value: BigInt::from(0).to_signed_bytes_be(), + change: ChangeType::Creation.into(), + }, + Attribute { + name: "tick".to_string(), + value: BigInt::from(0).to_signed_bytes_be(), + change: ChangeType::Creation.into(), + }, + Attribute { + name: "sqrt_price_x96".to_string(), + value: BigInt::from(0).to_signed_bytes_be(), + change: ChangeType::Creation.into(), + }, + ], + }], + component_changes: vec![ProtocolComponent { + id: event.pool.to_hex(), + tokens: vec![event.token0.clone(), event.token1.clone()], + contracts: vec![], + static_att: vec![ + Attribute { + name: "fee".to_string(), + value: event.fee.to_signed_bytes_be(), + change: ChangeType::Creation.into(), + }, + Attribute { + name: "tick_spacing".to_string(), + value: event.tick_spacing.to_signed_bytes_be(), + change: ChangeType::Creation.into(), + }, + Attribute { + name: "pool_address".to_string(), + value: event.pool.clone(), + change: ChangeType::Creation.into(), + }, + ], + change: i32::from(ChangeType::Creation), + protocol_type: Option::from(ProtocolType { + name: "pancakeswap_v3_pool".to_string(), + financial_type: FinancialType::Swap.into(), + attribute_schema: vec![], + implementation_type: ImplementationType::Custom.into(), + }), + tx: Some(tycho_tx), + }], + balance_changes: vec![ + BalanceChange { + token: event.token0, + balance: BigInt::from(0).to_signed_bytes_be(), + component_id: event + .pool + .clone() + .to_hex() + .as_bytes() + .to_vec(), + }, + BalanceChange { + token: event.token1, + balance: BigInt::from(0).to_signed_bytes_be(), + component_id: event.pool.to_hex().as_bytes().to_vec(), + }, + ], + contract_changes: vec![], + }) + }; + + let mut eh = EventHandler::new(block); + + eh.filter_by_address(vec![Address::from_str(factory_address).unwrap()]); + + eh.on::(&mut on_pool_created); + eh.handle_events(); +} diff --git a/substreams/ethereum-pancakeswap-v3/src/modules/2_store_pools.rs b/substreams/ethereum-pancakeswap-v3/src/modules/2_store_pools.rs new file mode 100644 index 0000000..e3b432e --- /dev/null +++ b/substreams/ethereum-pancakeswap-v3/src/modules/2_store_pools.rs @@ -0,0 +1,36 @@ +use std::str; + +use substreams::{ + scalar::BigInt, + store::{StoreNew, StoreSetIfNotExists, StoreSetIfNotExistsProto}, +}; +use tycho_substreams::models::BlockChanges; + +use crate::pb::pancakeswap::v3::Pool; + +#[substreams::handlers::store] +pub fn store_pools(pools_created: BlockChanges, store: StoreSetIfNotExistsProto) { + // Store pools. Required so the next maps can match any event to a known pool by their address + + for change in pools_created.changes { + for component_change in &change.component_changes { + let pool_address: &str = &component_change.id; + let pool: Pool = Pool { + address: hex::decode(pool_address.trim_start_matches("0x")).unwrap(), + token0: component_change.tokens[0].clone(), + token1: component_change.tokens[1].clone(), + created_tx_hash: change.tx.as_ref().unwrap().hash.clone(), + fee: BigInt::from_signed_bytes_be( + &component_change + .static_att + .iter() + .find(|attr| attr.name == "fee") + .expect("every pool should have fee as static attribute") + .value, + ) + .to_u64(), + }; + store.set_if_not_exists(0, format!("{}:{}", "Pool", pool_address), &pool); + } + } +} diff --git a/substreams/ethereum-pancakeswap-v3/src/modules/3_map_events.rs b/substreams/ethereum-pancakeswap-v3/src/modules/3_map_events.rs new file mode 100644 index 0000000..7d573a9 --- /dev/null +++ b/substreams/ethereum-pancakeswap-v3/src/modules/3_map_events.rs @@ -0,0 +1,195 @@ +use anyhow::Ok; +use substreams::{ + store::{StoreGet, StoreGetProto}, + Hex, +}; +use substreams_ethereum::{ + pb::eth::v2::{self as eth, Log, TransactionTrace}, + Event, +}; +use substreams_helper::hex::Hexable; + +use crate::{ + abi::pool::events::{ + Burn, Collect, CollectProtocol, Flash, Initialize, Mint, SetFeeProtocol, Swap, + }, + pb::pancakeswap::v3::{ + events::{ + pool_event::{self, Type}, + PoolEvent, + }, + Events, Pool, + }, +}; + +#[substreams::handlers::map] +pub fn map_events( + block: eth::Block, + pools_store: StoreGetProto, +) -> Result { + let mut pool_events = block + .transaction_traces + .into_iter() + .filter(|tx| tx.status == 1) + .flat_map(|tx| { + let receipt = tx + .receipt + .as_ref() + .expect("all transaction traces have a receipt"); + + receipt + .logs + .iter() + .filter_map(|log| { + let key = format!("{}:{}", "Pool", log.address.to_hex()); + // Skip if the log is not from a known pool. + if let Some(pool) = pools_store.get_last(key) { + log_to_event(log, pool, &tx) + } else { + None + } + }) + .collect::>() + }) + .collect::>(); + + pool_events.sort_unstable_by_key(|e| e.log_ordinal); + + Ok(Events { pool_events }) +} + +fn log_to_event(event: &Log, pool: Pool, tx: &TransactionTrace) -> Option { + if let Some(init) = Initialize::match_and_decode(event) { + Some(PoolEvent { + log_ordinal: event.ordinal, + pool_address: Hex(pool.address).to_string(), + token0: Hex(pool.token0).to_string(), + token1: Hex(pool.token1).to_string(), + fee: pool.fee, + transaction: Some(tx.into()), + r#type: Some(Type::Initialize(pool_event::Initialize { + sqrt_price: init.sqrt_price_x96.to_string(), + tick: init.tick.into(), + })), + }) + } else if let Some(swap) = Swap::match_and_decode(event) { + Some(PoolEvent { + log_ordinal: event.ordinal, + pool_address: Hex(pool.address).to_string(), + token0: Hex(pool.token0).to_string(), + token1: Hex(pool.token1).to_string(), + fee: pool.fee, + transaction: Some(tx.into()), + r#type: Some(Type::Swap(pool_event::Swap { + sender: Hex(swap.sender).to_string(), + recipient: Hex(swap.recipient).to_string(), + amount_0: swap.amount0.to_string(), + amount_1: swap.amount1.to_string(), + sqrt_price: swap.sqrt_price_x96.to_string(), + liquidity: swap.liquidity.to_string(), + tick: swap.tick.into(), + })), + }) + } else if let Some(flash) = Flash::match_and_decode(event) { + Some(PoolEvent { + log_ordinal: event.ordinal, + pool_address: Hex(pool.address).to_string(), + token0: Hex(pool.token0).to_string(), + token1: Hex(pool.token1).to_string(), + fee: pool.fee, + transaction: Some(tx.into()), + r#type: Some(Type::Flash(pool_event::Flash { + sender: Hex(flash.sender).to_string(), + recipient: Hex(flash.recipient).to_string(), + amount_0: flash.amount0.to_string(), + amount_1: flash.amount1.to_string(), + paid_0: flash.paid0.to_string(), + paid_1: flash.paid1.to_string(), + })), + }) + } else if let Some(mint) = Mint::match_and_decode(event) { + Some(PoolEvent { + log_ordinal: event.ordinal, + pool_address: Hex(pool.address).to_string(), + token0: Hex(pool.token0).to_string(), + token1: Hex(pool.token1).to_string(), + fee: pool.fee, + transaction: Some(tx.into()), + r#type: Some(Type::Mint(pool_event::Mint { + sender: Hex(mint.sender).to_string(), + owner: Hex(mint.owner).to_string(), + tick_lower: mint.tick_lower.into(), + tick_upper: mint.tick_upper.into(), + amount: mint.amount.to_string(), + amount_0: mint.amount0.to_string(), + amount_1: mint.amount1.to_string(), + })), + }) + } else if let Some(burn) = Burn::match_and_decode(event) { + Some(PoolEvent { + log_ordinal: event.ordinal, + pool_address: Hex(pool.address).to_string(), + token0: Hex(pool.token0).to_string(), + token1: Hex(pool.token1).to_string(), + fee: pool.fee, + transaction: Some(tx.into()), + r#type: Some(Type::Burn(pool_event::Burn { + owner: Hex(burn.owner).to_string(), + tick_lower: burn.tick_lower.into(), + tick_upper: burn.tick_upper.into(), + amount: burn.amount.to_string(), + amount_0: burn.amount0.to_string(), + amount_1: burn.amount1.to_string(), + })), + }) + } else if let Some(collect) = Collect::match_and_decode(event) { + Some(PoolEvent { + log_ordinal: event.ordinal, + pool_address: Hex(pool.address).to_string(), + token0: Hex(pool.token0).to_string(), + token1: Hex(pool.token1).to_string(), + fee: pool.fee, + transaction: Some(tx.into()), + r#type: Some(Type::Collect(pool_event::Collect { + owner: Hex(collect.owner).to_string(), + recipient: Hex(collect.recipient).to_string(), + tick_lower: collect.tick_lower.into(), + tick_upper: collect.tick_upper.into(), + amount_0: collect.amount0.to_string(), + amount_1: collect.amount1.to_string(), + })), + }) + } else if let Some(set_fp) = SetFeeProtocol::match_and_decode(event) { + Some(PoolEvent { + log_ordinal: event.ordinal, + pool_address: Hex(pool.address).to_string(), + token0: Hex(pool.token0).to_string(), + token1: Hex(pool.token1).to_string(), + fee: pool.fee, + transaction: Some(tx.into()), + r#type: Some(Type::SetFeeProtocol(pool_event::SetFeeProtocol { + fee_protocol_0_old: set_fp.fee_protocol0_old.to_u64(), + fee_protocol_1_old: set_fp.fee_protocol1_old.to_u64(), + fee_protocol_0_new: set_fp.fee_protocol0_new.to_u64(), + fee_protocol_1_new: set_fp.fee_protocol1_new.to_u64(), + })), + }) + } else if let Some(cp) = CollectProtocol::match_and_decode(event) { + Some(PoolEvent { + log_ordinal: event.ordinal, + pool_address: Hex(pool.address).to_string(), + token0: Hex(pool.token0).to_string(), + token1: Hex(pool.token1).to_string(), + fee: pool.fee, + transaction: Some(tx.into()), + r#type: Some(Type::CollectProtocol(pool_event::CollectProtocol { + sender: Hex(cp.sender).to_string(), + recipient: Hex(cp.recipient).to_string(), + amount_0: cp.amount0.to_string(), + amount_1: cp.amount1.to_string(), + })), + }) + } else { + None + } +} diff --git a/substreams/ethereum-pancakeswap-v3/src/modules/4_map_and_store_balance_changes.rs b/substreams/ethereum-pancakeswap-v3/src/modules/4_map_and_store_balance_changes.rs new file mode 100644 index 0000000..b8787dd --- /dev/null +++ b/substreams/ethereum-pancakeswap-v3/src/modules/4_map_and_store_balance_changes.rs @@ -0,0 +1,163 @@ +use std::str::FromStr; + +use anyhow::Ok; +use tycho_substreams::models::{BalanceDelta, BlockBalanceDeltas}; + +use crate::pb::pancakeswap::v3::{ + events::{pool_event, PoolEvent}, + Events, +}; +use substreams::{ + scalar::BigInt, + store::{StoreAddBigInt, StoreNew}, +}; + +#[substreams::handlers::map] +pub fn map_balance_changes(events: Events) -> Result { + let balance_deltas = events + .pool_events + .into_iter() + .flat_map(event_to_balance_deltas) + .collect(); + + Ok(BlockBalanceDeltas { balance_deltas }) +} + +#[substreams::handlers::store] +pub fn store_pools_balances(balances_deltas: BlockBalanceDeltas, store: StoreAddBigInt) { + tycho_substreams::balances::store_balance_changes(balances_deltas, store); +} + +fn event_to_balance_deltas(event: PoolEvent) -> Vec { + let address = format!("0x{}", event.pool_address) + .as_bytes() + .to_vec(); + match event.r#type.unwrap() { + pool_event::Type::Mint(e) => vec![ + BalanceDelta { + token: hex::decode(event.token0).unwrap(), + delta: BigInt::from_str(&e.amount_0) + .unwrap() + .to_signed_bytes_be(), + component_id: address.clone(), + ord: event.log_ordinal, + tx: event + .transaction + .as_ref() + .map(Into::into), + }, + BalanceDelta { + token: hex::decode(event.token1).unwrap(), + delta: BigInt::from_str(&e.amount_1) + .unwrap() + .to_signed_bytes_be(), + component_id: address, + ord: event.log_ordinal, + tx: event.transaction.map(Into::into), + }, + ], + pool_event::Type::Collect(e) => vec![ + BalanceDelta { + token: hex::decode(event.token0).unwrap(), + delta: BigInt::from_str(&e.amount_0) + .unwrap() + .neg() + .to_signed_bytes_be(), + component_id: address.clone(), + ord: event.log_ordinal, + tx: event + .transaction + .as_ref() + .map(Into::into), + }, + BalanceDelta { + token: hex::decode(event.token1).unwrap(), + delta: BigInt::from_str(&e.amount_1) + .unwrap() + .neg() + .to_signed_bytes_be(), + component_id: address, + ord: event.log_ordinal, + tx: event.transaction.map(Into::into), + }, + ], + //Burn balance changes are accounted for in the Collect event. + pool_event::Type::Burn(_) => vec![], + pool_event::Type::Swap(e) => { + vec![ + BalanceDelta { + token: hex::decode(event.token0).unwrap(), + delta: BigInt::from_str(&e.amount_0) + .unwrap() + .to_signed_bytes_be(), + component_id: address.clone(), + ord: event.log_ordinal, + tx: event + .transaction + .as_ref() + .map(Into::into), + }, + BalanceDelta { + token: hex::decode(event.token1).unwrap(), + delta: BigInt::from_str(&e.amount_1) + .unwrap() + .to_signed_bytes_be(), + component_id: address, + ord: event.log_ordinal, + tx: event.transaction.map(Into::into), + }, + ] + } + pool_event::Type::Flash(e) => vec![ + BalanceDelta { + token: hex::decode(event.token0).unwrap(), + delta: BigInt::from_str(&e.paid_0) + .unwrap() + .to_signed_bytes_be(), + component_id: address.clone(), + ord: event.log_ordinal, + tx: event + .transaction + .as_ref() + .map(Into::into), + }, + BalanceDelta { + token: hex::decode(event.token1).unwrap(), + delta: BigInt::from_str(&e.paid_1) + .unwrap() + .to_signed_bytes_be(), + component_id: address, + ord: event.log_ordinal, + tx: event.transaction.map(Into::into), + }, + ], + pool_event::Type::CollectProtocol(e) => { + vec![ + BalanceDelta { + token: hex::decode(event.token0).unwrap(), + delta: BigInt::from_str(&e.amount_0) + .unwrap() + .neg() + .to_signed_bytes_be(), + component_id: address.clone(), + ord: event.log_ordinal, + tx: event + .transaction + .as_ref() + .map(Into::into), + }, + BalanceDelta { + token: hex::decode(event.token1).unwrap(), + delta: BigInt::from_str(&e.amount_1) + .unwrap() + .neg() + .to_signed_bytes_be(), + component_id: address, + ord: event.log_ordinal, + tx: event.transaction.map(Into::into), + }, + ] + } + _ => vec![], + } +} diff --git a/substreams/ethereum-pancakeswap-v3/src/modules/4_map_and_store_liquidity.rs b/substreams/ethereum-pancakeswap-v3/src/modules/4_map_and_store_liquidity.rs new file mode 100644 index 0000000..d1e7bfe --- /dev/null +++ b/substreams/ethereum-pancakeswap-v3/src/modules/4_map_and_store_liquidity.rs @@ -0,0 +1,137 @@ +use std::str::FromStr; + +use substreams::store::{ + StoreGet, StoreGetInt64, StoreSet, StoreSetInt64, StoreSetSum, StoreSetSumBigInt, +}; + +use crate::pb::pancakeswap::v3::{ + events::{pool_event, PoolEvent}, + Events, LiquidityChange, LiquidityChangeType, LiquidityChanges, +}; + +use substreams::{scalar::BigInt, store::StoreNew}; + +use anyhow::Ok; + +#[substreams::handlers::store] +pub fn store_pool_current_tick(events: Events, store: StoreSetInt64) { + events + .pool_events + .into_iter() + .filter_map(event_to_current_tick) + .for_each(|(pool, ordinal, new_tick_index)| { + store.set(ordinal, format!("pool:{0}", pool), &new_tick_index.into()) + }); +} + +#[substreams::handlers::map] +pub fn map_liquidity_changes( + events: Events, + pools_current_tick_store: StoreGetInt64, +) -> Result { + let mut changes = events + .pool_events + .into_iter() + .filter(PoolEvent::can_introduce_liquidity_changes) + .map(|e| { + ( + pools_current_tick_store + .get_at(e.log_ordinal, format!("pool:{0}", &e.pool_address)) + .unwrap_or(0), + e, + ) + }) + .filter_map(|(current_tick, event)| event_to_liquidity_deltas(current_tick, event)) + .collect::>(); + + changes.sort_unstable_by_key(|l| l.ordinal); + Ok(LiquidityChanges { changes }) +} + +#[substreams::handlers::store] +pub fn store_liquidity(ticks_deltas: LiquidityChanges, store: StoreSetSumBigInt) { + ticks_deltas + .changes + .iter() + .for_each(|changes| match changes.change_type() { + LiquidityChangeType::Delta => { + store.sum( + changes.ordinal, + format!("pool:{0}", hex::encode(&changes.pool_address)), + BigInt::from_signed_bytes_be(&changes.value), + ); + } + LiquidityChangeType::Absolute => { + store.set( + changes.ordinal, + format!("pool:{0}", hex::encode(&changes.pool_address)), + BigInt::from_signed_bytes_be(&changes.value), + ); + } + }); +} + +fn event_to_liquidity_deltas(current_tick: i64, event: PoolEvent) -> Option { + match event.r#type.as_ref().unwrap() { + pool_event::Type::Mint(mint) => { + if current_tick >= mint.tick_lower.into() && current_tick < mint.tick_upper.into() { + Some(LiquidityChange { + pool_address: hex::decode(event.pool_address).unwrap(), + value: BigInt::from_str(&mint.amount) + .unwrap() + .to_signed_bytes_be(), + change_type: LiquidityChangeType::Delta.into(), + ordinal: event.log_ordinal, + transaction: Some(event.transaction.unwrap()), + }) + } else { + None + } + } + pool_event::Type::Burn(burn) => { + if current_tick >= burn.tick_lower.into() && current_tick < burn.tick_upper.into() { + Some(LiquidityChange { + pool_address: hex::decode(event.pool_address).unwrap(), + value: BigInt::from_str(&burn.amount) + .unwrap() + .neg() + .to_signed_bytes_be(), + change_type: LiquidityChangeType::Delta.into(), + ordinal: event.log_ordinal, + transaction: Some(event.transaction.unwrap()), + }) + } else { + None + } + } + pool_event::Type::Swap(swap) => Some(LiquidityChange { + pool_address: hex::decode(event.pool_address).unwrap(), + value: BigInt::from_str(&swap.liquidity) + .unwrap() + .to_signed_bytes_be(), + change_type: LiquidityChangeType::Absolute.into(), + ordinal: event.log_ordinal, + transaction: Some(event.transaction.unwrap()), + }), + _ => None, + } +} + +impl PoolEvent { + fn can_introduce_liquidity_changes(&self) -> bool { + matches!( + self.r#type.as_ref().unwrap(), + pool_event::Type::Mint(_) | pool_event::Type::Burn(_) | pool_event::Type::Swap(_) + ) + } +} + +fn event_to_current_tick(event: PoolEvent) -> Option<(String, u64, i32)> { + match event.r#type.as_ref().unwrap() { + pool_event::Type::Initialize(initialize) => { + Some((event.pool_address, event.log_ordinal, initialize.tick)) + } + pool_event::Type::Swap(swap) => Some((event.pool_address, event.log_ordinal, swap.tick)), + _ => None, + } +} diff --git a/substreams/ethereum-pancakeswap-v3/src/modules/4_map_and_store_ticks.rs b/substreams/ethereum-pancakeswap-v3/src/modules/4_map_and_store_ticks.rs new file mode 100644 index 0000000..6b48be8 --- /dev/null +++ b/substreams/ethereum-pancakeswap-v3/src/modules/4_map_and_store_ticks.rs @@ -0,0 +1,91 @@ +use std::str::FromStr; + +use substreams::store::StoreAddBigInt; + +use crate::pb::pancakeswap::v3::{ + events::{pool_event, PoolEvent}, + Events, TickDelta, TickDeltas, +}; + +use substreams::{ + scalar::BigInt, + store::{StoreAdd, StoreNew}, +}; + +use anyhow::Ok; + +#[substreams::handlers::map] +pub fn map_ticks_changes(events: Events) -> Result { + let ticks_deltas = events + .pool_events + .into_iter() + .flat_map(event_to_ticks_deltas) + .collect(); + + Ok(TickDeltas { deltas: ticks_deltas }) +} + +#[substreams::handlers::store] +pub fn store_ticks_liquidity(ticks_deltas: TickDeltas, store: StoreAddBigInt) { + let mut deltas = ticks_deltas.deltas; + + deltas.sort_unstable_by_key(|delta| delta.ordinal); + + deltas.iter().for_each(|delta| { + store.add( + delta.ordinal, + format!("pool:{0}:tick:{1}", hex::encode(&delta.pool_address), delta.tick_index,), + BigInt::from_signed_bytes_be(&delta.liquidity_net_delta), + ); + }); +} + +fn event_to_ticks_deltas(event: PoolEvent) -> Vec { + match event.r#type.as_ref().unwrap() { + pool_event::Type::Mint(mint) => { + vec![ + TickDelta { + pool_address: hex::decode(&event.pool_address).unwrap(), + tick_index: mint.tick_lower, + liquidity_net_delta: BigInt::from_str(&mint.amount) + .unwrap() + .to_signed_bytes_be(), + ordinal: event.log_ordinal, + transaction: event.transaction.clone(), + }, + TickDelta { + pool_address: hex::decode(&event.pool_address).unwrap(), + tick_index: mint.tick_upper, + liquidity_net_delta: BigInt::from_str(&mint.amount) + .unwrap() + .neg() + .to_signed_bytes_be(), + ordinal: event.log_ordinal, + transaction: event.transaction, + }, + ] + } + pool_event::Type::Burn(burn) => vec![ + TickDelta { + pool_address: hex::decode(&event.pool_address).unwrap(), + tick_index: burn.tick_lower, + liquidity_net_delta: BigInt::from_str(&burn.amount) + .unwrap() + .neg() + .to_signed_bytes_be(), + ordinal: event.log_ordinal, + transaction: event.transaction.clone(), + }, + TickDelta { + pool_address: hex::decode(&event.pool_address).unwrap(), + tick_index: burn.tick_upper, + liquidity_net_delta: BigInt::from_str(&burn.amount) + .unwrap() + .to_signed_bytes_be(), + ordinal: event.log_ordinal, + transaction: event.transaction, + }, + ], + _ => vec![], + } +} diff --git a/substreams/ethereum-pancakeswap-v3/src/modules/5_map_protocol_changes.rs b/substreams/ethereum-pancakeswap-v3/src/modules/5_map_protocol_changes.rs new file mode 100644 index 0000000..8b09a3e --- /dev/null +++ b/substreams/ethereum-pancakeswap-v3/src/modules/5_map_protocol_changes.rs @@ -0,0 +1,287 @@ +use crate::pb::pancakeswap::v3::{ + events::{pool_event, PoolEvent}, + Events, LiquidityChanges, TickDeltas, +}; +use itertools::Itertools; +use std::{collections::HashMap, str::FromStr, vec}; +use substreams::{pb::substreams::StoreDeltas, scalar::BigInt}; +use substreams_ethereum::pb::eth::v2::{self as eth}; +use substreams_helper::hex::Hexable; +use tycho_substreams::{balances::aggregate_balances_changes, prelude::*}; + +type PoolAddress = Vec; + +#[substreams::handlers::map] +pub fn map_protocol_changes( + block: eth::Block, + created_pools: BlockChanges, + events: Events, + balances_map_deltas: BlockBalanceDeltas, + balances_store_deltas: StoreDeltas, + ticks_map_deltas: TickDeltas, + ticks_store_deltas: StoreDeltas, + pool_liquidity_changes: LiquidityChanges, + pool_liquidity_store_deltas: StoreDeltas, +) -> Result { + // We merge contract changes by transaction (identified by transaction index) making it easy to + // sort them at the very end. + let mut transaction_changes: HashMap<_, TransactionChangesBuilder> = HashMap::new(); + + // Add created pools to the tx_changes_map + for change in created_pools.changes.into_iter() { + let tx = change.tx.as_ref().unwrap(); + let builder = transaction_changes + .entry(tx.index) + .or_insert_with(|| TransactionChangesBuilder::new(tx)); + change + .component_changes + .iter() + .for_each(|c| { + builder.add_protocol_component(c); + }); + change + .entity_changes + .iter() + .for_each(|ec| { + builder.add_entity_change(ec); + }); + change + .balance_changes + .iter() + .for_each(|bc| { + builder.add_balance_change(bc); + }); + } + + // Balance changes are gathered by the `StoreDelta` based on `PoolBalanceChanged` creating + // `BlockBalanceDeltas`. We essentially just process the changes that occurred to the `store` + // this block. Then, these balance changes are merged onto the existing map of tx contract + // changes, inserting a new one if it doesn't exist. + aggregate_balances_changes(balances_store_deltas, balances_map_deltas) + .into_iter() + .for_each(|(_, (tx, balances))| { + let builder = transaction_changes + .entry(tx.index) + .or_insert_with(|| TransactionChangesBuilder::new(&tx)); + balances + .values() + .for_each(|token_bc_map| { + token_bc_map + .values() + .for_each(|bc| builder.add_balance_change(bc)) + }); + }); + + // Insert ticks net-liquidity changes + ticks_store_deltas + .deltas + .into_iter() + .zip(ticks_map_deltas.deltas) + .for_each(|(store_delta, tick_delta)| { + let new_value_bigint = + BigInt::from_str(&String::from_utf8(store_delta.new_value).unwrap()).unwrap(); + + // If old value is empty or the int value is 0, it's considered as a creation. + let is_creation = store_delta.old_value.is_empty() || + BigInt::from_str(&String::from_utf8(store_delta.old_value).unwrap()) + .unwrap() + .is_zero(); + let attribute_name = format!("ticks/{}/net-liquidity", tick_delta.tick_index); + let attribute = Attribute { + name: attribute_name, + value: new_value_bigint.to_signed_bytes_be(), + change: if is_creation { + ChangeType::Creation.into() + } else if new_value_bigint.is_zero() { + ChangeType::Deletion.into() + } else { + ChangeType::Update.into() + }, + }; + let tx = tick_delta.transaction.unwrap(); + let builder = transaction_changes + .entry(tx.index) + .or_insert_with(|| TransactionChangesBuilder::new(&tx.into())); + + builder.add_entity_change(&EntityChanges { + component_id: tick_delta.pool_address.to_hex(), + attributes: vec![attribute], + }); + }); + + // Insert liquidity changes + pool_liquidity_store_deltas + .deltas + .into_iter() + .zip(pool_liquidity_changes.changes) + .for_each(|(store_delta, change)| { + let new_value_bigint = BigInt::from_str( + String::from_utf8(store_delta.new_value) + .unwrap() + .split(':') + .nth(1) + .unwrap(), + ) + .unwrap(); + let tx = change.transaction.unwrap(); + let builder = transaction_changes + .entry(tx.index) + .or_insert_with(|| TransactionChangesBuilder::new(&tx.into())); + + builder.add_entity_change(&EntityChanges { + component_id: change.pool_address.to_hex(), + attributes: vec![Attribute { + name: "liquidity".to_string(), + value: new_value_bigint.to_signed_bytes_be(), + change: ChangeType::Update.into(), + }], + }); + }); + + // Insert others changes + events + .pool_events + .into_iter() + .flat_map(event_to_attributes_updates) + .for_each(|(tx, pool_address, attr)| { + let builder = transaction_changes + .entry(tx.index) + .or_insert_with(|| TransactionChangesBuilder::new(&tx)); + builder.add_entity_change(&EntityChanges { + component_id: pool_address.to_hex(), + attributes: vec![attr], + }); + }); + + Ok(BlockChanges { + block: Some((&block).into()), + changes: transaction_changes + .drain() + .sorted_unstable_by_key(|(index, _)| *index) + .filter_map(|(_, builder)| builder.build()) + .collect::>(), + }) +} + +fn event_to_attributes_updates(event: PoolEvent) -> Vec<(Transaction, PoolAddress, Attribute)> { + match event.r#type.as_ref().unwrap() { + pool_event::Type::Initialize(initalize) => { + let (zero_to_one, one_to_zero) = fee_to_default_protocol_fees(event.fee); + vec![ + ( + event + .transaction + .as_ref() + .unwrap() + .into(), + hex::decode(&event.pool_address).unwrap(), + Attribute { + name: "sqrt_price_x96".to_string(), + value: BigInt::from_str(&initalize.sqrt_price) + .unwrap() + .to_signed_bytes_be(), + change: ChangeType::Update.into(), + }, + ), + ( + event + .transaction + .as_ref() + .unwrap() + .into(), + hex::decode(&event.pool_address).unwrap(), + Attribute { + name: "tick".to_string(), + value: BigInt::from(initalize.tick).to_signed_bytes_be(), + change: ChangeType::Update.into(), + }, + ), + ( + event + .transaction + .as_ref() + .unwrap() + .into(), + hex::decode(&event.pool_address).unwrap(), + Attribute { + name: "protocol_fees/zeroForOne".to_string(), + value: BigInt::from(zero_to_one).to_signed_bytes_be(), + change: ChangeType::Update.into(), + }, + ), + ( + event.transaction.unwrap().into(), + hex::decode(event.pool_address).unwrap(), + Attribute { + name: "protocol_fees/oneForZero".to_string(), + value: BigInt::from(one_to_zero).to_signed_bytes_be(), + change: ChangeType::Update.into(), + }, + ), + ] + } + pool_event::Type::Swap(swap) => vec![ + ( + event + .transaction + .as_ref() + .unwrap() + .into(), + hex::decode(&event.pool_address).unwrap(), + Attribute { + name: "sqrt_price_x96".to_string(), + value: BigInt::from_str(&swap.sqrt_price) + .unwrap() + .to_signed_bytes_be(), + change: ChangeType::Update.into(), + }, + ), + ( + event.transaction.unwrap().into(), + hex::decode(event.pool_address).unwrap(), + Attribute { + name: "tick".to_string(), + value: BigInt::from(swap.tick).to_signed_bytes_be(), + change: ChangeType::Update.into(), + }, + ), + ], + pool_event::Type::SetFeeProtocol(sfp) => vec![ + ( + event + .transaction + .as_ref() + .unwrap() + .into(), + hex::decode(&event.pool_address).unwrap(), + Attribute { + name: "protocol_fees/zeroForOne".to_string(), + value: BigInt::from(sfp.fee_protocol_0_new).to_signed_bytes_be(), + change: ChangeType::Update.into(), + }, + ), + ( + event.transaction.unwrap().into(), + hex::decode(event.pool_address).unwrap(), + Attribute { + name: "protocol_fees/oneForZero".to_string(), + value: BigInt::from(sfp.fee_protocol_1_new).to_signed_bytes_be(), + change: ChangeType::Update.into(), + }, + ), + ], + _ => vec![], + } +} + +// Map the pool fee to the default protocol fees. +// For the reference implementation see https://github.com/pancakeswap/pancake-v3-contracts/blob/5cc479f0c5a98966c74d94700057b8c3ca629afd/projects/v3-core/contracts/PancakeV3Pool.sol#L298-L306 +fn fee_to_default_protocol_fees(fee: u64) -> (u64, u64) { + match fee { + 100 => (3300, 3300), + 500 => (3400, 3400), + 2500 => (3200, 3200), + 10000 => (3200, 3200), + _ => panic!("Unexpected fee value"), + } +} diff --git a/substreams/ethereum-pancakeswap-v3/src/modules/mod.rs b/substreams/ethereum-pancakeswap-v3/src/modules/mod.rs new file mode 100644 index 0000000..da4f395 --- /dev/null +++ b/substreams/ethereum-pancakeswap-v3/src/modules/mod.rs @@ -0,0 +1,61 @@ +pub use map_pool_created::map_pools_created; +pub use map_protocol_changes::map_protocol_changes; +pub use store_pools::store_pools; +use substreams_ethereum::pb::eth::v2::TransactionTrace; + +use crate::pb::pancakeswap::v3::Transaction; + +#[path = "1_map_pool_created.rs"] +mod map_pool_created; + +#[path = "2_store_pools.rs"] +mod store_pools; + +#[path = "3_map_events.rs"] +mod map_events; + +#[path = "4_map_and_store_balance_changes.rs"] +mod map_store_balance_changes; + +#[path = "4_map_and_store_ticks.rs"] +mod map_store_ticks; + +#[path = "4_map_and_store_liquidity.rs"] +mod map_store_liquidity; + +#[path = "5_map_protocol_changes.rs"] +mod map_protocol_changes; + +impl From for Transaction { + fn from(value: TransactionTrace) -> Self { + Self { hash: value.hash, from: value.from, to: value.to, index: value.index.into() } + } +} + +impl From<&TransactionTrace> for Transaction { + fn from(value: &TransactionTrace) -> Self { + Self { + hash: value.hash.clone(), + from: value.from.clone(), + to: value.to.clone(), + index: value.index.into(), + } + } +} + +impl From<&Transaction> for tycho_substreams::prelude::Transaction { + fn from(value: &Transaction) -> Self { + Self { + hash: value.hash.clone(), + from: value.from.clone(), + to: value.to.clone(), + index: value.index, + } + } +} + +impl From for tycho_substreams::prelude::Transaction { + fn from(value: Transaction) -> Self { + Self { hash: value.hash, from: value.from, to: value.to, index: value.index } + } +} diff --git a/substreams/ethereum-pancakeswap-v3/src/pb/mod.rs b/substreams/ethereum-pancakeswap-v3/src/pb/mod.rs new file mode 100644 index 0000000..d77a317 --- /dev/null +++ b/substreams/ethereum-pancakeswap-v3/src/pb/mod.rs @@ -0,0 +1,8 @@ +// @generated +pub mod pancakeswap { + // @@protoc_insertion_point(attribute:pancakeswap.v3) + pub mod v3 { + include!("pancakeswap.v3.rs"); + // @@protoc_insertion_point(pancakeswap.v3) + } +} diff --git a/substreams/ethereum-pancakeswap-v3/src/pb/pancakeswap.v3.rs b/substreams/ethereum-pancakeswap-v3/src/pb/pancakeswap.v3.rs new file mode 100644 index 0000000..d0eb8bb --- /dev/null +++ b/substreams/ethereum-pancakeswap-v3/src/pb/pancakeswap.v3.rs @@ -0,0 +1,302 @@ +// @generated +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Pool { + #[prost(bytes="vec", tag="1")] + pub address: ::prost::alloc::vec::Vec, + #[prost(bytes="vec", tag="2")] + pub token0: ::prost::alloc::vec::Vec, + #[prost(bytes="vec", tag="3")] + pub token1: ::prost::alloc::vec::Vec, + #[prost(uint64, tag="4")] + pub fee: u64, + #[prost(bytes="vec", tag="5")] + pub created_tx_hash: ::prost::alloc::vec::Vec, +} +/// A struct describing a transaction. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Transaction { + /// The transaction hash. + #[prost(bytes="vec", tag="1")] + pub hash: ::prost::alloc::vec::Vec, + /// The sender of the transaction. + #[prost(bytes="vec", tag="2")] + pub from: ::prost::alloc::vec::Vec, + /// The receiver of the transaction. + #[prost(bytes="vec", tag="3")] + pub to: ::prost::alloc::vec::Vec, + /// The transactions index within the block. + #[prost(uint64, tag="4")] + pub index: u64, +} +/// A change to a pool's tick. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TickDelta { + /// The address of the pool. + #[prost(bytes="vec", tag="1")] + pub pool_address: ::prost::alloc::vec::Vec, + /// The index of the tick. + #[prost(int32, tag="2")] + pub tick_index: i32, + /// The liquidity net delta of this tick. Bigint encoded as signed little endian bytes. + #[prost(bytes="vec", tag="3")] + pub liquidity_net_delta: ::prost::alloc::vec::Vec, + /// Used to determine the order of the balance changes. Necessary for the balance store. + #[prost(uint64, tag="4")] + pub ordinal: u64, + #[prost(message, optional, tag="5")] + pub transaction: ::core::option::Option, +} +/// A group of TickDelta +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TickDeltas { + #[prost(message, repeated, tag="1")] + pub deltas: ::prost::alloc::vec::Vec, +} +/// A change to a pool's liquidity. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct LiquidityChange { + /// The address of the pool. + #[prost(bytes="vec", tag="1")] + pub pool_address: ::prost::alloc::vec::Vec, + /// The liquidity changed amount. Bigint encoded as signed little endian bytes. + #[prost(bytes="vec", tag="2")] + pub value: ::prost::alloc::vec::Vec, + /// The type of update, can be absolute or delta. + #[prost(enumeration="LiquidityChangeType", tag="3")] + pub change_type: i32, + /// Used to determine the order of the balance changes. Necessary for the balance store. + #[prost(uint64, tag="4")] + pub ordinal: u64, + #[prost(message, optional, tag="5")] + pub transaction: ::core::option::Option, +} +/// A group of LiquidityChange +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct LiquidityChanges { + #[prost(message, repeated, tag="1")] + pub changes: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Events { + #[prost(message, repeated, tag="3")] + pub pool_events: ::prost::alloc::vec::Vec, +} +/// Nested message and enum types in `Events`. +pub mod events { + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] + pub struct PoolEvent { + #[prost(uint64, tag="100")] + pub log_ordinal: u64, + #[prost(string, tag="102")] + pub pool_address: ::prost::alloc::string::String, + #[prost(string, tag="103")] + pub token0: ::prost::alloc::string::String, + #[prost(string, tag="104")] + pub token1: ::prost::alloc::string::String, + #[prost(uint64, tag="105")] + pub fee: u64, + #[prost(message, optional, tag="106")] + pub transaction: ::core::option::Option, + #[prost(oneof="pool_event::Type", tags="1, 2, 3, 4, 5, 6, 7, 8")] + pub r#type: ::core::option::Option, + } + /// Nested message and enum types in `PoolEvent`. + pub mod pool_event { + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] + pub struct Initialize { + /// Unsigned + #[prost(string, tag="1")] + pub sqrt_price: ::prost::alloc::string::String, + #[prost(int32, tag="2")] + pub tick: i32, + } + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] + pub struct Mint { + #[prost(string, tag="1")] + pub sender: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub owner: ::prost::alloc::string::String, + /// Signed + #[prost(int32, tag="3")] + pub tick_lower: i32, + /// Signed + #[prost(int32, tag="4")] + pub tick_upper: i32, + /// Unsigned + #[prost(string, tag="5")] + pub amount: ::prost::alloc::string::String, + /// Unsigned + #[prost(string, tag="6")] + pub amount_0: ::prost::alloc::string::String, + /// Unsigned + #[prost(string, tag="7")] + pub amount_1: ::prost::alloc::string::String, + } + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] + pub struct Collect { + #[prost(string, tag="1")] + pub owner: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub recipient: ::prost::alloc::string::String, + #[prost(int32, tag="3")] + pub tick_lower: i32, + #[prost(int32, tag="4")] + pub tick_upper: i32, + /// Unsigned + #[prost(string, tag="5")] + pub amount_0: ::prost::alloc::string::String, + /// Unsigned + #[prost(string, tag="6")] + pub amount_1: ::prost::alloc::string::String, + } + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] + pub struct Burn { + #[prost(string, tag="1")] + pub owner: ::prost::alloc::string::String, + #[prost(int32, tag="2")] + pub tick_lower: i32, + #[prost(int32, tag="3")] + pub tick_upper: i32, + /// Unsigned + #[prost(string, tag="4")] + pub amount: ::prost::alloc::string::String, + /// Unsigned + #[prost(string, tag="5")] + pub amount_0: ::prost::alloc::string::String, + /// Unsigned + #[prost(string, tag="6")] + pub amount_1: ::prost::alloc::string::String, + } + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] + pub struct Swap { + #[prost(string, tag="1")] + pub sender: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub recipient: ::prost::alloc::string::String, + /// Signed + #[prost(string, tag="3")] + pub amount_0: ::prost::alloc::string::String, + /// Signed + #[prost(string, tag="4")] + pub amount_1: ::prost::alloc::string::String, + /// Unsigned + #[prost(string, tag="6")] + pub sqrt_price: ::prost::alloc::string::String, + /// Unsigned + #[prost(string, tag="7")] + pub liquidity: ::prost::alloc::string::String, + #[prost(int32, tag="8")] + pub tick: i32, + } + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] + pub struct Flash { + #[prost(string, tag="1")] + pub sender: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub recipient: ::prost::alloc::string::String, + /// Unsigned + #[prost(string, tag="3")] + pub amount_0: ::prost::alloc::string::String, + /// Unsigned + #[prost(string, tag="4")] + pub amount_1: ::prost::alloc::string::String, + /// Unsigned + #[prost(string, tag="5")] + pub paid_0: ::prost::alloc::string::String, + /// Unsigned + #[prost(string, tag="6")] + pub paid_1: ::prost::alloc::string::String, + } + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] + pub struct SetFeeProtocol { + /// Unsigned + #[prost(uint64, tag="1")] + pub fee_protocol_0_old: u64, + /// Unsigned + #[prost(uint64, tag="2")] + pub fee_protocol_1_old: u64, + /// Unsigned + #[prost(uint64, tag="3")] + pub fee_protocol_0_new: u64, + /// Unsigned + #[prost(uint64, tag="4")] + pub fee_protocol_1_new: u64, + } + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] + pub struct CollectProtocol { + #[prost(string, tag="1")] + pub sender: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub recipient: ::prost::alloc::string::String, + /// Unsigned + #[prost(string, tag="3")] + pub amount_0: ::prost::alloc::string::String, + /// Unsigned + #[prost(string, tag="4")] + pub amount_1: ::prost::alloc::string::String, + } + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Type { + #[prost(message, tag="1")] + Initialize(Initialize), + #[prost(message, tag="2")] + Mint(Mint), + #[prost(message, tag="3")] + Collect(Collect), + #[prost(message, tag="4")] + Burn(Burn), + #[prost(message, tag="5")] + Swap(Swap), + #[prost(message, tag="6")] + Flash(Flash), + #[prost(message, tag="7")] + SetFeeProtocol(SetFeeProtocol), + #[prost(message, tag="8")] + CollectProtocol(CollectProtocol), + } + } +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum LiquidityChangeType { + Delta = 0, + Absolute = 1, +} +impl LiquidityChangeType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + LiquidityChangeType::Delta => "DELTA", + LiquidityChangeType::Absolute => "ABSOLUTE", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "DELTA" => Some(Self::Delta), + "ABSOLUTE" => Some(Self::Absolute), + _ => None, + } + } +} +// @@protoc_insertion_point(module) diff --git a/substreams/rustfmt.toml b/substreams/rustfmt.toml index 42cdd4f..6b2ceae 100644 --- a/substreams/rustfmt.toml +++ b/substreams/rustfmt.toml @@ -18,5 +18,6 @@ ignore = [ "ethereum-uniswap-v2/src/abi", "ethereum-uniswap-v3/src/abi", "ethereum-uniswap-v3-logs-only/src/abi", + "ethereum-pancakeswap-v3/src/abi", "ethereum-uniswap-v4/src/abi", ]