From bbf70e8ea61994215dac98e6fa3ae159971ad116 Mon Sep 17 00:00:00 2001 From: saucepoint Date: Mon, 13 Nov 2023 16:05:51 -0500 Subject: [PATCH 1/6] minor copy updates --- src/components/Footer.tsx | 30 +++++------------------------- src/pages/index.tsx | 6 +++--- 2 files changed, 8 insertions(+), 28 deletions(-) diff --git a/src/components/Footer.tsx b/src/components/Footer.tsx index e0b74d4a..4ae40904 100644 --- a/src/components/Footer.tsx +++ b/src/components/Footer.tsx @@ -5,17 +5,13 @@ import youTube from "./youtube.png" import telegram from "./telegram.png" import discord from "./discord.png" -// Khan Academy -const ADDRESS = "0x95a647B3d8a3F11176BAdB799b9499C671fa243a" - function Footer() { return (
- {/* smart contract engineer */} - 👽  - - saucepoint + 🦄  + + Uniswap Foundation
{/*
@@ -41,32 +37,16 @@ function Footer() {
*/} -
- Donate - 🙂 - - {ADDRESS.slice(0, 6)}...{ADDRESS.slice(-6, -1)} - - to - - Khan Academy - -
- {/*
- - contact@solidity-by-example.org - -
*/}
source
|
license diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 5969c738..6ed69463 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -111,16 +111,16 @@ export default function HomePage() { return (

Uniswap v4 by Example

-
v 0.8.20
+
v0.8.22

- an introduction to integrating and using Uniswap v4 with + An introduction to integrating and using Uniswap v4 through simple examples

From 412dba11643d92569e7308447779e5933dcd93a6 Mon Sep 17 00:00:00 2001 From: saucepoint Date: Mon, 13 Nov 2023 18:09:47 -0500 Subject: [PATCH 2/6] reduce clutter by providing concise solidity snippets --- scripts/md-to-react.ts | 2 +- src/pages/initialize/HookDataInit.solsnippet | 22 +++ src/pages/initialize/Hookless.solsnippet | 21 +++ .../PoolInitializeExampleInputs.sol | 68 ---------- src/pages/initialize/index.html.ts | 128 ++++++++---------- src/pages/initialize/index.md | 12 +- 6 files changed, 107 insertions(+), 146 deletions(-) create mode 100644 src/pages/initialize/HookDataInit.solsnippet create mode 100644 src/pages/initialize/Hookless.solsnippet delete mode 100644 src/pages/initialize/PoolInitializeExampleInputs.sol diff --git a/scripts/md-to-react.ts b/scripts/md-to-react.ts index 64eb9b36..95b23e46 100644 --- a/scripts/md-to-react.ts +++ b/scripts/md-to-react.ts @@ -38,7 +38,7 @@ hljs.registerLanguage("solidity", solidity) async function findSolidityFiles(dir: string): Promise { const files = await readdir(dir) - return files.filter((file) => file.split(".").pop() == "sol") + return files.filter((file) => file.split(".").pop() == "sol" || file.split(".").pop() == "solsnippet") } async function mdToHtml(filePath: string) { diff --git a/src/pages/initialize/HookDataInit.solsnippet b/src/pages/initialize/HookDataInit.solsnippet new file mode 100644 index 00000000..7d6376c6 --- /dev/null +++ b/src/pages/initialize/HookDataInit.solsnippet @@ -0,0 +1,22 @@ +IPoolManager manager = IPoolManager(0x01); + +address hook = address(0x80); // prefix indicates the hook only has a beforeInitialize() function +address token0 = address(0x11); +address token1 = address(0x22); +uint24 swapFee = 3000; // 0.30% fee tier +int24 tickSpacing = 60; + +// floor(sqrt(1) * 2^96) +uint160 startingPrice = 79228162514264337593543950336; + +// Assume the custom hook requires a timestamp when initializing it +bytes memory hookData = abi.encode(block.timestamp); + +PoolKey memory pool = PoolKey({ + currency0: Currency.wrap(token0), + currency1: Currency.wrap(token1), + fee: swapFee, + tickSpacing: tickSpacing, + hooks: IHooks(hook) +}); +manager.initialize(pool, startingPrice, hookData); \ No newline at end of file diff --git a/src/pages/initialize/Hookless.solsnippet b/src/pages/initialize/Hookless.solsnippet new file mode 100644 index 00000000..747d8c34 --- /dev/null +++ b/src/pages/initialize/Hookless.solsnippet @@ -0,0 +1,21 @@ +IPoolManager manager = IPoolManager(0x01); + +address token0 = address(0x11); +address token1 = address(0x22); +uint24 swapFee = 500; // 0.05% fee tier +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.wrap(token0), + currency1: Currency.wrap(token1), + fee: swapFee, + tickSpacing: tickSpacing, + hooks: IHooks(address(0x0)) // !!! Hookless pool is address(0x0) +}); +manager.initialize(pool, startingPrice, hookData); \ No newline at end of file diff --git a/src/pages/initialize/PoolInitializeExampleInputs.sol b/src/pages/initialize/PoolInitializeExampleInputs.sol deleted file mode 100644 index 83c443e1..00000000 --- a/src/pages/initialize/PoolInitializeExampleInputs.sol +++ /dev/null @@ -1,68 +0,0 @@ -// 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.wrap(token0), - currency1: Currency.wrap(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; - - // Assume the custom hook requires a timestamp when initializing it - bytes memory hookData = abi.encode(block.timestamp); - - PoolKey memory pool = PoolKey({ - currency0: Currency.wrap(token0), - currency1: Currency.wrap(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 index de8ac1b4..a1d10a6c 100644 --- a/src/pages/initialize/index.html.ts +++ b/src/pages/initialize/index.html.ts @@ -14,20 +14,24 @@ export const keywords = [ export const codes = [ { - fileName: "PoolInitialize.sol", - code: "Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVApwcmFnbWEgc29saWRpdHkgXjAuOC4yMDsKCmltcG9ydCB7SVBvb2xNYW5hZ2VyfSBmcm9tICJAdW5pc3dhcC92NC1jb3JlL2NvbnRyYWN0cy9pbnRlcmZhY2VzL0lQb29sTWFuYWdlci5zb2wiOwppbXBvcnQge0lIb29rc30gZnJvbSAiQHVuaXN3YXAvdjQtY29yZS9jb250cmFjdHMvaW50ZXJmYWNlcy9JSG9va3Muc29sIjsKaW1wb3J0IHtQb29sS2V5fSBmcm9tICJAdW5pc3dhcC92NC1jb3JlL2NvbnRyYWN0cy90eXBlcy9Qb29sS2V5LnNvbCI7CmltcG9ydCB7Q3VycmVuY3lMaWJyYXJ5LCBDdXJyZW5jeX0gZnJvbSAiQHVuaXN3YXAvdjQtY29yZS9jb250cmFjdHMvdHlwZXMvQ3VycmVuY3kuc29sIjsKCmNvbnRyYWN0IFBvb2xJbml0aWFsaXplIHsKICAgIHVzaW5nIEN1cnJlbmN5TGlicmFyeSBmb3IgQ3VycmVuY3k7CgogICAgLy8gc2V0IHRoZSBwb29sIG1hbmFnZXIgYWRkcmVzcwogICAgSVBvb2xNYW5hZ2VyIG1hbmFnZXIgPSBJUG9vbE1hbmFnZXIoMHgwMSk7CgogICAgZnVuY3Rpb24gaW5pdCgKICAgICAgICBhZGRyZXNzIHRva2VuMCwKICAgICAgICBhZGRyZXNzIHRva2VuMSwKICAgICAgICB1aW50MjQgc3dhcEZlZSwKICAgICAgICBpbnQyNCB0aWNrU3BhY2luZywKICAgICAgICBhZGRyZXNzIGhvb2ssCiAgICAgICAgdWludDE2MCBzcXJ0UHJpY2VYOTYsCiAgICAgICAgYnl0ZXMgY2FsbGRhdGEgaG9va0RhdGEKICAgICkgZXh0ZXJuYWwgewogICAgICAgIC8vIHNvcnQgeW91ciB0b2tlbnMhIHY0IHJlcXVpcmVzIHRva2VuMCA8IHRva2VuMQogICAgICAgIGlmICh0b2tlbjAgPiB0b2tlbjEpIHsKICAgICAgICAgICAgKHRva2VuMCwgdG9rZW4xKSA9ICh0b2tlbjEsIHRva2VuMCk7CiAgICAgICAgfQoKICAgICAgICBQb29sS2V5IG1lbW9yeSBwb29sID0gUG9vbEtleSh7CiAgICAgICAgICAgIGN1cnJlbmN5MDogQ3VycmVuY3kud3JhcCh0b2tlbjApLAogICAgICAgICAgICBjdXJyZW5jeTE6IEN1cnJlbmN5LndyYXAodG9rZW4xKSwKICAgICAgICAgICAgZmVlOiBzd2FwRmVlLAogICAgICAgICAgICB0aWNrU3BhY2luZzogdGlja1NwYWNpbmcsCiAgICAgICAgICAgIGhvb2tzOiBJSG9va3MoaG9vaykKICAgICAgICB9KTsKICAgICAgICBtYW5hZ2VyLmluaXRpYWxpemUocG9vbCwgc3FydFByaWNlWDk2LCBob29rRGF0YSk7CiAgICB9Cn0K", + fileName: "HookDataInit.sol", + code: "SVBvb2xNYW5hZ2VyIG1hbmFnZXIgPSBJUG9vbE1hbmFnZXIoMHgwMSk7CgphZGRyZXNzIGhvb2sgPSBhZGRyZXNzKDB4ODApOyAvLyBwcmVmaXggaW5kaWNhdGVzIHRoZSBob29rIG9ubHkgaGFzIGEgYmVmb3JlSW5pdGlhbGl6ZSgpIGZ1bmN0aW9uCmFkZHJlc3MgdG9rZW4wID0gYWRkcmVzcygweDExKTsKYWRkcmVzcyB0b2tlbjEgPSBhZGRyZXNzKDB4MjIpOwp1aW50MjQgc3dhcEZlZSA9IDMwMDA7IC8vIDAuMDUlIGZlZSB0aWVyCmludDI0IHRpY2tTcGFjaW5nID0gNjA7CgovLyBmbG9vcihzcXJ0KDEpICogMl45NikKdWludDE2MCBzdGFydGluZ1ByaWNlID0gNzkyMjgxNjI1MTQyNjQzMzc1OTM1NDM5NTAzMzY7CgovLyBBc3N1bWUgdGhlIGN1c3RvbSBob29rIHJlcXVpcmVzIGEgdGltZXN0YW1wIHdoZW4gaW5pdGlhbGl6aW5nIGl0CmJ5dGVzIG1lbW9yeSBob29rRGF0YSA9IGFiaS5lbmNvZGUoYmxvY2sudGltZXN0YW1wKTsKClBvb2xLZXkgbWVtb3J5IHBvb2wgPSBQb29sS2V5KHsKICAgIGN1cnJlbmN5MDogQ3VycmVuY3kud3JhcCh0b2tlbjApLAogICAgY3VycmVuY3kxOiBDdXJyZW5jeS53cmFwKHRva2VuMSksCiAgICBmZWU6IHN3YXBGZWUsCiAgICB0aWNrU3BhY2luZzogdGlja1NwYWNpbmcsCiAgICBob29rczogSUhvb2tzKGhvb2spCn0pOwptYW5hZ2VyLmluaXRpYWxpemUocG9vbCwgc3RhcnRpbmdQcmljZSwgaG9va0RhdGEpOw==", + }, + { + fileName: "Hookless.sol", + code: "SVBvb2xNYW5hZ2VyIG1hbmFnZXIgPSBJUG9vbE1hbmFnZXIoMHgwMSk7CgphZGRyZXNzIHRva2VuMCA9IGFkZHJlc3MoMHgxMSk7CmFkZHJlc3MgdG9rZW4xID0gYWRkcmVzcygweDIyKTsKdWludDI0IHN3YXBGZWUgPSA1MDA7IC8vIDAuMDUlIGZlZSB0aWVyCmludDI0IHRpY2tTcGFjaW5nID0gMTA7CgovLyBmbG9vcihzcXJ0KDEpICogMl45NikKdWludDE2MCBzdGFydGluZ1ByaWNlID0gNzkyMjgxNjI1MTQyNjQzMzc1OTM1NDM5NTAzMzY7CgovLyBob29rbGVzcyBwb29sIGRvZXNudCBleHBlY3QgYW55IGluaXRpYWxpemF0aW9uIGRhdGEKYnl0ZXMgbWVtb3J5IGhvb2tEYXRhID0gbmV3IGJ5dGVzKDApOwoKUG9vbEtleSBtZW1vcnkgcG9vbCA9IFBvb2xLZXkoewogICAgY3VycmVuY3kwOiBDdXJyZW5jeS53cmFwKHRva2VuMCksCiAgICBjdXJyZW5jeTE6IEN1cnJlbmN5LndyYXAodG9rZW4xKSwKICAgIGZlZTogc3dhcEZlZSwKICAgIHRpY2tTcGFjaW5nOiB0aWNrU3BhY2luZywKICAgIGhvb2tzOiBJSG9va3MoYWRkcmVzcygweDApKSAvLyAhISEgSG9va2xlc3MgcG9vbCBpcyBhZGRyZXNzKDB4MCkKfSk7Cm1hbmFnZXIuaW5pdGlhbGl6ZShwb29sLCBzdGFydGluZ1ByaWNlLCBob29rRGF0YSk7", }, { - fileName: "PoolInitializeExampleInputs.sol", - code: "Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVApwcmFnbWEgc29saWRpdHkgXjAuOC4yMDsKCmltcG9ydCB7SVBvb2xNYW5hZ2VyfSBmcm9tICJAdW5pc3dhcC92NC1jb3JlL2NvbnRyYWN0cy9pbnRlcmZhY2VzL0lQb29sTWFuYWdlci5zb2wiOwppbXBvcnQge0lIb29rc30gZnJvbSAiQHVuaXN3YXAvdjQtY29yZS9jb250cmFjdHMvaW50ZXJmYWNlcy9JSG9va3Muc29sIjsKaW1wb3J0IHtQb29sS2V5fSBmcm9tICJAdW5pc3dhcC92NC1jb3JlL2NvbnRyYWN0cy90eXBlcy9Qb29sS2V5LnNvbCI7CmltcG9ydCB7Q3VycmVuY3lMaWJyYXJ5LCBDdXJyZW5jeX0gZnJvbSAiQHVuaXN3YXAvdjQtY29yZS9jb250cmFjdHMvdHlwZXMvQ3VycmVuY3kuc29sIjsKCmNvbnRyYWN0IFBvb2xJbml0aWFsaXplRXhhbXBsZUlucHV0cyB7CiAgICB1c2luZyBDdXJyZW5jeUxpYnJhcnkgZm9yIEN1cnJlbmN5OwoKICAgIC8vIHNldCB0aGUgcG9vbCBtYW5hZ2VyIGFkZHJlc3MKICAgIElQb29sTWFuYWdlciBtYW5hZ2VyID0gSVBvb2xNYW5hZ2VyKDB4MDEpOwoKICAgIC8vLyBAbm90aWNlIEluaXRpYWxpemUgYSBob29rbGVzcyBwb29sOgogICAgLy8vICAgICAwLjA1JSBzd2FwIGZlZQogICAgLy8vICAgICB0aWNrIHNwYWNpbmcgb2YgMTAKICAgIC8vLyAgICAgc3RhcnRpbmcgcHJpY2Ugb2YgMToxCiAgICBmdW5jdGlvbiBleGFtcGxlQSgpIGV4dGVybmFsIHsKICAgICAgICBhZGRyZXNzIHRva2VuMCA9IGFkZHJlc3MoMHgxMSk7CiAgICAgICAgYWRkcmVzcyB0b2tlbjEgPSBhZGRyZXNzKDB4MjIpOwogICAgICAgIHVpbnQyNCBzd2FwRmVlID0gNTAwOwogICAgICAgIGludDI0IHRpY2tTcGFjaW5nID0gMTA7CgogICAgICAgIC8vIGZsb29yKHNxcnQoMSkgKiAyXjk2KQogICAgICAgIHVpbnQxNjAgc3RhcnRpbmdQcmljZSA9IDc5MjI4MTYyNTE0MjY0MzM3NTkzNTQzOTUwMzM2OwoKICAgICAgICAvLyBob29rbGVzcyBwb29sIGRvZXNudCBleHBlY3QgYW55IGluaXRpYWxpemF0aW9uIGRhdGEKICAgICAgICBieXRlcyBtZW1vcnkgaG9va0RhdGEgPSBuZXcgYnl0ZXMoMCk7CgogICAgICAgIFBvb2xLZXkgbWVtb3J5IHBvb2wgPSBQb29sS2V5KHsKICAgICAgICAgICAgY3VycmVuY3kwOiBDdXJyZW5jeS53cmFwKHRva2VuMCksCiAgICAgICAgICAgIGN1cnJlbmN5MTogQ3VycmVuY3kud3JhcCh0b2tlbjEpLAogICAgICAgICAgICBmZWU6IHN3YXBGZWUsCiAgICAgICAgICAgIHRpY2tTcGFjaW5nOiB0aWNrU3BhY2luZywKICAgICAgICAgICAgaG9va3M6IElIb29rcyhhZGRyZXNzKDB4MCkpCiAgICAgICAgfSk7CiAgICAgICAgbWFuYWdlci5pbml0aWFsaXplKHBvb2wsIHN0YXJ0aW5nUHJpY2UsIGhvb2tEYXRhKTsKICAgIH0KCiAgICAvLy8gQG5vdGljZSBJbml0aWFsaXplIGEgcG9vbCB3aXRoIGEgY3VzdG9tIGhvb2s6CiAgICAvLy8gICAgIDAuMzAlIHN3YXAgZmVlCiAgICAvLy8gICAgIHRpY2sgc3BhY2luZyBvZiA2MAogICAgLy8vICAgICBzdGFydGluZyBwcmljZSBvZiAxOjEKICAgIC8vLyAgICAgaG9vaydzIGJlZm9yZUluaXRpYWxpemUoKSByZXF1aXJlcyBwcm92aWRpbmcgYSB0aW1lc3RhbXAKICAgIGZ1bmN0aW9uIGV4YW1wbGVCKCkgZXh0ZXJuYWwgewogICAgICAgIGFkZHJlc3MgaG9vayA9IGFkZHJlc3MoMHg4MCk7IC8vIHByZWZpeCBpbmRpY2F0ZXMgdGhlIGhvb2sgb25seSBoYXMgYSBiZWZvcmVJbml0aWFsaXplKCkgZnVuY3Rpb24KICAgICAgICBhZGRyZXNzIHRva2VuMCA9IGFkZHJlc3MoMHgxMSk7CiAgICAgICAgYWRkcmVzcyB0b2tlbjEgPSBhZGRyZXNzKDB4MjIpOwogICAgICAgIHVpbnQyNCBzd2FwRmVlID0gMzAwMDsKICAgICAgICBpbnQyNCB0aWNrU3BhY2luZyA9IDYwOwoKICAgICAgICAvLyBmbG9vcihzcXJ0KDEpICogMl45NikKICAgICAgICB1aW50MTYwIHN0YXJ0aW5nUHJpY2UgPSA3OTIyODE2MjUxNDI2NDMzNzU5MzU0Mzk1MDMzNjsKCiAgICAgICAgLy8gQXNzdW1lIHRoZSBjdXN0b20gaG9vayByZXF1aXJlcyBhIHRpbWVzdGFtcCB3aGVuIGluaXRpYWxpemluZyBpdAogICAgICAgIGJ5dGVzIG1lbW9yeSBob29rRGF0YSA9IGFiaS5lbmNvZGUoYmxvY2sudGltZXN0YW1wKTsKCiAgICAgICAgUG9vbEtleSBtZW1vcnkgcG9vbCA9IFBvb2xLZXkoewogICAgICAgICAgICBjdXJyZW5jeTA6IEN1cnJlbmN5LndyYXAodG9rZW4wKSwKICAgICAgICAgICAgY3VycmVuY3kxOiBDdXJyZW5jeS53cmFwKHRva2VuMSksCiAgICAgICAgICAgIGZlZTogc3dhcEZlZSwKICAgICAgICAgICAgdGlja1NwYWNpbmc6IHRpY2tTcGFjaW5nLAogICAgICAgICAgICBob29rczogSUhvb2tzKGhvb2spCiAgICAgICAgfSk7CiAgICAgICAgbWFuYWdlci5pbml0aWFsaXplKHBvb2wsIHN0YXJ0aW5nUHJpY2UsIGhvb2tEYXRhKTsKICAgIH0KfQo=", + fileName: "PoolInitialize.sol", + code: "Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVApwcmFnbWEgc29saWRpdHkgXjAuOC4yMDsKCmltcG9ydCB7SVBvb2xNYW5hZ2VyfSBmcm9tICJAdW5pc3dhcC92NC1jb3JlL2NvbnRyYWN0cy9pbnRlcmZhY2VzL0lQb29sTWFuYWdlci5zb2wiOwppbXBvcnQge0lIb29rc30gZnJvbSAiQHVuaXN3YXAvdjQtY29yZS9jb250cmFjdHMvaW50ZXJmYWNlcy9JSG9va3Muc29sIjsKaW1wb3J0IHtQb29sS2V5fSBmcm9tICJAdW5pc3dhcC92NC1jb3JlL2NvbnRyYWN0cy90eXBlcy9Qb29sS2V5LnNvbCI7CmltcG9ydCB7Q3VycmVuY3lMaWJyYXJ5LCBDdXJyZW5jeX0gZnJvbSAiQHVuaXN3YXAvdjQtY29yZS9jb250cmFjdHMvdHlwZXMvQ3VycmVuY3kuc29sIjsKCmNvbnRyYWN0IFBvb2xJbml0aWFsaXplIHsKICAgIHVzaW5nIEN1cnJlbmN5TGlicmFyeSBmb3IgQ3VycmVuY3k7CgogICAgLy8gc2V0IHRoZSBwb29sIG1hbmFnZXIgYWRkcmVzcwogICAgSVBvb2xNYW5hZ2VyIG1hbmFnZXIgPSBJUG9vbE1hbmFnZXIoMHgwMSk7CgogICAgZnVuY3Rpb24gaW5pdCgKICAgICAgICBhZGRyZXNzIHRva2VuMCwKICAgICAgICBhZGRyZXNzIHRva2VuMSwKICAgICAgICB1aW50MjQgc3dhcEZlZSwKICAgICAgICBpbnQyNCB0aWNrU3BhY2luZywKICAgICAgICBhZGRyZXNzIGhvb2ssCiAgICAgICAgdWludDE2MCBzcXJ0UHJpY2VYOTYsCiAgICAgICAgYnl0ZXMgY2FsbGRhdGEgaG9va0RhdGEKICAgICkgZXh0ZXJuYWwgewogICAgICAgIC8vIHNvcnQgeW91ciB0b2tlbnMhIHY0IHJlcXVpcmVzIHRva2VuMCA8IHRva2VuMQogICAgICAgIGlmICh0b2tlbjAgPiB0b2tlbjEpIHsKICAgICAgICAgICAgKHRva2VuMCwgdG9rZW4xKSA9ICh0b2tlbjEsIHRva2VuMCk7CiAgICAgICAgfQoKICAgICAgICBQb29sS2V5IG1lbW9yeSBwb29sID0gUG9vbEtleSh7CiAgICAgICAgICAgIGN1cnJlbmN5MDogQ3VycmVuY3kud3JhcCh0b2tlbjApLAogICAgICAgICAgICBjdXJyZW5jeTE6IEN1cnJlbmN5LndyYXAodG9rZW4xKSwKICAgICAgICAgICAgZmVlOiBzd2FwRmVlLAogICAgICAgICAgICB0aWNrU3BhY2luZzogdGlja1NwYWNpbmcsCiAgICAgICAgICAgIGhvb2tzOiBJSG9va3MoaG9vaykKICAgICAgICB9KTsKICAgICAgICBtYW5hZ2VyLmluaXRpYWxpemUocG9vbCwgc3FydFByaWNlWDk2LCBob29rRGF0YSk7CiAgICB9Cn0K", }, ] const html = `
  • Create a Uniswap v4 Pool
-

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

+

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%. A trading pair exists as many pools, but one pool has one hook contract

+

In V4, pools are initialized and managed by a single contract: PoolManager

Think of a PoolKey as the unique identifier for a pool, i.e. like a v3 pair's contract address

Creating a Pool is determined by 5 primary arguments:

    @@ -77,74 +81,50 @@ const html = `
      }

      Examples of Initializing a V4 Pool

      Hooks are not mandatory, you can create a pool without a hook

      -
      // 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.wrap(token0),
      -            currency1: Currency.wrap(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;
      -
      -        // Assume the custom hook requires a timestamp when initializing it
      -        bytes memory hookData = abi.encode(block.timestamp);
      -
      -        PoolKey memory pool = PoolKey({
      -            currency0: Currency.wrap(token0),
      -            currency1: Currency.wrap(token1),
      -            fee: swapFee,
      -            tickSpacing: tickSpacing,
      -            hooks: IHooks(hook)
      -        });
      -        manager.initialize(pool, startingPrice, hookData);
      -    }
      -}
      +
      IPoolManager manager = IPoolManager(0x01);
      +
      +address token0 = address(0x11);
      +address token1 = address(0x22);
      +uint24 swapFee = 500; // 0.05% fee tier
      +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.wrap(token0),
      +    currency1: Currency.wrap(token1),
      +    fee: swapFee,
      +    tickSpacing: tickSpacing,
      +    hooks: IHooks(address(0x0)) // !!! Hookless pool is address(0x0)
      +});
      +manager.initialize(pool, startingPrice, hookData);
      +

      Some hooks may require initialization data, i.e. block.timestamp

      +
      IPoolManager manager = IPoolManager(0x01);
      +
      +address hook = address(0x80); // prefix indicates the hook only has a beforeInitialize() function
      +address token0 = address(0x11);
      +address token1 = address(0x22);
      +uint24 swapFee = 3000; // 0.05% fee tier
      +int24 tickSpacing = 60;
      +
      +// floor(sqrt(1) * 2^96)
      +uint160 startingPrice = 79228162514264337593543950336;
      +
      +// Assume the custom hook requires a timestamp when initializing it
      +bytes memory hookData = abi.encode(block.timestamp);
      +
      +PoolKey memory pool = PoolKey({
      +    currency0: Currency.wrap(token0),
      +    currency1: Currency.wrap(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 index 79053779..86135327 100644 --- a/src/pages/initialize/index.md +++ b/src/pages/initialize/index.md @@ -7,9 +7,9 @@ keywords: [pool, initialize, init, create, pair, factory] * Create a Uniswap v4 Pool -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. +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%. A trading pair exists as many pools, but one *pool* has one *hook contract* -Initializing a V3 Pair involved deploying a contract via the factory. In V4, pools are initialized and managed by a single contract: `PoolManager` +In V4, pools are initialized and managed by a single contract: `PoolManager` *Think of a `PoolKey` as the unique identifier for a pool, i.e. like a v3 pair's contract address* @@ -30,5 +30,11 @@ Creating a Pool is determined by 5 primary arguments: *Hooks are not mandatory, you can create a pool without a hook* ```solidity -{{{PoolInitializeExampleInputs}}} +{{{Hookless}}} ``` + +*Some hooks may require initialization data, i.e. `block.timestamp`* + +```solidity +{{{HookDataInit}}} +``` \ No newline at end of file From c65c55c116662a9847de03552b5af3f9556c8f31 Mon Sep 17 00:00:00 2001 From: saucepoint Date: Mon, 13 Nov 2023 21:19:36 -0500 Subject: [PATCH 3/6] copy updates --- .../CreateLiquidityExampleInputs.sol | 43 ----------- .../CreateLiquidityExampleInputs.solsnippet | 29 ++++++++ src/pages/create-liquidity/index.html.ts | 74 ++++++++----------- src/pages/create-liquidity/index.md | 12 ++- 4 files changed, 68 insertions(+), 90 deletions(-) delete mode 100644 src/pages/create-liquidity/CreateLiquidityExampleInputs.sol create mode 100644 src/pages/create-liquidity/CreateLiquidityExampleInputs.solsnippet diff --git a/src/pages/create-liquidity/CreateLiquidityExampleInputs.sol b/src/pages/create-liquidity/CreateLiquidityExampleInputs.sol deleted file mode 100644 index cacf7a95..00000000 --- a/src/pages/create-liquidity/CreateLiquidityExampleInputs.sol +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; - -import {IERC20} from "forge-std/interfaces/IERC20.sol"; -import {IPoolManager} from "@uniswap/v4-core/contracts/interfaces/IPoolManager.sol"; -import {PoolKey} from "@uniswap/v4-core/contracts/types/PoolKey.sol"; -import {PoolModifyPositionTest} from "@uniswap/v4-core/contracts/test/PoolModifyPositionTest.sol"; -import {CurrencyLibrary, Currency} from "@uniswap/v4-core/contracts/types/Currency.sol"; - -contract CreateLiquidityExampleInputs { - using CurrencyLibrary for Currency; - - // set the router address - PoolModifyPositionTest lpRouter = PoolModifyPositionTest(0x01); - - function exampleA() external { - address token0 = address(0x11); - address token1 = address(0x22); - - // Using a hookless pool - PoolKey memory pool = PoolKey({ - currency0: Currency.wrap(token0), - currency1: Currency.wrap(token1), - fee: 3000, - tickSpacing: 60, - hooks: IHooks(address(0x0)) - }); - - // approve tokens to the LP Router - IERC20(token0).approve(address(lpRouter), type(uint256).max); - IERC20(token1).approve(address(lpRouter), type(uint256).max); - - // Provide 10e18 worth of liquidity on the range of [-600, 600] - int24 tickLower = -600; - int24 tickUpper = 600; - int256 liquidity = 10e18; - lpRouter.modifyPosition( - poolKey, - IPoolManager.ModifyPositionParams({tickLower: tickLower, tickUpper: tickUpper, liquidityDelta: liquidity}), - new bytes(0) - ); - } -} diff --git a/src/pages/create-liquidity/CreateLiquidityExampleInputs.solsnippet b/src/pages/create-liquidity/CreateLiquidityExampleInputs.solsnippet new file mode 100644 index 00000000..3366c871 --- /dev/null +++ b/src/pages/create-liquidity/CreateLiquidityExampleInputs.solsnippet @@ -0,0 +1,29 @@ +import {PoolModifyPositionTest} from "@uniswap/v4-core/contracts/test/PoolModifyPositionTest.sol"; + +PoolModifyPositionTest lpRouter = PoolModifyPositionTest(0x01); +address token0 = address(0x11); +address token1 = address(0x22); +address hookAddress = address(0x80); + +// Pool that will receieve liquidity +PoolKey memory pool = PoolKey({ + currency0: Currency.wrap(token0), + currency1: Currency.wrap(token1), + fee: 3000, + tickSpacing: 60, + hooks: IHooks(hookAddress) +}); + +// approve tokens to the LP Router +IERC20(token0).approve(address(lpRouter), type(uint256).max); +IERC20(token1).approve(address(lpRouter), type(uint256).max); + +// Provide 10e18 worth of liquidity on the range of [-600, 600] +int24 tickLower = -600; +int24 tickUpper = 600; +int256 liquidity = 10e18; +lpRouter.modifyPosition( + poolKey, + IPoolManager.ModifyPositionParams({tickLower: tickLower, tickUpper: tickUpper, liquidityDelta: liquidity}), + new bytes(0) +); diff --git a/src/pages/create-liquidity/index.html.ts b/src/pages/create-liquidity/index.html.ts index 5c861734..66357fbd 100644 --- a/src/pages/create-liquidity/index.html.ts +++ b/src/pages/create-liquidity/index.html.ts @@ -19,19 +19,21 @@ export const codes = [ }, { fileName: "CreateLiquidityExampleInputs.sol", - code: "Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVApwcmFnbWEgc29saWRpdHkgXjAuOC4yMDsKCmltcG9ydCB7SUVSQzIwfSBmcm9tICJmb3JnZS1zdGQvaW50ZXJmYWNlcy9JRVJDMjAuc29sIjsKaW1wb3J0IHtJUG9vbE1hbmFnZXJ9IGZyb20gIkB1bmlzd2FwL3Y0LWNvcmUvY29udHJhY3RzL2ludGVyZmFjZXMvSVBvb2xNYW5hZ2VyLnNvbCI7CmltcG9ydCB7UG9vbEtleX0gZnJvbSAiQHVuaXN3YXAvdjQtY29yZS9jb250cmFjdHMvdHlwZXMvUG9vbEtleS5zb2wiOwppbXBvcnQge1Bvb2xNb2RpZnlQb3NpdGlvblRlc3R9IGZyb20gIkB1bmlzd2FwL3Y0LWNvcmUvY29udHJhY3RzL3Rlc3QvUG9vbE1vZGlmeVBvc2l0aW9uVGVzdC5zb2wiOwppbXBvcnQge0N1cnJlbmN5TGlicmFyeSwgQ3VycmVuY3l9IGZyb20gIkB1bmlzd2FwL3Y0LWNvcmUvY29udHJhY3RzL3R5cGVzL0N1cnJlbmN5LnNvbCI7Cgpjb250cmFjdCBDcmVhdGVMaXF1aWRpdHlFeGFtcGxlSW5wdXRzIHsKICAgIHVzaW5nIEN1cnJlbmN5TGlicmFyeSBmb3IgQ3VycmVuY3k7CgogICAgLy8gc2V0IHRoZSByb3V0ZXIgYWRkcmVzcwogICAgUG9vbE1vZGlmeVBvc2l0aW9uVGVzdCBscFJvdXRlciA9IFBvb2xNb2RpZnlQb3NpdGlvblRlc3QoMHgwMSk7CgogICAgZnVuY3Rpb24gZXhhbXBsZUEoKSBleHRlcm5hbCB7CiAgICAgICAgYWRkcmVzcyB0b2tlbjAgPSBhZGRyZXNzKDB4MTEpOwogICAgICAgIGFkZHJlc3MgdG9rZW4xID0gYWRkcmVzcygweDIyKTsKCiAgICAgICAgLy8gVXNpbmcgYSBob29rbGVzcyBwb29sCiAgICAgICAgUG9vbEtleSBtZW1vcnkgcG9vbCA9IFBvb2xLZXkoewogICAgICAgICAgICBjdXJyZW5jeTA6IEN1cnJlbmN5LndyYXAodG9rZW4wKSwKICAgICAgICAgICAgY3VycmVuY3kxOiBDdXJyZW5jeS53cmFwKHRva2VuMSksCiAgICAgICAgICAgIGZlZTogMzAwMCwKICAgICAgICAgICAgdGlja1NwYWNpbmc6IDYwLAogICAgICAgICAgICBob29rczogSUhvb2tzKGFkZHJlc3MoMHgwKSkKICAgICAgICB9KTsKCiAgICAgICAgLy8gYXBwcm92ZSB0b2tlbnMgdG8gdGhlIExQIFJvdXRlcgogICAgICAgIElFUkMyMCh0b2tlbjApLmFwcHJvdmUoYWRkcmVzcyhscFJvdXRlciksIHR5cGUodWludDI1NikubWF4KTsKICAgICAgICBJRVJDMjAodG9rZW4xKS5hcHByb3ZlKGFkZHJlc3MobHBSb3V0ZXIpLCB0eXBlKHVpbnQyNTYpLm1heCk7CgogICAgICAgIC8vIFByb3ZpZGUgMTBlMTggd29ydGggb2YgbGlxdWlkaXR5IG9uIHRoZSByYW5nZSBvZiBbLTYwMCwgNjAwXQogICAgICAgIGludDI0IHRpY2tMb3dlciA9IC02MDA7CiAgICAgICAgaW50MjQgdGlja1VwcGVyID0gNjAwOwogICAgICAgIGludDI1NiBsaXF1aWRpdHkgPSAxMGUxODsKICAgICAgICBscFJvdXRlci5tb2RpZnlQb3NpdGlvbigKICAgICAgICAgICAgcG9vbEtleSwKICAgICAgICAgICAgSVBvb2xNYW5hZ2VyLk1vZGlmeVBvc2l0aW9uUGFyYW1zKHt0aWNrTG93ZXI6IHRpY2tMb3dlciwgdGlja1VwcGVyOiB0aWNrVXBwZXIsIGxpcXVpZGl0eURlbHRhOiBsaXF1aWRpdHl9KSwKICAgICAgICAgICAgbmV3IGJ5dGVzKDApCiAgICAgICAgKTsKICAgIH0KfQo=", + code: "aW1wb3J0IHtQb29sTW9kaWZ5UG9zaXRpb25UZXN0fSBmcm9tICJAdW5pc3dhcC92NC1jb3JlL2NvbnRyYWN0cy90ZXN0L1Bvb2xNb2RpZnlQb3NpdGlvblRlc3Quc29sIjsKClBvb2xNb2RpZnlQb3NpdGlvblRlc3QgbHBSb3V0ZXIgPSBQb29sTW9kaWZ5UG9zaXRpb25UZXN0KDB4MDEpOwphZGRyZXNzIHRva2VuMCA9IGFkZHJlc3MoMHgxMSk7CmFkZHJlc3MgdG9rZW4xID0gYWRkcmVzcygweDIyKTsKYWRkcmVzcyBob29rQWRkcmVzcyA9IGFkZHJlc3MoMHg4MCk7CgovLyBQb29sIHRoYXQgd2lsbCByZWNlaWV2ZSBsaXF1aWRpdHkKUG9vbEtleSBtZW1vcnkgcG9vbCA9IFBvb2xLZXkoewogICAgY3VycmVuY3kwOiBDdXJyZW5jeS53cmFwKHRva2VuMCksCiAgICBjdXJyZW5jeTE6IEN1cnJlbmN5LndyYXAodG9rZW4xKSwKICAgIGZlZTogMzAwMCwKICAgIHRpY2tTcGFjaW5nOiA2MCwKICAgIGhvb2tzOiBJSG9va3MoaG9va0FkZHJlc3MpCn0pOwoKLy8gYXBwcm92ZSB0b2tlbnMgdG8gdGhlIExQIFJvdXRlcgpJRVJDMjAodG9rZW4wKS5hcHByb3ZlKGFkZHJlc3MobHBSb3V0ZXIpLCB0eXBlKHVpbnQyNTYpLm1heCk7CklFUkMyMCh0b2tlbjEpLmFwcHJvdmUoYWRkcmVzcyhscFJvdXRlciksIHR5cGUodWludDI1NikubWF4KTsKCi8vIFByb3ZpZGUgMTBlMTggd29ydGggb2YgbGlxdWlkaXR5IG9uIHRoZSByYW5nZSBvZiBbLTYwMCwgNjAwXQppbnQyNCB0aWNrTG93ZXIgPSAtNjAwOwppbnQyNCB0aWNrVXBwZXIgPSA2MDA7CmludDI1NiBsaXF1aWRpdHkgPSAxMGUxODsKbHBSb3V0ZXIubW9kaWZ5UG9zaXRpb24oCiAgICBwb29sS2V5LAogICAgSVBvb2xNYW5hZ2VyLk1vZGlmeVBvc2l0aW9uUGFyYW1zKHt0aWNrTG93ZXI6IHRpY2tMb3dlciwgdGlja1VwcGVyOiB0aWNrVXBwZXIsIGxpcXVpZGl0eURlbHRhOiBsaXF1aWRpdHl9KSwKICAgIG5ldyBieXRlcygwKQopOwo=", }, ] const html = `
      • Provide Liquidity to a Uniswap v4 Pool
      -

      ⚠️ Using the test router in production will lead to a loss of funds ⚠️

      -

      Using the v4-core provided test router, we can provide liquidity to a pool. These snippets should only be used for non-production, testing purposes

      Creating liquidity involves using periphery contracts. It is not recommended to directly provide liquidity with poolManager.modifyPosition

      +
      +

      Using the provided test router, we can provide liquidity to a pool. These snippets should only be used for non-production, testing purposes

      +

      (⚠️ Using the test router in production will lead to a loss of funds ⚠️ )

      +

      Providing liquidity involves 3 primary arguments:

        -
      • Which pool to swap on
      • +
      • Which pool to LP on
      • The range of the the liquidity, i.e. the upper and lower bounds
      • A liquidity value that determines input token amounts
      @@ -64,49 +66,35 @@ const html = `
        } }

      Examples of Providing Liquidity to a V4 Pool

      -
      // SPDX-License-Identifier: MIT
      -pragma solidity ^0.8.20;
      -
      -import {IERC20} from "forge-std/interfaces/IERC20.sol";
      -import {IPoolManager} from "@uniswap/v4-core/contracts/interfaces/IPoolManager.sol";
      -import {PoolKey} from "@uniswap/v4-core/contracts/types/PoolKey.sol";
      -import {PoolModifyPositionTest} from "@uniswap/v4-core/contracts/test/PoolModifyPositionTest.sol";
      -import {CurrencyLibrary, Currency} from "@uniswap/v4-core/contracts/types/Currency.sol";
      -
      -contract CreateLiquidityExampleInputs {
      -    using CurrencyLibrary for Currency;
      -
      -    // set the router address
      -    PoolModifyPositionTest lpRouter = PoolModifyPositionTest(0x01);
      +
      import {PoolModifyPositionTest} from "@uniswap/v4-core/contracts/test/PoolModifyPositionTest.sol";
       
      -    function exampleA() external {
      -        address token0 = address(0x11);
      -        address token1 = address(0x22);
      +PoolModifyPositionTest lpRouter = PoolModifyPositionTest(0x01);
      +address token0 = address(0x11);
      +address token1 = address(0x22);
      +address hookAddress = address(0x80);
       
      -        // Using a hookless pool
      -        PoolKey memory pool = PoolKey({
      -            currency0: Currency.wrap(token0),
      -            currency1: Currency.wrap(token1),
      -            fee: 3000,
      -            tickSpacing: 60,
      -            hooks: IHooks(address(0x0))
      -        });
      +// Pool that will receieve liquidity
      +PoolKey memory pool = PoolKey({
      +    currency0: Currency.wrap(token0),
      +    currency1: Currency.wrap(token1),
      +    fee: 3000,
      +    tickSpacing: 60,
      +    hooks: IHooks(hookAddress)
      +});
       
      -        // approve tokens to the LP Router
      -        IERC20(token0).approve(address(lpRouter), type(uint256).max);
      -        IERC20(token1).approve(address(lpRouter), type(uint256).max);
      +// approve tokens to the LP Router
      +IERC20(token0).approve(address(lpRouter), type(uint256).max);
      +IERC20(token1).approve(address(lpRouter), type(uint256).max);
       
      -        // Provide 10e18 worth of liquidity on the range of [-600, 600]
      -        int24 tickLower = -600;
      -        int24 tickUpper = 600;
      -        int256 liquidity = 10e18;
      -        lpRouter.modifyPosition(
      -            poolKey,
      -            IPoolManager.ModifyPositionParams({tickLower: tickLower, tickUpper: tickUpper, liquidityDelta: liquidity}),
      -            new bytes(0)
      -        );
      -    }
      -}
      +// Provide 10e18 worth of liquidity on the range of [-600, 600]
      +int24 tickLower = -600;
      +int24 tickUpper = 600;
      +int256 liquidity = 10e18;
      +lpRouter.modifyPosition(
      +    poolKey,
      +    IPoolManager.ModifyPositionParams({tickLower: tickLower, tickUpper: tickUpper, liquidityDelta: liquidity}),
      +    new bytes(0)
      +);
       
      ` export default html diff --git a/src/pages/create-liquidity/index.md b/src/pages/create-liquidity/index.md index 5cd0b1e1..726b6d94 100644 --- a/src/pages/create-liquidity/index.md +++ b/src/pages/create-liquidity/index.md @@ -7,15 +7,19 @@ keywords: [liquidity, LP, lp, provide, provision, supply] * Provide Liquidity to a Uniswap v4 Pool -⚠️ Using the test router in production **will lead to a loss of funds** ⚠️ +Creating liquidity involves using periphery contracts. It is **not** recommended to directly provide liquidity with `poolManager.modifyPosition` -Using the `v4-core` provided *test* router, we can provide liquidity to a pool. These snippets should only be used for non-production, testing purposes +--- -Creating liquidity involves using periphery contracts. It is **not** recommended to directly provide liquidity with `poolManager.modifyPosition` +Using the provided *test* router, we can provide liquidity to a pool. These snippets should only be used for non-production, testing purposes + +(⚠️ Using the test router in production **will lead to a loss of funds** ⚠️ ) + +--- Providing liquidity involves 3 primary arguments: -* Which pool to swap on +* Which pool to LP on * The range of the the liquidity, i.e. the upper and lower bounds * A `liquidity` value that determines input token amounts From 2eb4461eb228a76f9d1f5a5b25d1ef76c70f45b7 Mon Sep 17 00:00:00 2001 From: saucepoint Date: Mon, 13 Nov 2023 21:25:13 -0500 Subject: [PATCH 4/6] copy updates --- src/pages/swap/SwapExampleInputs.sol | 52 ----------- src/pages/swap/SwapExampleInputs.solsnippet | 39 ++++++++ src/pages/swap/index.html.ts | 98 +++++++++------------ src/pages/swap/index.md | 6 +- 4 files changed, 88 insertions(+), 107 deletions(-) delete mode 100644 src/pages/swap/SwapExampleInputs.sol create mode 100644 src/pages/swap/SwapExampleInputs.solsnippet diff --git a/src/pages/swap/SwapExampleInputs.sol b/src/pages/swap/SwapExampleInputs.sol deleted file mode 100644 index cba89446..00000000 --- a/src/pages/swap/SwapExampleInputs.sol +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; - -import {IPoolManager} from "@uniswap/v4-core/contracts/interfaces/IPoolManager.sol"; -import {PoolKey} from "@uniswap/v4-core/contracts/types/PoolKey.sol"; -import {PoolSwapTest} from "@uniswap/v4-core/contracts/test/PoolSwapTest.sol"; -import {TickMath} from "@uniswap/v4-core/contracts/libraries/TickMath.sol"; - -contract SwapExampleInputs { - // set the router address - PoolSwapTest swapRouter = PoolSwapTest(0x01); - - // slippage tolerance to allow for unlimited price impact - uint160 public constant MIN_PRICE_LIMIT = TickMath.MIN_SQRT_RATIO + 1; - uint160 public constant MAX_PRICE_LIMIT = TickMath.MAX_SQRT_RATIO - 1; - - function exampleA() internal { - address token0 = address(0x11); - address token1 = address(0x22); - - // Using a hookless pool - PoolKey memory pool = PoolKey({ - currency0: Currency.wrap(token0), - currency1: Currency.wrap(token1), - fee: 3000, - tickSpacing: 60, - hooks: IHooks(address(0x0)) - }); - - // approve tokens to the swap router - IERC20(token0).approve(address(swapRouter), type(uint256).max); - IERC20(token1).approve(address(swapRouter), type(uint256).max); - - // ---------------------------- // - // Swap 1e18 token0 into token1 - // ---------------------------- // - bool zeroForOne = true; - IPoolManager.SwapParams memory params = IPoolManager.SwapParams({ - zeroForOne: zeroForOne, - amountSpecified: 1e18, - sqrtPriceLimitX96: zeroForOne ? MIN_PRICE_LIMIT : MAX_PRICE_LIMIT // unlimited impact - }); - - // in v4, users have the option to receieve native ERC20s or wrapped ERC1155 tokens - // here, we'll take the ERC20s - PoolSwapTest.TestSettings memory testSettings = - PoolSwapTest.TestSettings({withdrawTokens: true, settleUsingTransfer: true}); - - bytes memory hookData = new bytes(0); // no hook data on the hookless pool - swapRouter.swap(key, params, testSettings, hookData); - } -} diff --git a/src/pages/swap/SwapExampleInputs.solsnippet b/src/pages/swap/SwapExampleInputs.solsnippet new file mode 100644 index 00000000..3e9a0b54 --- /dev/null +++ b/src/pages/swap/SwapExampleInputs.solsnippet @@ -0,0 +1,39 @@ +PoolSwapTest swapRouter = PoolSwapTest(0x01); + +// slippage tolerance to allow for unlimited price impact +uint160 public constant MIN_PRICE_LIMIT = TickMath.MIN_SQRT_RATIO + 1; +uint160 public constant MAX_PRICE_LIMIT = TickMath.MAX_SQRT_RATIO - 1; + +address token0 = address(0x11); +address token1 = address(0x22); +address hookAddr = address(0x33); + +PoolKey memory pool = PoolKey({ + currency0: Currency.wrap(token0), + currency1: Currency.wrap(token1), + fee: 3000, + tickSpacing: 60, + hooks: IHooks(hookAddr) +}); + +// approve tokens to the swap router +IERC20(token0).approve(address(swapRouter), type(uint256).max); +IERC20(token1).approve(address(swapRouter), type(uint256).max); + +// ---------------------------- // +// Swap 1e18 token0 into token1 +// ---------------------------- // +bool zeroForOne = true; +IPoolManager.SwapParams memory params = IPoolManager.SwapParams({ + zeroForOne: zeroForOne, + amountSpecified: 1e18, + sqrtPriceLimitX96: zeroForOne ? MIN_PRICE_LIMIT : MAX_PRICE_LIMIT // unlimited impact +}); + +// in v4, users have the option to receieve native ERC20s or wrapped ERC1155 tokens +// here, we'll take the ERC20s +PoolSwapTest.TestSettings memory testSettings = + PoolSwapTest.TestSettings({withdrawTokens: true, settleUsingTransfer: true}); + +bytes memory hookData = new bytes(0); // no hook data on the hookless pool +swapRouter.swap(key, params, testSettings, hookData); diff --git a/src/pages/swap/index.html.ts b/src/pages/swap/index.html.ts index fe341323..08dd23d0 100644 --- a/src/pages/swap/index.html.ts +++ b/src/pages/swap/index.html.ts @@ -16,15 +16,17 @@ export const codes = [ }, { fileName: "SwapExampleInputs.sol", - code: "Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVApwcmFnbWEgc29saWRpdHkgXjAuOC4yMDsKCmltcG9ydCB7SVBvb2xNYW5hZ2VyfSBmcm9tICJAdW5pc3dhcC92NC1jb3JlL2NvbnRyYWN0cy9pbnRlcmZhY2VzL0lQb29sTWFuYWdlci5zb2wiOwppbXBvcnQge1Bvb2xLZXl9IGZyb20gIkB1bmlzd2FwL3Y0LWNvcmUvY29udHJhY3RzL3R5cGVzL1Bvb2xLZXkuc29sIjsKaW1wb3J0IHtQb29sU3dhcFRlc3R9IGZyb20gIkB1bmlzd2FwL3Y0LWNvcmUvY29udHJhY3RzL3Rlc3QvUG9vbFN3YXBUZXN0LnNvbCI7CmltcG9ydCB7VGlja01hdGh9IGZyb20gIkB1bmlzd2FwL3Y0LWNvcmUvY29udHJhY3RzL2xpYnJhcmllcy9UaWNrTWF0aC5zb2wiOwoKY29udHJhY3QgU3dhcEV4YW1wbGVJbnB1dHMgewogICAgLy8gc2V0IHRoZSByb3V0ZXIgYWRkcmVzcwogICAgUG9vbFN3YXBUZXN0IHN3YXBSb3V0ZXIgPSBQb29sU3dhcFRlc3QoMHgwMSk7CgogICAgLy8gc2xpcHBhZ2UgdG9sZXJhbmNlIHRvIGFsbG93IGZvciB1bmxpbWl0ZWQgcHJpY2UgaW1wYWN0CiAgICB1aW50MTYwIHB1YmxpYyBjb25zdGFudCBNSU5fUFJJQ0VfTElNSVQgPSBUaWNrTWF0aC5NSU5fU1FSVF9SQVRJTyArIDE7CiAgICB1aW50MTYwIHB1YmxpYyBjb25zdGFudCBNQVhfUFJJQ0VfTElNSVQgPSBUaWNrTWF0aC5NQVhfU1FSVF9SQVRJTyAtIDE7CgogICAgZnVuY3Rpb24gZXhhbXBsZUEoKSBpbnRlcm5hbCB7CiAgICAgICAgYWRkcmVzcyB0b2tlbjAgPSBhZGRyZXNzKDB4MTEpOwogICAgICAgIGFkZHJlc3MgdG9rZW4xID0gYWRkcmVzcygweDIyKTsKCiAgICAgICAgLy8gVXNpbmcgYSBob29rbGVzcyBwb29sCiAgICAgICAgUG9vbEtleSBtZW1vcnkgcG9vbCA9IFBvb2xLZXkoewogICAgICAgICAgICBjdXJyZW5jeTA6IEN1cnJlbmN5LndyYXAodG9rZW4wKSwKICAgICAgICAgICAgY3VycmVuY3kxOiBDdXJyZW5jeS53cmFwKHRva2VuMSksCiAgICAgICAgICAgIGZlZTogMzAwMCwKICAgICAgICAgICAgdGlja1NwYWNpbmc6IDYwLAogICAgICAgICAgICBob29rczogSUhvb2tzKGFkZHJlc3MoMHgwKSkKICAgICAgICB9KTsKCiAgICAgICAgLy8gYXBwcm92ZSB0b2tlbnMgdG8gdGhlIHN3YXAgcm91dGVyCiAgICAgICAgSUVSQzIwKHRva2VuMCkuYXBwcm92ZShhZGRyZXNzKHN3YXBSb3V0ZXIpLCB0eXBlKHVpbnQyNTYpLm1heCk7CiAgICAgICAgSUVSQzIwKHRva2VuMSkuYXBwcm92ZShhZGRyZXNzKHN3YXBSb3V0ZXIpLCB0eXBlKHVpbnQyNTYpLm1heCk7CgogICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gLy8KICAgICAgICAvLyBTd2FwIDFlMTggdG9rZW4wIGludG8gdG9rZW4xCiAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAvLwogICAgICAgIGJvb2wgemVyb0Zvck9uZSA9IHRydWU7CiAgICAgICAgSVBvb2xNYW5hZ2VyLlN3YXBQYXJhbXMgbWVtb3J5IHBhcmFtcyA9IElQb29sTWFuYWdlci5Td2FwUGFyYW1zKHsKICAgICAgICAgICAgemVyb0Zvck9uZTogemVyb0Zvck9uZSwKICAgICAgICAgICAgYW1vdW50U3BlY2lmaWVkOiAxZTE4LAogICAgICAgICAgICBzcXJ0UHJpY2VMaW1pdFg5NjogemVyb0Zvck9uZSA/IE1JTl9QUklDRV9MSU1JVCA6IE1BWF9QUklDRV9MSU1JVCAvLyB1bmxpbWl0ZWQgaW1wYWN0CiAgICAgICAgfSk7CgogICAgICAgIC8vIGluIHY0LCB1c2VycyBoYXZlIHRoZSBvcHRpb24gdG8gcmVjZWlldmUgbmF0aXZlIEVSQzIwcyBvciB3cmFwcGVkIEVSQzExNTUgdG9rZW5zCiAgICAgICAgLy8gaGVyZSwgd2UnbGwgdGFrZSB0aGUgRVJDMjBzCiAgICAgICAgUG9vbFN3YXBUZXN0LlRlc3RTZXR0aW5ncyBtZW1vcnkgdGVzdFNldHRpbmdzID0KICAgICAgICAgICAgUG9vbFN3YXBUZXN0LlRlc3RTZXR0aW5ncyh7d2l0aGRyYXdUb2tlbnM6IHRydWUsIHNldHRsZVVzaW5nVHJhbnNmZXI6IHRydWV9KTsKCiAgICAgICAgYnl0ZXMgbWVtb3J5IGhvb2tEYXRhID0gbmV3IGJ5dGVzKDApOyAvLyBubyBob29rIGRhdGEgb24gdGhlIGhvb2tsZXNzIHBvb2wKICAgICAgICBzd2FwUm91dGVyLnN3YXAoa2V5LCBwYXJhbXMsIHRlc3RTZXR0aW5ncywgaG9va0RhdGEpOwogICAgfQp9Cg==", + code: "UG9vbFN3YXBUZXN0IHN3YXBSb3V0ZXIgPSBQb29sU3dhcFRlc3QoMHgwMSk7CgovLyBzbGlwcGFnZSB0b2xlcmFuY2UgdG8gYWxsb3cgZm9yIHVubGltaXRlZCBwcmljZSBpbXBhY3QKdWludDE2MCBwdWJsaWMgY29uc3RhbnQgTUlOX1BSSUNFX0xJTUlUID0gVGlja01hdGguTUlOX1NRUlRfUkFUSU8gKyAxOwp1aW50MTYwIHB1YmxpYyBjb25zdGFudCBNQVhfUFJJQ0VfTElNSVQgPSBUaWNrTWF0aC5NQVhfU1FSVF9SQVRJTyAtIDE7CgphZGRyZXNzIHRva2VuMCA9IGFkZHJlc3MoMHgxMSk7CmFkZHJlc3MgdG9rZW4xID0gYWRkcmVzcygweDIyKTsKYWRkcmVzcyBob29rQWRkciA9IGFkZHJlc3MoMHgzMyk7CgovLyBVc2luZyBhIGhvb2tsZXNzIHBvb2wKUG9vbEtleSBtZW1vcnkgcG9vbCA9IFBvb2xLZXkoewogICAgY3VycmVuY3kwOiBDdXJyZW5jeS53cmFwKHRva2VuMCksCiAgICBjdXJyZW5jeTE6IEN1cnJlbmN5LndyYXAodG9rZW4xKSwKICAgIGZlZTogMzAwMCwKICAgIHRpY2tTcGFjaW5nOiA2MCwKICAgIGhvb2tzOiBJSG9va3MoaG9va0FkZHIpCn0pOwoKLy8gYXBwcm92ZSB0b2tlbnMgdG8gdGhlIHN3YXAgcm91dGVyCklFUkMyMCh0b2tlbjApLmFwcHJvdmUoYWRkcmVzcyhzd2FwUm91dGVyKSwgdHlwZSh1aW50MjU2KS5tYXgpOwpJRVJDMjAodG9rZW4xKS5hcHByb3ZlKGFkZHJlc3Moc3dhcFJvdXRlciksIHR5cGUodWludDI1NikubWF4KTsKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gLy8KLy8gU3dhcCAxZTE4IHRva2VuMCBpbnRvIHRva2VuMQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIC8vCmJvb2wgemVyb0Zvck9uZSA9IHRydWU7CklQb29sTWFuYWdlci5Td2FwUGFyYW1zIG1lbW9yeSBwYXJhbXMgPSBJUG9vbE1hbmFnZXIuU3dhcFBhcmFtcyh7CiAgICB6ZXJvRm9yT25lOiB6ZXJvRm9yT25lLAogICAgYW1vdW50U3BlY2lmaWVkOiAxZTE4LAogICAgc3FydFByaWNlTGltaXRYOTY6IHplcm9Gb3JPbmUgPyBNSU5fUFJJQ0VfTElNSVQgOiBNQVhfUFJJQ0VfTElNSVQgLy8gdW5saW1pdGVkIGltcGFjdAp9KTsKCi8vIGluIHY0LCB1c2VycyBoYXZlIHRoZSBvcHRpb24gdG8gcmVjZWlldmUgbmF0aXZlIEVSQzIwcyBvciB3cmFwcGVkIEVSQzExNTUgdG9rZW5zCi8vIGhlcmUsIHdlJ2xsIHRha2UgdGhlIEVSQzIwcwpQb29sU3dhcFRlc3QuVGVzdFNldHRpbmdzIG1lbW9yeSB0ZXN0U2V0dGluZ3MgPQogICAgUG9vbFN3YXBUZXN0LlRlc3RTZXR0aW5ncyh7d2l0aGRyYXdUb2tlbnM6IHRydWUsIHNldHRsZVVzaW5nVHJhbnNmZXI6IHRydWV9KTsKCmJ5dGVzIG1lbW9yeSBob29rRGF0YSA9IG5ldyBieXRlcygwKTsgLy8gbm8gaG9vayBkYXRhIG9uIHRoZSBob29rbGVzcyBwb29sCnN3YXBSb3V0ZXIuc3dhcChrZXksIHBhcmFtcywgdGVzdFNldHRpbmdzLCBob29rRGF0YSk7Cg==", }, ] const html = `
      • Swap between tokens on a single pool
      -

      Using the v4-core provided test router, we can swap on a single pool. These snippets should only be used for non-production, testing purposes

      Swapping will typically make use of a periphery contract. It is not recommended to directly swap with poolManager.swap

      +
      +

      Using the v4-core provided test router, we can swap on a single pool. These snippets should only be used for non-production, testing purposes

      +

      Swapping involves 3 primary arguments:

      • Which pool to swap on
      • @@ -70,58 +72,46 @@ const html = `
          } }

      Examples of Swapping on a V4 Pool

      -
      // SPDX-License-Identifier: MIT
      -pragma solidity ^0.8.20;
      -
      -import {IPoolManager} from "@uniswap/v4-core/contracts/interfaces/IPoolManager.sol";
      -import {PoolKey} from "@uniswap/v4-core/contracts/types/PoolKey.sol";
      -import {PoolSwapTest} from "@uniswap/v4-core/contracts/test/PoolSwapTest.sol";
      -import {TickMath} from "@uniswap/v4-core/contracts/libraries/TickMath.sol";
      -
      -contract SwapExampleInputs {
      -    // set the router address
      -    PoolSwapTest swapRouter = PoolSwapTest(0x01);
      -
      -    // slippage tolerance to allow for unlimited price impact
      -    uint160 public constant MIN_PRICE_LIMIT = TickMath.MIN_SQRT_RATIO + 1;
      -    uint160 public constant MAX_PRICE_LIMIT = TickMath.MAX_SQRT_RATIO - 1;
      -
      -    function exampleA() internal {
      -        address token0 = address(0x11);
      -        address token1 = address(0x22);
      -
      -        // Using a hookless pool
      -        PoolKey memory pool = PoolKey({
      -            currency0: Currency.wrap(token0),
      -            currency1: Currency.wrap(token1),
      -            fee: 3000,
      -            tickSpacing: 60,
      -            hooks: IHooks(address(0x0))
      -        });
      -
      -        // approve tokens to the swap router
      -        IERC20(token0).approve(address(swapRouter), type(uint256).max);
      -        IERC20(token1).approve(address(swapRouter), type(uint256).max);
      -
      -        // ---------------------------- //
      -        // Swap 1e18 token0 into token1
      -        // ---------------------------- //
      -        bool zeroForOne = true;
      -        IPoolManager.SwapParams memory params = IPoolManager.SwapParams({
      -            zeroForOne: zeroForOne,
      -            amountSpecified: 1e18,
      -            sqrtPriceLimitX96: zeroForOne ? MIN_PRICE_LIMIT : MAX_PRICE_LIMIT // unlimited impact
      -        });
      -
      -        // in v4, users have the option to receieve native ERC20s or wrapped ERC1155 tokens
      -        // here, we'll take the ERC20s
      -        PoolSwapTest.TestSettings memory testSettings =
      -            PoolSwapTest.TestSettings({withdrawTokens: true, settleUsingTransfer: true});
      -
      -        bytes memory hookData = new bytes(0); // no hook data on the hookless pool
      -        swapRouter.swap(key, params, testSettings, hookData);
      -    }
      -}
      +
      PoolSwapTest swapRouter = PoolSwapTest(0x01);
      +
      +// slippage tolerance to allow for unlimited price impact
      +uint160 public constant MIN_PRICE_LIMIT = TickMath.MIN_SQRT_RATIO + 1;
      +uint160 public constant MAX_PRICE_LIMIT = TickMath.MAX_SQRT_RATIO - 1;
      +
      +address token0 = address(0x11);
      +address token1 = address(0x22);
      +address hookAddr = address(0x33);
      +
      +// Using a hookless pool
      +PoolKey memory pool = PoolKey({
      +    currency0: Currency.wrap(token0),
      +    currency1: Currency.wrap(token1),
      +    fee: 3000,
      +    tickSpacing: 60,
      +    hooks: IHooks(hookAddr)
      +});
      +
      +// approve tokens to the swap router
      +IERC20(token0).approve(address(swapRouter), type(uint256).max);
      +IERC20(token1).approve(address(swapRouter), type(uint256).max);
      +
      +// ---------------------------- //
      +// Swap 1e18 token0 into token1
      +// ---------------------------- //
      +bool zeroForOne = true;
      +IPoolManager.SwapParams memory params = IPoolManager.SwapParams({
      +    zeroForOne: zeroForOne,
      +    amountSpecified: 1e18,
      +    sqrtPriceLimitX96: zeroForOne ? MIN_PRICE_LIMIT : MAX_PRICE_LIMIT // unlimited impact
      +});
      +
      +// in v4, users have the option to receieve native ERC20s or wrapped ERC1155 tokens
      +// here, we'll take the ERC20s
      +PoolSwapTest.TestSettings memory testSettings =
      +    PoolSwapTest.TestSettings({withdrawTokens: true, settleUsingTransfer: true});
      +
      +bytes memory hookData = new bytes(0); // no hook data on the hookless pool
      +swapRouter.swap(key, params, testSettings, hookData);
       
      ` export default html diff --git a/src/pages/swap/index.md b/src/pages/swap/index.md index 28316b0c..e75a2903 100644 --- a/src/pages/swap/index.md +++ b/src/pages/swap/index.md @@ -7,9 +7,13 @@ keywords: [swap, trade, swapping] * Swap between tokens on a single pool +Swapping will typically make use of a periphery contract. It is **not** recommended to directly swap with `poolManager.swap` + +--- + Using the `v4-core` provided *test* router, we can swap on a single pool. These snippets should only be used for non-production, testing purposes -Swapping will typically make use of a periphery contract. It is **not** recommended to directly swap with `poolManager.swap` +--- Swapping involves 3 primary arguments: From 04a1d92833539fbb50b90d17761bd57e89f2497c Mon Sep 17 00:00:00 2001 From: saucepoint Date: Mon, 13 Nov 2023 21:50:38 -0500 Subject: [PATCH 5/6] linting --- src/components/Footer.tsx | 11 +++-- src/keywords.json | 26 ++-------- src/nav.ts | 22 +++------ src/pages/create-liquidity/index.html.ts | 25 ++++------ src/pages/create-liquidity/index.md | 11 +++-- src/pages/index.tsx | 9 ++-- src/pages/initialize/index.html.ts | 33 +++++-------- src/pages/initialize/index.md | 22 ++++----- src/pages/swap/index.html.ts | 22 ++++----- src/pages/swap/index.md | 11 +++-- src/routes.tsx | 34 ++++++------- src/search.json | 62 ++++++------------------ 12 files changed, 110 insertions(+), 178 deletions(-) diff --git a/src/components/Footer.tsx b/src/components/Footer.tsx index 4ae40904..c6ab047d 100644 --- a/src/components/Footer.tsx +++ b/src/components/Footer.tsx @@ -38,10 +38,7 @@ function Footer() {
*/}
- + source
|
@@ -52,6 +49,12 @@ function Footer() { license
+
+ (fork of  + + solidity-by-example) + +
) } diff --git a/src/keywords.json b/src/keywords.json index a7c01221..6e67db62 100644 --- a/src/keywords.json +++ b/src/keywords.json @@ -1,23 +1,5 @@ { - "/swap": [ - "swap", - "trade", - "swapping" - ], - "/initialize": [ - "pool", - "initialize", - "init", - "create", - "pair", - "factory" - ], - "/create-liquidity": [ - "liquidity", - "LP", - "lp", - "provide", - "provision", - "supply" - ] -} \ No newline at end of file + "/swap": ["swap", "trade", "swapping"], + "/initialize": ["pool", "initialize", "init", "create", "pair", "factory"], + "/create-liquidity": ["liquidity", "LP", "lp", "provide", "provision", "supply"] +} diff --git a/src/nav.ts b/src/nav.ts index 947a376f..94ce3f70 100644 --- a/src/nav.ts +++ b/src/nav.ts @@ -8,36 +8,30 @@ export interface Translation { url: string } -export const TRANSLATIONS: Translation[] = [ - -] +export const TRANSLATIONS: Translation[] = [] export const SOL_ROUTES: Route[] = [ { path: "initialize", - title: "Initialize Pool" + title: "Initialize Pool", }, { path: "create-liquidity", - title: "Create Liquidity" + title: "Create Liquidity", }, { path: "swap", - title: "Swap" + title: "Swap", }, ] -export const APP_ROUTES: Route[] = [ -] +export const APP_ROUTES: Route[] = [] -const HACK_ROUTES: Route[] = [ -] +const HACK_ROUTES: Route[] = [] -export const TEST_ROUTES: Route[] = [ -] +export const TEST_ROUTES: Route[] = [] -export const DEFI_ROUTES = [ -] +export const DEFI_ROUTES = [] export const ROUTES_BY_CATEGORY = [ { diff --git a/src/pages/create-liquidity/index.html.ts b/src/pages/create-liquidity/index.html.ts index 66357fbd..aa84ffe3 100644 --- a/src/pages/create-liquidity/index.html.ts +++ b/src/pages/create-liquidity/index.html.ts @@ -3,24 +3,17 @@ export const version = "0.8.20" export const title = "Create Liquidity" export const description = "Providing Liquidity to a Uniswap V4 Pool" -export const keywords = [ - "liquidity", - "LP", - "lp", - "provide", - "provision", - "supply", -] +export const keywords = ["liquidity", "LP", "lp", "provide", "provision", "supply"] export const codes = [ - { - fileName: "CreateLiquidity.sol", - code: "Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVApwcmFnbWEgc29saWRpdHkgXjAuOC4yMDsKCmltcG9ydCB7SVBvb2xNYW5hZ2VyfSBmcm9tICJAdW5pc3dhcC92NC1jb3JlL2NvbnRyYWN0cy9pbnRlcmZhY2VzL0lQb29sTWFuYWdlci5zb2wiOwppbXBvcnQge1Bvb2xLZXl9IGZyb20gIkB1bmlzd2FwL3Y0LWNvcmUvY29udHJhY3RzL3R5cGVzL1Bvb2xLZXkuc29sIjsKaW1wb3J0IHtQb29sTW9kaWZ5UG9zaXRpb25UZXN0fSBmcm9tICJAdW5pc3dhcC92NC1jb3JlL2NvbnRyYWN0cy90ZXN0L1Bvb2xNb2RpZnlQb3NpdGlvblRlc3Quc29sIjsKCmNvbnRyYWN0IENyZWF0ZUxpcXVpZGl0eSB7CiAgICAvLyBzZXQgdGhlIHJvdXRlciBhZGRyZXNzCiAgICBQb29sTW9kaWZ5UG9zaXRpb25UZXN0IGxwUm91dGVyID0gUG9vbE1vZGlmeVBvc2l0aW9uVGVzdCgweDAxKTsKCiAgICBmdW5jdGlvbiBjcmVhdGVMaXF1aWRpdHkoCiAgICAgICAgUG9vbEtleSBtZW1vcnkgcG9vbEtleSwKICAgICAgICBpbnQyNCB0aWNrTG93ZXIsCiAgICAgICAgaW50MjQgdGlja1VwcGVyLAogICAgICAgIGludDI1NiBsaXF1aWRpdHksCiAgICAgICAgYnl0ZXMgY2FsbGRhdGEgaG9va0RhdGEKICAgICkgZXh0ZXJuYWwgewogICAgICAgIC8vIGlmIDAgPCBsaXF1aWRpdHk6IGFkZCBsaXF1aWRpdHkgLS0gb3RoZXJ3aXNlIHJlbW92ZSBsaXF1aWRpdHkKICAgICAgICBscFJvdXRlci5tb2RpZnlQb3NpdGlvbigKICAgICAgICAgICAgcG9vbEtleSwKICAgICAgICAgICAgSVBvb2xNYW5hZ2VyLk1vZGlmeVBvc2l0aW9uUGFyYW1zKHt0aWNrTG93ZXI6IHRpY2tMb3dlciwgdGlja1VwcGVyOiB0aWNrVXBwZXIsIGxpcXVpZGl0eURlbHRhOiBsaXF1aWRpdHl9KSwKICAgICAgICAgICAgaG9va0RhdGEKICAgICAgICApOwogICAgfQp9Cg==", - }, - { - fileName: "CreateLiquidityExampleInputs.sol", - code: "aW1wb3J0IHtQb29sTW9kaWZ5UG9zaXRpb25UZXN0fSBmcm9tICJAdW5pc3dhcC92NC1jb3JlL2NvbnRyYWN0cy90ZXN0L1Bvb2xNb2RpZnlQb3NpdGlvblRlc3Quc29sIjsKClBvb2xNb2RpZnlQb3NpdGlvblRlc3QgbHBSb3V0ZXIgPSBQb29sTW9kaWZ5UG9zaXRpb25UZXN0KDB4MDEpOwphZGRyZXNzIHRva2VuMCA9IGFkZHJlc3MoMHgxMSk7CmFkZHJlc3MgdG9rZW4xID0gYWRkcmVzcygweDIyKTsKYWRkcmVzcyBob29rQWRkcmVzcyA9IGFkZHJlc3MoMHg4MCk7CgovLyBQb29sIHRoYXQgd2lsbCByZWNlaWV2ZSBsaXF1aWRpdHkKUG9vbEtleSBtZW1vcnkgcG9vbCA9IFBvb2xLZXkoewogICAgY3VycmVuY3kwOiBDdXJyZW5jeS53cmFwKHRva2VuMCksCiAgICBjdXJyZW5jeTE6IEN1cnJlbmN5LndyYXAodG9rZW4xKSwKICAgIGZlZTogMzAwMCwKICAgIHRpY2tTcGFjaW5nOiA2MCwKICAgIGhvb2tzOiBJSG9va3MoaG9va0FkZHJlc3MpCn0pOwoKLy8gYXBwcm92ZSB0b2tlbnMgdG8gdGhlIExQIFJvdXRlcgpJRVJDMjAodG9rZW4wKS5hcHByb3ZlKGFkZHJlc3MobHBSb3V0ZXIpLCB0eXBlKHVpbnQyNTYpLm1heCk7CklFUkMyMCh0b2tlbjEpLmFwcHJvdmUoYWRkcmVzcyhscFJvdXRlciksIHR5cGUodWludDI1NikubWF4KTsKCi8vIFByb3ZpZGUgMTBlMTggd29ydGggb2YgbGlxdWlkaXR5IG9uIHRoZSByYW5nZSBvZiBbLTYwMCwgNjAwXQppbnQyNCB0aWNrTG93ZXIgPSAtNjAwOwppbnQyNCB0aWNrVXBwZXIgPSA2MDA7CmludDI1NiBsaXF1aWRpdHkgPSAxMGUxODsKbHBSb3V0ZXIubW9kaWZ5UG9zaXRpb24oCiAgICBwb29sS2V5LAogICAgSVBvb2xNYW5hZ2VyLk1vZGlmeVBvc2l0aW9uUGFyYW1zKHt0aWNrTG93ZXI6IHRpY2tMb3dlciwgdGlja1VwcGVyOiB0aWNrVXBwZXIsIGxpcXVpZGl0eURlbHRhOiBsaXF1aWRpdHl9KSwKICAgIG5ldyBieXRlcygwKQopOwo=", - }, + { + fileName: "CreateLiquidity.sol", + code: "Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVApwcmFnbWEgc29saWRpdHkgXjAuOC4yMDsKCmltcG9ydCB7SVBvb2xNYW5hZ2VyfSBmcm9tICJAdW5pc3dhcC92NC1jb3JlL2NvbnRyYWN0cy9pbnRlcmZhY2VzL0lQb29sTWFuYWdlci5zb2wiOwppbXBvcnQge1Bvb2xLZXl9IGZyb20gIkB1bmlzd2FwL3Y0LWNvcmUvY29udHJhY3RzL3R5cGVzL1Bvb2xLZXkuc29sIjsKaW1wb3J0IHtQb29sTW9kaWZ5UG9zaXRpb25UZXN0fSBmcm9tICJAdW5pc3dhcC92NC1jb3JlL2NvbnRyYWN0cy90ZXN0L1Bvb2xNb2RpZnlQb3NpdGlvblRlc3Quc29sIjsKCmNvbnRyYWN0IENyZWF0ZUxpcXVpZGl0eSB7CiAgICAvLyBzZXQgdGhlIHJvdXRlciBhZGRyZXNzCiAgICBQb29sTW9kaWZ5UG9zaXRpb25UZXN0IGxwUm91dGVyID0gUG9vbE1vZGlmeVBvc2l0aW9uVGVzdCgweDAxKTsKCiAgICBmdW5jdGlvbiBjcmVhdGVMaXF1aWRpdHkoCiAgICAgICAgUG9vbEtleSBtZW1vcnkgcG9vbEtleSwKICAgICAgICBpbnQyNCB0aWNrTG93ZXIsCiAgICAgICAgaW50MjQgdGlja1VwcGVyLAogICAgICAgIGludDI1NiBsaXF1aWRpdHksCiAgICAgICAgYnl0ZXMgY2FsbGRhdGEgaG9va0RhdGEKICAgICkgZXh0ZXJuYWwgewogICAgICAgIC8vIGlmIDAgPCBsaXF1aWRpdHk6IGFkZCBsaXF1aWRpdHkgLS0gb3RoZXJ3aXNlIHJlbW92ZSBsaXF1aWRpdHkKICAgICAgICBscFJvdXRlci5tb2RpZnlQb3NpdGlvbigKICAgICAgICAgICAgcG9vbEtleSwKICAgICAgICAgICAgSVBvb2xNYW5hZ2VyLk1vZGlmeVBvc2l0aW9uUGFyYW1zKHt0aWNrTG93ZXI6IHRpY2tMb3dlciwgdGlja1VwcGVyOiB0aWNrVXBwZXIsIGxpcXVpZGl0eURlbHRhOiBsaXF1aWRpdHl9KSwKICAgICAgICAgICAgaG9va0RhdGEKICAgICAgICApOwogICAgfQp9Cg==", + }, + { + fileName: "CreateLiquidityExampleInputs.sol", + code: "aW1wb3J0IHtQb29sTW9kaWZ5UG9zaXRpb25UZXN0fSBmcm9tICJAdW5pc3dhcC92NC1jb3JlL2NvbnRyYWN0cy90ZXN0L1Bvb2xNb2RpZnlQb3NpdGlvblRlc3Quc29sIjsKClBvb2xNb2RpZnlQb3NpdGlvblRlc3QgbHBSb3V0ZXIgPSBQb29sTW9kaWZ5UG9zaXRpb25UZXN0KDB4MDEpOwphZGRyZXNzIHRva2VuMCA9IGFkZHJlc3MoMHgxMSk7CmFkZHJlc3MgdG9rZW4xID0gYWRkcmVzcygweDIyKTsKYWRkcmVzcyBob29rQWRkcmVzcyA9IGFkZHJlc3MoMHg4MCk7CgovLyBQb29sIHRoYXQgd2lsbCByZWNlaWV2ZSBsaXF1aWRpdHkKUG9vbEtleSBtZW1vcnkgcG9vbCA9IFBvb2xLZXkoewogICAgY3VycmVuY3kwOiBDdXJyZW5jeS53cmFwKHRva2VuMCksCiAgICBjdXJyZW5jeTE6IEN1cnJlbmN5LndyYXAodG9rZW4xKSwKICAgIGZlZTogMzAwMCwKICAgIHRpY2tTcGFjaW5nOiA2MCwKICAgIGhvb2tzOiBJSG9va3MoaG9va0FkZHJlc3MpCn0pOwoKLy8gYXBwcm92ZSB0b2tlbnMgdG8gdGhlIExQIFJvdXRlcgpJRVJDMjAodG9rZW4wKS5hcHByb3ZlKGFkZHJlc3MobHBSb3V0ZXIpLCB0eXBlKHVpbnQyNTYpLm1heCk7CklFUkMyMCh0b2tlbjEpLmFwcHJvdmUoYWRkcmVzcyhscFJvdXRlciksIHR5cGUodWludDI1NikubWF4KTsKCi8vIFByb3ZpZGUgMTBlMTggd29ydGggb2YgbGlxdWlkaXR5IG9uIHRoZSByYW5nZSBvZiBbLTYwMCwgNjAwXQppbnQyNCB0aWNrTG93ZXIgPSAtNjAwOwppbnQyNCB0aWNrVXBwZXIgPSA2MDA7CmludDI1NiBsaXF1aWRpdHkgPSAxMGUxODsKbHBSb3V0ZXIubW9kaWZ5UG9zaXRpb24oCiAgICBwb29sS2V5LAogICAgSVBvb2xNYW5hZ2VyLk1vZGlmeVBvc2l0aW9uUGFyYW1zKHt0aWNrTG93ZXI6IHRpY2tMb3dlciwgdGlja1VwcGVyOiB0aWNrVXBwZXIsIGxpcXVpZGl0eURlbHRhOiBsaXF1aWRpdHl9KSwKICAgIG5ldyBieXRlcygwKQopOwo=", + }, ] const html = `