From 0d403cfdd61753b7dd0bc7e0ccff81825de0785a Mon Sep 17 00:00:00 2001 From: saucepoint Date: Wed, 18 Oct 2023 13:55:11 -0400 Subject: [PATCH] first pass on pool initialization --- src/pages/initialize/PoolInitialize.sol | 38 + .../PoolInitializeExampleInputs.sol | 68 ++ src/pages/initialize/index.html.ts | 138 +++ src/pages/initialize/index.md | 20 + src/pages/initialize/index.tsx | 29 + src/routes.tsx | 847 +++++++++--------- 6 files changed, 719 insertions(+), 421 deletions(-) create mode 100644 src/pages/initialize/PoolInitialize.sol create mode 100644 src/pages/initialize/PoolInitializeExampleInputs.sol create mode 100644 src/pages/initialize/index.html.ts create mode 100644 src/pages/initialize/index.md create mode 100644 src/pages/initialize/index.tsx diff --git a/src/pages/initialize/PoolInitialize.sol b/src/pages/initialize/PoolInitialize.sol new file mode 100644 index 000000000..52e59cc9a --- /dev/null +++ b/src/pages/initialize/PoolInitialize.sol @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +import {IPoolManager} from "@uniswap/v4-core/contracts/interfaces/IPoolManager.sol"; +import {IHooks} from "@uniswap/v4-core/contracts/interfaces/IHooks.sol"; +import {PoolKey} from "@uniswap/v4-core/contracts/types/PoolKey.sol"; +import {CurrencyLibrary, Currency} from "@uniswap/v4-core/contracts/types/Currency.sol"; + +contract PoolInitialize { + using CurrencyLibrary for Currency; + + // set the pool manager address + IPoolManager manager = IPoolManager(0x01); + + function init( + address token0, + address token1, + uint24 swapFee, + int24 tickSpacing, + address hook, + uint160 sqrtPriceX96, + bytes calldata hookData + ) external { + // sort your tokens! v4 expects: token0 < token1 + if (token0 > token1) { + (token0, token1) = (token1, token0); + } + + PoolKey memory pool = PoolKey({ + currency0: Currency(token0), + currency1: Currency(token1), + fee: swapFee, + tickSpacing: tickSpacing, + hooks: IHooks(hook) + }); + manager.initialize(pool, sqrtPriceX96, hookData); + } +} diff --git a/src/pages/initialize/PoolInitializeExampleInputs.sol b/src/pages/initialize/PoolInitializeExampleInputs.sol new file mode 100644 index 000000000..da602622b --- /dev/null +++ b/src/pages/initialize/PoolInitializeExampleInputs.sol @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +import {IPoolManager} from "@uniswap/v4-core/contracts/interfaces/IPoolManager.sol"; +import {IHooks} from "@uniswap/v4-core/contracts/interfaces/IHooks.sol"; +import {PoolKey} from "@uniswap/v4-core/contracts/types/PoolKey.sol"; +import {CurrencyLibrary, Currency} from "@uniswap/v4-core/contracts/types/Currency.sol"; + +contract PoolInitializeExampleInputs { + using CurrencyLibrary for Currency; + + // set the pool manager address + IPoolManager manager = IPoolManager(0x01); + + /// @notice Initialize a hookless pool: + /// 0.05% swap fee + /// tick spacing of 10 + /// starting price of 1:1 + function exampleA() external { + address token0 = address(0x11); + address token1 = address(0x22); + uint24 swapFee = 500; + int24 tickSpacing = 10; + + // floor(sqrt(1) * 2^96) + uint160 startingPrice = 79228162514264337593543950336; + + // hookless pool doesnt expect any initialization data + bytes memory hookData = new bytes(0); + + PoolKey memory pool = PoolKey({ + currency0: Currency(token0), + currency1: Currency(token1), + fee: swapFee, + tickSpacing: tickSpacing, + hooks: IHooks(address(0x0)) + }); + manager.initialize(pool, startingPrice, hookData); + } + + /// @notice Initialize a pool with a custom hook: + /// 0.30% swap fee + /// tick spacing of 60 + /// starting price of 1:1 + /// hook's beforeInitialize() requires providing a timestamp + function exampleB() external { + address hook = address(0x80); // prefix indicates the hook only has a beforeInitialize() function + address token0 = address(0x11); + address token1 = address(0x22); + uint24 swapFee = 3000; + int24 tickSpacing = 60; + + // floor(sqrt(1) * 2^96) + uint160 startingPrice = 79228162514264337593543950336; + + // Custom hook requires a timestamp when initializing it + bytes memory hookData = abi.encode(block.timestamp); + + PoolKey memory pool = PoolKey({ + currency0: Currency(token0), + currency1: Currency(token1), + fee: swapFee, + tickSpacing: tickSpacing, + hooks: IHooks(hook) + }); + manager.initialize(pool, startingPrice, hookData); + } +} diff --git a/src/pages/initialize/index.html.ts b/src/pages/initialize/index.html.ts new file mode 100644 index 000000000..0de73daf9 --- /dev/null +++ b/src/pages/initialize/index.html.ts @@ -0,0 +1,138 @@ +// metadata +export const version = "0.8.20" +export const title = "Pool Initialization" +export const description = "Initializing a pool in Uniswap v4" + +export const keywords = [ + "pool", + "initialize", + "init", + "create", + "pair", + "factory", +] + +export const codes = [ + { + fileName: "PoolInitialize.sol", + code: "Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVApwcmFnbWEgc29saWRpdHkgXjAuOC4yMDsKCmltcG9ydCB7SVBvb2xNYW5hZ2VyfSBmcm9tICJAdW5pc3dhcC92NC1jb3JlL2NvbnRyYWN0cy9pbnRlcmZhY2VzL0lQb29sTWFuYWdlci5zb2wiOwppbXBvcnQge0lIb29rc30gZnJvbSAiQHVuaXN3YXAvdjQtY29yZS9jb250cmFjdHMvaW50ZXJmYWNlcy9JSG9va3Muc29sIjsKaW1wb3J0IHtQb29sS2V5fSBmcm9tICJAdW5pc3dhcC92NC1jb3JlL2NvbnRyYWN0cy90eXBlcy9Qb29sS2V5LnNvbCI7CmltcG9ydCB7Q3VycmVuY3lMaWJyYXJ5LCBDdXJyZW5jeX0gZnJvbSAiQHVuaXN3YXAvdjQtY29yZS9jb250cmFjdHMvdHlwZXMvQ3VycmVuY3kuc29sIjsKCmNvbnRyYWN0IFBvb2xJbml0aWFsaXplIHsKICAgIHVzaW5nIEN1cnJlbmN5TGlicmFyeSBmb3IgQ3VycmVuY3k7CgogICAgLy8gc2V0IHRoZSBwb29sIG1hbmFnZXIgYWRkcmVzcwogICAgSVBvb2xNYW5hZ2VyIG1hbmFnZXIgPSBJUG9vbE1hbmFnZXIoMHgwMSk7CgogICAgZnVuY3Rpb24gaW5pdCgKICAgICAgICBhZGRyZXNzIHRva2VuMCwKICAgICAgICBhZGRyZXNzIHRva2VuMSwKICAgICAgICB1aW50MjQgc3dhcEZlZSwKICAgICAgICBpbnQyNCB0aWNrU3BhY2luZywKICAgICAgICBhZGRyZXNzIGhvb2ssCiAgICAgICAgdWludDE2MCBzcXJ0UHJpY2VYOTYsCiAgICAgICAgYnl0ZXMgY2FsbGRhdGEgaG9va0RhdGEKICAgICkgZXh0ZXJuYWwgewogICAgICAgIC8vIHNvcnQgeW91ciB0b2tlbnMhIHY0IGV4cGVjdHM6IHRva2VuMCA8IHRva2VuMQogICAgICAgIGlmICh0b2tlbjAgPiB0b2tlbjEpIHsKICAgICAgICAgICAgKHRva2VuMCwgdG9rZW4xKSA9ICh0b2tlbjEsIHRva2VuMCk7CiAgICAgICAgfQoKICAgICAgICBQb29sS2V5IG1lbW9yeSBwb29sID0gUG9vbEtleSh7CiAgICAgICAgICAgIGN1cnJlbmN5MDogQ3VycmVuY3kodG9rZW4wKSwKICAgICAgICAgICAgY3VycmVuY3kxOiBDdXJyZW5jeSh0b2tlbjEpLAogICAgICAgICAgICBmZWU6IHN3YXBGZWUsCiAgICAgICAgICAgIHRpY2tTcGFjaW5nOiB0aWNrU3BhY2luZywKICAgICAgICAgICAgaG9va3M6IElIb29rcyhob29rKQogICAgICAgIH0pOwogICAgICAgIG1hbmFnZXIuaW5pdGlhbGl6ZShwb29sLCBzcXJ0UHJpY2VYOTYsIGhvb2tEYXRhKTsKICAgIH0KfQo=", + }, + { + fileName: "PoolInitializeExampleInputs.sol", + code: "Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVApwcmFnbWEgc29saWRpdHkgXjAuOC4yMDsKCmltcG9ydCB7SVBvb2xNYW5hZ2VyfSBmcm9tICJAdW5pc3dhcC92NC1jb3JlL2NvbnRyYWN0cy9pbnRlcmZhY2VzL0lQb29sTWFuYWdlci5zb2wiOwppbXBvcnQge0lIb29rc30gZnJvbSAiQHVuaXN3YXAvdjQtY29yZS9jb250cmFjdHMvaW50ZXJmYWNlcy9JSG9va3Muc29sIjsKaW1wb3J0IHtQb29sS2V5fSBmcm9tICJAdW5pc3dhcC92NC1jb3JlL2NvbnRyYWN0cy90eXBlcy9Qb29sS2V5LnNvbCI7CmltcG9ydCB7Q3VycmVuY3lMaWJyYXJ5LCBDdXJyZW5jeX0gZnJvbSAiQHVuaXN3YXAvdjQtY29yZS9jb250cmFjdHMvdHlwZXMvQ3VycmVuY3kuc29sIjsKCmNvbnRyYWN0IFBvb2xJbml0aWFsaXplRXhhbXBsZUlucHV0cyB7CiAgICB1c2luZyBDdXJyZW5jeUxpYnJhcnkgZm9yIEN1cnJlbmN5OwoKICAgIC8vIHNldCB0aGUgcG9vbCBtYW5hZ2VyIGFkZHJlc3MKICAgIElQb29sTWFuYWdlciBtYW5hZ2VyID0gSVBvb2xNYW5hZ2VyKDB4MDEpOwoKICAgIC8vLyBAbm90aWNlIEluaXRpYWxpemUgYSBob29rbGVzcyBwb29sOgogICAgLy8vICAgICAwLjA1JSBzd2FwIGZlZQogICAgLy8vICAgICB0aWNrIHNwYWNpbmcgb2YgMTAKICAgIC8vLyAgICAgc3RhcnRpbmcgcHJpY2Ugb2YgMToxCiAgICBmdW5jdGlvbiBleGFtcGxlQSgpIGV4dGVybmFsIHsKICAgICAgICBhZGRyZXNzIHRva2VuMCA9IGFkZHJlc3MoMHgxMSk7CiAgICAgICAgYWRkcmVzcyB0b2tlbjEgPSBhZGRyZXNzKDB4MjIpOwogICAgICAgIHVpbnQyNCBzd2FwRmVlID0gNTAwOwogICAgICAgIGludDI0IHRpY2tTcGFjaW5nID0gMTA7CgogICAgICAgIC8vIGZsb29yKHNxcnQoMSkgKiAyXjk2KQogICAgICAgIHVpbnQxNjAgc3RhcnRpbmdQcmljZSA9IDc5MjI4MTYyNTE0MjY0MzM3NTkzNTQzOTUwMzM2OwoKICAgICAgICAvLyBob29rbGVzcyBwb29sIGRvZXNudCBleHBlY3QgYW55IGluaXRpYWxpemF0aW9uIGRhdGEKICAgICAgICBieXRlcyBtZW1vcnkgaG9va0RhdGEgPSBuZXcgYnl0ZXMoMCk7CgogICAgICAgIFBvb2xLZXkgbWVtb3J5IHBvb2wgPSBQb29sS2V5KHsKICAgICAgICAgICAgY3VycmVuY3kwOiBDdXJyZW5jeSh0b2tlbjApLAogICAgICAgICAgICBjdXJyZW5jeTE6IEN1cnJlbmN5KHRva2VuMSksCiAgICAgICAgICAgIGZlZTogc3dhcEZlZSwKICAgICAgICAgICAgdGlja1NwYWNpbmc6IHRpY2tTcGFjaW5nLAogICAgICAgICAgICBob29rczogSUhvb2tzKGFkZHJlc3MoMHgwKSkKICAgICAgICB9KTsKICAgICAgICBtYW5hZ2VyLmluaXRpYWxpemUocG9vbCwgc3RhcnRpbmdQcmljZSwgaG9va0RhdGEpOwogICAgfQoKICAgIC8vLyBAbm90aWNlIEluaXRpYWxpemUgYSBwb29sIHdpdGggYSBjdXN0b20gaG9vazoKICAgIC8vLyAgICAgMC4zMCUgc3dhcCBmZWUKICAgIC8vLyAgICAgdGljayBzcGFjaW5nIG9mIDYwCiAgICAvLy8gICAgIHN0YXJ0aW5nIHByaWNlIG9mIDE6MQogICAgLy8vICAgICBob29rJ3MgYmVmb3JlSW5pdGlhbGl6ZSgpIHJlcXVpcmVzIHByb3ZpZGluZyBhIHRpbWVzdGFtcAogICAgZnVuY3Rpb24gZXhhbXBsZUIoKSBleHRlcm5hbCB7CiAgICAgICAgYWRkcmVzcyBob29rID0gYWRkcmVzcygweDgwKTsgLy8gcHJlZml4IGluZGljYXRlcyB0aGUgaG9vayBvbmx5IGhhcyBhIGJlZm9yZUluaXRpYWxpemUoKSBmdW5jdGlvbgogICAgICAgIGFkZHJlc3MgdG9rZW4wID0gYWRkcmVzcygweDExKTsKICAgICAgICBhZGRyZXNzIHRva2VuMSA9IGFkZHJlc3MoMHgyMik7CiAgICAgICAgdWludDI0IHN3YXBGZWUgPSAzMDAwOwogICAgICAgIGludDI0IHRpY2tTcGFjaW5nID0gNjA7CgogICAgICAgIC8vIGZsb29yKHNxcnQoMSkgKiAyXjk2KQogICAgICAgIHVpbnQxNjAgc3RhcnRpbmdQcmljZSA9IDc5MjI4MTYyNTE0MjY0MzM3NTkzNTQzOTUwMzM2OwoKICAgICAgICAvLyBDdXN0b20gaG9vayByZXF1aXJlcyBhIHRpbWVzdGFtcCB3aGVuIGluaXRpYWxpemluZyBpdAogICAgICAgIGJ5dGVzIG1lbW9yeSBob29rRGF0YSA9IGFiaS5lbmNvZGUoYmxvY2sudGltZXN0YW1wKTsKCiAgICAgICAgUG9vbEtleSBtZW1vcnkgcG9vbCA9IFBvb2xLZXkoewogICAgICAgICAgICBjdXJyZW5jeTA6IEN1cnJlbmN5KHRva2VuMCksCiAgICAgICAgICAgIGN1cnJlbmN5MTogQ3VycmVuY3kodG9rZW4xKSwKICAgICAgICAgICAgZmVlOiBzd2FwRmVlLAogICAgICAgICAgICB0aWNrU3BhY2luZzogdGlja1NwYWNpbmcsCiAgICAgICAgICAgIGhvb2tzOiBJSG9va3MoaG9vaykKICAgICAgICB9KTsKICAgICAgICBtYW5hZ2VyLmluaXRpYWxpemUocG9vbCwgc3RhcnRpbmdQcmljZSwgaG9va0RhdGEpOwogICAgfQp9Cg==", + }, +] + +const html = `

A single trading pair (ETH/USDC), can exist as an infinite number of pools in v4. Uniswap v4 does not restrict fee tiers to 1%, 0.30%, or 0.05%. The same trading pair can also have an infinite number of hooks.

+

Initializing a V3 Pair involved deploying a contract via the factory. In V4, pools are initialized and managed by a single contract: PoolManager

+
// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {IPoolManager} from "@uniswap/v4-core/contracts/interfaces/IPoolManager.sol";
+import {IHooks} from "@uniswap/v4-core/contracts/interfaces/IHooks.sol";
+import {PoolKey} from "@uniswap/v4-core/contracts/types/PoolKey.sol";
+import {CurrencyLibrary, Currency} from "@uniswap/v4-core/contracts/types/Currency.sol";
+
+contract PoolInitialize {
+    using CurrencyLibrary for Currency;
+
+    // set the pool manager address
+    IPoolManager manager = IPoolManager(0x01);
+
+    function init(
+        address token0,
+        address token1,
+        uint24 swapFee,
+        int24 tickSpacing,
+        address hook,
+        uint160 sqrtPriceX96,
+        bytes calldata hookData
+    ) external {
+        // sort your tokens! v4 expects: token0 < token1
+        if (token0 > token1) {
+            (token0, token1) = (token1, token0);
+        }
+
+        PoolKey memory pool = PoolKey({
+            currency0: Currency(token0),
+            currency1: Currency(token1),
+            fee: swapFee,
+            tickSpacing: tickSpacing,
+            hooks: IHooks(hook)
+        });
+        manager.initialize(pool, sqrtPriceX96, hookData);
+    }
+}
+

Examples of Initializing a V4 Pool

+

Remove array element by shifting elements from right to left

+
// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {IPoolManager} from "@uniswap/v4-core/contracts/interfaces/IPoolManager.sol";
+import {IHooks} from "@uniswap/v4-core/contracts/interfaces/IHooks.sol";
+import {PoolKey} from "@uniswap/v4-core/contracts/types/PoolKey.sol";
+import {CurrencyLibrary, Currency} from "@uniswap/v4-core/contracts/types/Currency.sol";
+
+contract PoolInitializeExampleInputs {
+    using CurrencyLibrary for Currency;
+
+    // set the pool manager address
+    IPoolManager manager = IPoolManager(0x01);
+
+    /// @notice Initialize a hookless pool:
+    ///     0.05% swap fee
+    ///     tick spacing of 10
+    ///     starting price of 1:1
+    function exampleA() external {
+        address token0 = address(0x11);
+        address token1 = address(0x22);
+        uint24 swapFee = 500;
+        int24 tickSpacing = 10;
+
+        // floor(sqrt(1) * 2^96)
+        uint160 startingPrice = 79228162514264337593543950336;
+
+        // hookless pool doesnt expect any initialization data
+        bytes memory hookData = new bytes(0);
+
+        PoolKey memory pool = PoolKey({
+            currency0: Currency(token0),
+            currency1: Currency(token1),
+            fee: swapFee,
+            tickSpacing: tickSpacing,
+            hooks: IHooks(address(0x0))
+        });
+        manager.initialize(pool, startingPrice, hookData);
+    }
+
+    /// @notice Initialize a pool with a custom hook:
+    ///     0.30% swap fee
+    ///     tick spacing of 60
+    ///     starting price of 1:1
+    ///     hook's beforeInitialize() requires providing a timestamp
+    function exampleB() external {
+        address hook = address(0x80); // prefix indicates the hook only has a beforeInitialize() function
+        address token0 = address(0x11);
+        address token1 = address(0x22);
+        uint24 swapFee = 3000;
+        int24 tickSpacing = 60;
+
+        // floor(sqrt(1) * 2^96)
+        uint160 startingPrice = 79228162514264337593543950336;
+
+        // Custom hook requires a timestamp when initializing it
+        bytes memory hookData = abi.encode(block.timestamp);
+
+        PoolKey memory pool = PoolKey({
+            currency0: Currency(token0),
+            currency1: Currency(token1),
+            fee: swapFee,
+            tickSpacing: tickSpacing,
+            hooks: IHooks(hook)
+        });
+        manager.initialize(pool, startingPrice, hookData);
+    }
+}
+
` + +export default html diff --git a/src/pages/initialize/index.md b/src/pages/initialize/index.md new file mode 100644 index 000000000..a3a6095db --- /dev/null +++ b/src/pages/initialize/index.md @@ -0,0 +1,20 @@ +--- +title: Pool Initialization +version: 0.8.20 +description: Initializing a pool in Uniswap v4 +keywords: [pool, initialize, init, create, pair, factory] +--- + +A single trading pair (ETH/USDC), can exist as an infinite number of pools in v4. Uniswap v4 does **not** restrict fee tiers to 1%, 0.30%, or 0.05%. The same trading pair can also have an infinite number of hooks. + +Initializing a V3 Pair involved deploying a contract via the factory. In V4, pools are initialized and managed by a single contract: `PoolManager` + +```solidity +{{{PoolInitialize}}} +``` + +### Examples of Initializing a V4 Pool + +```solidity +{{{PoolInitializeExampleInputs}}} +``` diff --git a/src/pages/initialize/index.tsx b/src/pages/initialize/index.tsx new file mode 100644 index 000000000..e44c294e3 --- /dev/null +++ b/src/pages/initialize/index.tsx @@ -0,0 +1,29 @@ +import React from "react" +import Example from "../../components/Example" +import html, { version, title, description, codes } from "./index.html" + +interface Path { + path: string + title: string +} + +interface Props { + prev: Path | null + next: Path | null +} + +const ExamplePage: React.FC = ({ prev, next }) => { + return ( + + ) +} + +export default ExamplePage diff --git a/src/routes.tsx b/src/routes.tsx index 54346092c..bf049794c 100644 --- a/src/routes.tsx +++ b/src/routes.tsx @@ -83,6 +83,7 @@ import component_if_else from "./pages/if-else" import component_immutable from "./pages/immutable" import component_import from "./pages/import" import component_inheritance from "./pages/inheritance" +import component_initialize from "./pages/initialize" import component_interface from "./pages/interface" import component_library from "./pages/library" import component_loop from "./pages/loop" @@ -121,426 +122,430 @@ interface Route { } const routes: Route[] = [ - { - path: "/abi-decode", - component: component_abi_decode, - }, - { - path: "/abi-encode", - component: component_abi_encode, - }, - { - path: "/app/assembly-bin-exp", - component: component_app_assembly_bin_exp, - }, - { - path: "/app/bi-directional-payment-channel", - component: component_app_bi_directional_payment_channel, - }, - { - path: "/app/create2", - component: component_app_create2, - }, - { - path: "/app/crowd-fund", - component: component_app_crowd_fund, - }, - { - path: "/app/deploy-any-contract", - component: component_app_deploy_any_contract, - }, - { - path: "/app/dutch-auction", - component: component_app_dutch_auction, - }, - { - path: "/app/english-auction", - component: component_app_english_auction, - }, - { - path: "/app/erc1155", - component: component_app_erc1155, - }, - { - path: "/app/erc20", - component: component_app_erc20, - }, - { - path: "/app/erc721", - component: component_app_erc721, - }, - { - path: "/app/ether-wallet", - component: component_app_ether_wallet, - }, - { - path: "/app/gasless-token-transfer", - component: component_app_gasless_token_transfer, - }, - { - path: "/app/iterable-mapping", - component: component_app_iterable_mapping, - }, - { - path: "/app/merkle-tree", - component: component_app_merkle_tree, - }, - { - path: "/app/minimal-proxy", - component: component_app_minimal_proxy, - }, - { - path: "/app/multi-call", - component: component_app_multi_call, - }, - { - path: "/app/multi-delegatecall", - component: component_app_multi_delegatecall, - }, - { - path: "/app/multi-sig-wallet", - component: component_app_multi_sig_wallet, - }, - { - path: "/app/simple-bytecode-contract", - component: component_app_simple_bytecode_contract, - }, - { - path: "/app/time-lock", - component: component_app_time_lock, - }, - { - path: "/app/uni-directional-payment-channel", - component: component_app_uni_directional_payment_channel, - }, - { - path: "/app/upgradeable-proxy", - component: component_app_upgradeable_proxy, - }, - { - path: "/app/write-to-any-slot", - component: component_app_write_to_any_slot, - }, - { - path: "/array", - component: component_array, - }, - { - path: "/assembly-error", - component: component_assembly_error, - }, - { - path: "/assembly-if", - component: component_assembly_if, - }, - { - path: "/assembly-loop", - component: component_assembly_loop, - }, - { - path: "/assembly-math", - component: component_assembly_math, - }, - { - path: "/assembly-variable", - component: component_assembly_variable, - }, - { - path: "/bitwise", - component: component_bitwise, - }, - { - path: "/call", - component: component_call, - }, - { - path: "/calling-contract", - component: component_calling_contract, - }, - { - path: "/constants", - component: component_constants, - }, - { - path: "/constructor", - component: component_constructor, - }, - { - path: "/data-locations", - component: component_data_locations, - }, - { - path: "/defi/chainlink-price-oracle", - component: component_defi_chainlink_price_oracle, - }, - { - path: "/defi/constant-product-amm", - component: component_defi_constant_product_amm, - }, - { - path: "/defi/constant-sum-amm", - component: component_defi_constant_sum_amm, - }, - { - path: "/defi/discrete-staking-rewards", - component: component_defi_discrete_staking_rewards, - }, - { - path: "/defi/stable-swap-amm", - component: component_defi_stable_swap_amm, - }, - { - path: "/defi/staking-rewards", - component: component_defi_staking_rewards, - }, - { - path: "/defi/uniswap-v2", - component: component_defi_uniswap_v2, - }, - { - path: "/defi/uniswap-v2-add-remove-liquidity", - component: component_defi_uniswap_v2_add_remove_liquidity, - }, - { - path: "/defi/uniswap-v2-flash-swap", - component: component_defi_uniswap_v2_flash_swap, - }, - { - path: "/defi/uniswap-v2-optimal-one-sided-supply", - component: component_defi_uniswap_v2_optimal_one_sided_supply, - }, - { - path: "/defi/uniswap-v3-flash", - component: component_defi_uniswap_v3_flash, - }, - { - path: "/defi/uniswap-v3-flash-swap", - component: component_defi_uniswap_v3_flash_swap, - }, - { - path: "/defi/uniswap-v3-liquidity", - component: component_defi_uniswap_v3_liquidity, - }, - { - path: "/defi/uniswap-v3-swap", - component: component_defi_uniswap_v3_swap, - }, - { - path: "/defi/vault", - component: component_defi_vault, - }, - { - path: "/delegatecall", - component: component_delegatecall, - }, - { - path: "/enum", - component: component_enum, - }, - { - path: "/error", - component: component_error, - }, - { - path: "/ether-units", - component: component_ether_units, - }, - { - path: "/events", - component: component_events, - }, - { - path: "/fallback", - component: component_fallback, - }, - { - path: "/first-app", - component: component_first_app, - }, - { - path: "/function", - component: component_function, - }, - { - path: "/function-modifier", - component: component_function_modifier, - }, - { - path: "/function-selector", - component: component_function_selector, - }, - { - path: "/gas", - component: component_gas, - }, - { - path: "/gas-golf", - component: component_gas_golf, - }, - { - path: "/hacks/accessing-private-data", - component: component_hacks_accessing_private_data, - }, - { - path: "/hacks/block-timestamp-manipulation", - component: component_hacks_block_timestamp_manipulation, - }, - { - path: "/hacks/contract-size", - component: component_hacks_contract_size, - }, - { - path: "/hacks/delegatecall", - component: component_hacks_delegatecall, - }, - { - path: "/hacks/denial-of-service", - component: component_hacks_denial_of_service, - }, - { - path: "/hacks/deploy-different-contracts-same-address", - component: component_hacks_deploy_different_contracts_same_address, - }, - { - path: "/hacks/front-running", - component: component_hacks_front_running, - }, - { - path: "/hacks/hiding-malicious-code-with-external-contract", - component: component_hacks_hiding_malicious_code_with_external_contract, - }, - { - path: "/hacks/honeypot", - component: component_hacks_honeypot, - }, - { - path: "/hacks/overflow", - component: component_hacks_overflow, - }, - { - path: "/hacks/phishing-with-tx-origin", - component: component_hacks_phishing_with_tx_origin, - }, - { - path: "/hacks/randomness", - component: component_hacks_randomness, - }, - { - path: "/hacks/re-entrancy", - component: component_hacks_re_entrancy, - }, - { - path: "/hacks/self-destruct", - component: component_hacks_self_destruct, - }, - { - path: "/hacks/signature-replay", - component: component_hacks_signature_replay, - }, - { - path: "/hashing", - component: component_hashing, - }, - { - path: "/hello-world", - component: component_hello_world, - }, - { - path: "/if-else", - component: component_if_else, - }, - { - path: "/immutable", - component: component_immutable, - }, - { - path: "/import", - component: component_import, - }, - { - path: "/inheritance", - component: component_inheritance, - }, - { - path: "/interface", - component: component_interface, - }, - { - path: "/library", - component: component_library, - }, - { - path: "/loop", - component: component_loop, - }, - { - path: "/mapping", - component: component_mapping, - }, - { - path: "/new-contract", - component: component_new_contract, - }, - { - path: "/payable", - component: component_payable, - }, - { - path: "/primitives", - component: component_primitives, - }, - { - path: "/sending-ether", - component: component_sending_ether, - }, - { - path: "/shadowing-inherited-state-variables", - component: component_shadowing_inherited_state_variables, - }, - { - path: "/signature", - component: component_signature, - }, - { - path: "/state-variables", - component: component_state_variables, - }, - { - path: "/structs", - component: component_structs, - }, - { - path: "/super", - component: component_super, - }, - { - path: "/tests/echidna", - component: component_tests_echidna, - }, - { - path: "/try-catch", - component: component_try_catch, - }, - { - path: "/unchecked-math", - component: component_unchecked_math, - }, - { - path: "/variables", - component: component_variables, - }, - { - path: "/view-and-pure-functions", - component: component_view_and_pure_functions, - }, - { - path: "/visibility", - component: component_visibility, - }, - { - path: "", - component: component_, - }, + { + path: "/abi-decode", + component: component_abi_decode + }, + { + path: "/abi-encode", + component: component_abi_encode + }, + { + path: "/app/assembly-bin-exp", + component: component_app_assembly_bin_exp + }, + { + path: "/app/bi-directional-payment-channel", + component: component_app_bi_directional_payment_channel + }, + { + path: "/app/create2", + component: component_app_create2 + }, + { + path: "/app/crowd-fund", + component: component_app_crowd_fund + }, + { + path: "/app/deploy-any-contract", + component: component_app_deploy_any_contract + }, + { + path: "/app/dutch-auction", + component: component_app_dutch_auction + }, + { + path: "/app/english-auction", + component: component_app_english_auction + }, + { + path: "/app/erc1155", + component: component_app_erc1155 + }, + { + path: "/app/erc20", + component: component_app_erc20 + }, + { + path: "/app/erc721", + component: component_app_erc721 + }, + { + path: "/app/ether-wallet", + component: component_app_ether_wallet + }, + { + path: "/app/gasless-token-transfer", + component: component_app_gasless_token_transfer + }, + { + path: "/app/iterable-mapping", + component: component_app_iterable_mapping + }, + { + path: "/app/merkle-tree", + component: component_app_merkle_tree + }, + { + path: "/app/minimal-proxy", + component: component_app_minimal_proxy + }, + { + path: "/app/multi-call", + component: component_app_multi_call + }, + { + path: "/app/multi-delegatecall", + component: component_app_multi_delegatecall + }, + { + path: "/app/multi-sig-wallet", + component: component_app_multi_sig_wallet + }, + { + path: "/app/simple-bytecode-contract", + component: component_app_simple_bytecode_contract + }, + { + path: "/app/time-lock", + component: component_app_time_lock + }, + { + path: "/app/uni-directional-payment-channel", + component: component_app_uni_directional_payment_channel + }, + { + path: "/app/upgradeable-proxy", + component: component_app_upgradeable_proxy + }, + { + path: "/app/write-to-any-slot", + component: component_app_write_to_any_slot + }, + { + path: "/array", + component: component_array + }, + { + path: "/assembly-error", + component: component_assembly_error + }, + { + path: "/assembly-if", + component: component_assembly_if + }, + { + path: "/assembly-loop", + component: component_assembly_loop + }, + { + path: "/assembly-math", + component: component_assembly_math + }, + { + path: "/assembly-variable", + component: component_assembly_variable + }, + { + path: "/bitwise", + component: component_bitwise + }, + { + path: "/call", + component: component_call + }, + { + path: "/calling-contract", + component: component_calling_contract + }, + { + path: "/constants", + component: component_constants + }, + { + path: "/constructor", + component: component_constructor + }, + { + path: "/data-locations", + component: component_data_locations + }, + { + path: "/defi/chainlink-price-oracle", + component: component_defi_chainlink_price_oracle + }, + { + path: "/defi/constant-product-amm", + component: component_defi_constant_product_amm + }, + { + path: "/defi/constant-sum-amm", + component: component_defi_constant_sum_amm + }, + { + path: "/defi/discrete-staking-rewards", + component: component_defi_discrete_staking_rewards + }, + { + path: "/defi/stable-swap-amm", + component: component_defi_stable_swap_amm + }, + { + path: "/defi/staking-rewards", + component: component_defi_staking_rewards + }, + { + path: "/defi/uniswap-v2", + component: component_defi_uniswap_v2 + }, + { + path: "/defi/uniswap-v2-add-remove-liquidity", + component: component_defi_uniswap_v2_add_remove_liquidity + }, + { + path: "/defi/uniswap-v2-flash-swap", + component: component_defi_uniswap_v2_flash_swap + }, + { + path: "/defi/uniswap-v2-optimal-one-sided-supply", + component: component_defi_uniswap_v2_optimal_one_sided_supply + }, + { + path: "/defi/uniswap-v3-flash", + component: component_defi_uniswap_v3_flash + }, + { + path: "/defi/uniswap-v3-flash-swap", + component: component_defi_uniswap_v3_flash_swap + }, + { + path: "/defi/uniswap-v3-liquidity", + component: component_defi_uniswap_v3_liquidity + }, + { + path: "/defi/uniswap-v3-swap", + component: component_defi_uniswap_v3_swap + }, + { + path: "/defi/vault", + component: component_defi_vault + }, + { + path: "/delegatecall", + component: component_delegatecall + }, + { + path: "/enum", + component: component_enum + }, + { + path: "/error", + component: component_error + }, + { + path: "/ether-units", + component: component_ether_units + }, + { + path: "/events", + component: component_events + }, + { + path: "/fallback", + component: component_fallback + }, + { + path: "/first-app", + component: component_first_app + }, + { + path: "/function", + component: component_function + }, + { + path: "/function-modifier", + component: component_function_modifier + }, + { + path: "/function-selector", + component: component_function_selector + }, + { + path: "/gas", + component: component_gas + }, + { + path: "/gas-golf", + component: component_gas_golf + }, + { + path: "/hacks/accessing-private-data", + component: component_hacks_accessing_private_data + }, + { + path: "/hacks/block-timestamp-manipulation", + component: component_hacks_block_timestamp_manipulation + }, + { + path: "/hacks/contract-size", + component: component_hacks_contract_size + }, + { + path: "/hacks/delegatecall", + component: component_hacks_delegatecall + }, + { + path: "/hacks/denial-of-service", + component: component_hacks_denial_of_service + }, + { + path: "/hacks/deploy-different-contracts-same-address", + component: component_hacks_deploy_different_contracts_same_address + }, + { + path: "/hacks/front-running", + component: component_hacks_front_running + }, + { + path: "/hacks/hiding-malicious-code-with-external-contract", + component: component_hacks_hiding_malicious_code_with_external_contract + }, + { + path: "/hacks/honeypot", + component: component_hacks_honeypot + }, + { + path: "/hacks/overflow", + component: component_hacks_overflow + }, + { + path: "/hacks/phishing-with-tx-origin", + component: component_hacks_phishing_with_tx_origin + }, + { + path: "/hacks/randomness", + component: component_hacks_randomness + }, + { + path: "/hacks/re-entrancy", + component: component_hacks_re_entrancy + }, + { + path: "/hacks/self-destruct", + component: component_hacks_self_destruct + }, + { + path: "/hacks/signature-replay", + component: component_hacks_signature_replay + }, + { + path: "/hashing", + component: component_hashing + }, + { + path: "/hello-world", + component: component_hello_world + }, + { + path: "/if-else", + component: component_if_else + }, + { + path: "/immutable", + component: component_immutable + }, + { + path: "/import", + component: component_import + }, + { + path: "/inheritance", + component: component_inheritance + }, + { + path: "/initialize", + component: component_initialize + }, + { + path: "/interface", + component: component_interface + }, + { + path: "/library", + component: component_library + }, + { + path: "/loop", + component: component_loop + }, + { + path: "/mapping", + component: component_mapping + }, + { + path: "/new-contract", + component: component_new_contract + }, + { + path: "/payable", + component: component_payable + }, + { + path: "/primitives", + component: component_primitives + }, + { + path: "/sending-ether", + component: component_sending_ether + }, + { + path: "/shadowing-inherited-state-variables", + component: component_shadowing_inherited_state_variables + }, + { + path: "/signature", + component: component_signature + }, + { + path: "/state-variables", + component: component_state_variables + }, + { + path: "/structs", + component: component_structs + }, + { + path: "/super", + component: component_super + }, + { + path: "/tests/echidna", + component: component_tests_echidna + }, + { + path: "/try-catch", + component: component_try_catch + }, + { + path: "/unchecked-math", + component: component_unchecked_math + }, + { + path: "/variables", + component: component_variables + }, + { + path: "/view-and-pure-functions", + component: component_view_and_pure_functions + }, + { + path: "/visibility", + component: component_visibility + }, + { + path: "", + component: component_ + }, ] -export default routes +export default routes \ No newline at end of file