Skip to content

Commit

Permalink
copy updates
Browse files Browse the repository at this point in the history
  • Loading branch information
saucepoint committed Nov 14, 2023
1 parent c65c55c commit 2eb4461
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 107 deletions.
52 changes: 0 additions & 52 deletions src/pages/swap/SwapExampleInputs.sol

This file was deleted.

39 changes: 39 additions & 0 deletions src/pages/swap/SwapExampleInputs.solsnippet
Original file line number Diff line number Diff line change
@@ -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);
98 changes: 44 additions & 54 deletions src/pages/swap/index.html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,17 @@ export const codes = [
},
{
fileName: "SwapExampleInputs.sol",
code: "Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVApwcmFnbWEgc29saWRpdHkgXjAuOC4yMDsKCmltcG9ydCB7SVBvb2xNYW5hZ2VyfSBmcm9tICJAdW5pc3dhcC92NC1jb3JlL2NvbnRyYWN0cy9pbnRlcmZhY2VzL0lQb29sTWFuYWdlci5zb2wiOwppbXBvcnQge1Bvb2xLZXl9IGZyb20gIkB1bmlzd2FwL3Y0LWNvcmUvY29udHJhY3RzL3R5cGVzL1Bvb2xLZXkuc29sIjsKaW1wb3J0IHtQb29sU3dhcFRlc3R9IGZyb20gIkB1bmlzd2FwL3Y0LWNvcmUvY29udHJhY3RzL3Rlc3QvUG9vbFN3YXBUZXN0LnNvbCI7CmltcG9ydCB7VGlja01hdGh9IGZyb20gIkB1bmlzd2FwL3Y0LWNvcmUvY29udHJhY3RzL2xpYnJhcmllcy9UaWNrTWF0aC5zb2wiOwoKY29udHJhY3QgU3dhcEV4YW1wbGVJbnB1dHMgewogICAgLy8gc2V0IHRoZSByb3V0ZXIgYWRkcmVzcwogICAgUG9vbFN3YXBUZXN0IHN3YXBSb3V0ZXIgPSBQb29sU3dhcFRlc3QoMHgwMSk7CgogICAgLy8gc2xpcHBhZ2UgdG9sZXJhbmNlIHRvIGFsbG93IGZvciB1bmxpbWl0ZWQgcHJpY2UgaW1wYWN0CiAgICB1aW50MTYwIHB1YmxpYyBjb25zdGFudCBNSU5fUFJJQ0VfTElNSVQgPSBUaWNrTWF0aC5NSU5fU1FSVF9SQVRJTyArIDE7CiAgICB1aW50MTYwIHB1YmxpYyBjb25zdGFudCBNQVhfUFJJQ0VfTElNSVQgPSBUaWNrTWF0aC5NQVhfU1FSVF9SQVRJTyAtIDE7CgogICAgZnVuY3Rpb24gZXhhbXBsZUEoKSBpbnRlcm5hbCB7CiAgICAgICAgYWRkcmVzcyB0b2tlbjAgPSBhZGRyZXNzKDB4MTEpOwogICAgICAgIGFkZHJlc3MgdG9rZW4xID0gYWRkcmVzcygweDIyKTsKCiAgICAgICAgLy8gVXNpbmcgYSBob29rbGVzcyBwb29sCiAgICAgICAgUG9vbEtleSBtZW1vcnkgcG9vbCA9IFBvb2xLZXkoewogICAgICAgICAgICBjdXJyZW5jeTA6IEN1cnJlbmN5LndyYXAodG9rZW4wKSwKICAgICAgICAgICAgY3VycmVuY3kxOiBDdXJyZW5jeS53cmFwKHRva2VuMSksCiAgICAgICAgICAgIGZlZTogMzAwMCwKICAgICAgICAgICAgdGlja1NwYWNpbmc6IDYwLAogICAgICAgICAgICBob29rczogSUhvb2tzKGFkZHJlc3MoMHgwKSkKICAgICAgICB9KTsKCiAgICAgICAgLy8gYXBwcm92ZSB0b2tlbnMgdG8gdGhlIHN3YXAgcm91dGVyCiAgICAgICAgSUVSQzIwKHRva2VuMCkuYXBwcm92ZShhZGRyZXNzKHN3YXBSb3V0ZXIpLCB0eXBlKHVpbnQyNTYpLm1heCk7CiAgICAgICAgSUVSQzIwKHRva2VuMSkuYXBwcm92ZShhZGRyZXNzKHN3YXBSb3V0ZXIpLCB0eXBlKHVpbnQyNTYpLm1heCk7CgogICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gLy8KICAgICAgICAvLyBTd2FwIDFlMTggdG9rZW4wIGludG8gdG9rZW4xCiAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAvLwogICAgICAgIGJvb2wgemVyb0Zvck9uZSA9IHRydWU7CiAgICAgICAgSVBvb2xNYW5hZ2VyLlN3YXBQYXJhbXMgbWVtb3J5IHBhcmFtcyA9IElQb29sTWFuYWdlci5Td2FwUGFyYW1zKHsKICAgICAgICAgICAgemVyb0Zvck9uZTogemVyb0Zvck9uZSwKICAgICAgICAgICAgYW1vdW50U3BlY2lmaWVkOiAxZTE4LAogICAgICAgICAgICBzcXJ0UHJpY2VMaW1pdFg5NjogemVyb0Zvck9uZSA/IE1JTl9QUklDRV9MSU1JVCA6IE1BWF9QUklDRV9MSU1JVCAvLyB1bmxpbWl0ZWQgaW1wYWN0CiAgICAgICAgfSk7CgogICAgICAgIC8vIGluIHY0LCB1c2VycyBoYXZlIHRoZSBvcHRpb24gdG8gcmVjZWlldmUgbmF0aXZlIEVSQzIwcyBvciB3cmFwcGVkIEVSQzExNTUgdG9rZW5zCiAgICAgICAgLy8gaGVyZSwgd2UnbGwgdGFrZSB0aGUgRVJDMjBzCiAgICAgICAgUG9vbFN3YXBUZXN0LlRlc3RTZXR0aW5ncyBtZW1vcnkgdGVzdFNldHRpbmdzID0KICAgICAgICAgICAgUG9vbFN3YXBUZXN0LlRlc3RTZXR0aW5ncyh7d2l0aGRyYXdUb2tlbnM6IHRydWUsIHNldHRsZVVzaW5nVHJhbnNmZXI6IHRydWV9KTsKCiAgICAgICAgYnl0ZXMgbWVtb3J5IGhvb2tEYXRhID0gbmV3IGJ5dGVzKDApOyAvLyBubyBob29rIGRhdGEgb24gdGhlIGhvb2tsZXNzIHBvb2wKICAgICAgICBzd2FwUm91dGVyLnN3YXAoa2V5LCBwYXJhbXMsIHRlc3RTZXR0aW5ncywgaG9va0RhdGEpOwogICAgfQp9Cg==",
code: "UG9vbFN3YXBUZXN0IHN3YXBSb3V0ZXIgPSBQb29sU3dhcFRlc3QoMHgwMSk7CgovLyBzbGlwcGFnZSB0b2xlcmFuY2UgdG8gYWxsb3cgZm9yIHVubGltaXRlZCBwcmljZSBpbXBhY3QKdWludDE2MCBwdWJsaWMgY29uc3RhbnQgTUlOX1BSSUNFX0xJTUlUID0gVGlja01hdGguTUlOX1NRUlRfUkFUSU8gKyAxOwp1aW50MTYwIHB1YmxpYyBjb25zdGFudCBNQVhfUFJJQ0VfTElNSVQgPSBUaWNrTWF0aC5NQVhfU1FSVF9SQVRJTyAtIDE7CgphZGRyZXNzIHRva2VuMCA9IGFkZHJlc3MoMHgxMSk7CmFkZHJlc3MgdG9rZW4xID0gYWRkcmVzcygweDIyKTsKYWRkcmVzcyBob29rQWRkciA9IGFkZHJlc3MoMHgzMyk7CgovLyBVc2luZyBhIGhvb2tsZXNzIHBvb2wKUG9vbEtleSBtZW1vcnkgcG9vbCA9IFBvb2xLZXkoewogICAgY3VycmVuY3kwOiBDdXJyZW5jeS53cmFwKHRva2VuMCksCiAgICBjdXJyZW5jeTE6IEN1cnJlbmN5LndyYXAodG9rZW4xKSwKICAgIGZlZTogMzAwMCwKICAgIHRpY2tTcGFjaW5nOiA2MCwKICAgIGhvb2tzOiBJSG9va3MoaG9va0FkZHIpCn0pOwoKLy8gYXBwcm92ZSB0b2tlbnMgdG8gdGhlIHN3YXAgcm91dGVyCklFUkMyMCh0b2tlbjApLmFwcHJvdmUoYWRkcmVzcyhzd2FwUm91dGVyKSwgdHlwZSh1aW50MjU2KS5tYXgpOwpJRVJDMjAodG9rZW4xKS5hcHByb3ZlKGFkZHJlc3Moc3dhcFJvdXRlciksIHR5cGUodWludDI1NikubWF4KTsKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gLy8KLy8gU3dhcCAxZTE4IHRva2VuMCBpbnRvIHRva2VuMQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIC8vCmJvb2wgemVyb0Zvck9uZSA9IHRydWU7CklQb29sTWFuYWdlci5Td2FwUGFyYW1zIG1lbW9yeSBwYXJhbXMgPSBJUG9vbE1hbmFnZXIuU3dhcFBhcmFtcyh7CiAgICB6ZXJvRm9yT25lOiB6ZXJvRm9yT25lLAogICAgYW1vdW50U3BlY2lmaWVkOiAxZTE4LAogICAgc3FydFByaWNlTGltaXRYOTY6IHplcm9Gb3JPbmUgPyBNSU5fUFJJQ0VfTElNSVQgOiBNQVhfUFJJQ0VfTElNSVQgLy8gdW5saW1pdGVkIGltcGFjdAp9KTsKCi8vIGluIHY0LCB1c2VycyBoYXZlIHRoZSBvcHRpb24gdG8gcmVjZWlldmUgbmF0aXZlIEVSQzIwcyBvciB3cmFwcGVkIEVSQzExNTUgdG9rZW5zCi8vIGhlcmUsIHdlJ2xsIHRha2UgdGhlIEVSQzIwcwpQb29sU3dhcFRlc3QuVGVzdFNldHRpbmdzIG1lbW9yeSB0ZXN0U2V0dGluZ3MgPQogICAgUG9vbFN3YXBUZXN0LlRlc3RTZXR0aW5ncyh7d2l0aGRyYXdUb2tlbnM6IHRydWUsIHNldHRsZVVzaW5nVHJhbnNmZXI6IHRydWV9KTsKCmJ5dGVzIG1lbW9yeSBob29rRGF0YSA9IG5ldyBieXRlcygwKTsgLy8gbm8gaG9vayBkYXRhIG9uIHRoZSBob29rbGVzcyBwb29sCnN3YXBSb3V0ZXIuc3dhcChrZXksIHBhcmFtcywgdGVzdFNldHRpbmdzLCBob29rRGF0YSk7Cg==",
},
]

const html = `<ul>
<li>Swap between tokens on a single pool</li>
</ul>
<p>Using the <code>v4-core</code> provided <em>test</em> router, we can swap on a single pool. These snippets should only be used for non-production, testing purposes</p>
<p>Swapping will typically make use of a periphery contract. It is <strong>not</strong> recommended to directly swap with <code>poolManager.swap</code></p>
<hr>
<p>Using the <code>v4-core</code> provided <em>test</em> router, we can swap on a single pool. These snippets should only be used for non-production, testing purposes</p>
<hr>
<p>Swapping involves 3 primary arguments:</p>
<ul>
<li>Which pool to swap on</li>
Expand Down Expand Up @@ -70,58 +72,46 @@ const html = `<ul>
}
}
</code></pre><h3>Examples of Swapping on a V4 Pool</h3>
<pre><code class="language-solidity"><span class="hljs-comment">// SPDX-License-Identifier: MIT</span>
<span class="hljs-meta"><span class="hljs-keyword">pragma</span> <span class="hljs-keyword">solidity</span> ^0.8.20;</span>
<span class="hljs-keyword">import</span> {<span class="hljs-title">IPoolManager</span>} <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">"@uniswap/v4-core/contracts/interfaces/IPoolManager.sol"</span>;
<span class="hljs-keyword">import</span> {<span class="hljs-title">PoolKey</span>} <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">"@uniswap/v4-core/contracts/types/PoolKey.sol"</span>;
<span class="hljs-keyword">import</span> {<span class="hljs-title">PoolSwapTest</span>} <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">"@uniswap/v4-core/contracts/test/PoolSwapTest.sol"</span>;
<span class="hljs-keyword">import</span> {<span class="hljs-title">TickMath</span>} <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">"@uniswap/v4-core/contracts/libraries/TickMath.sol"</span>;
<span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">SwapExampleInputs</span> </span>{
<span class="hljs-comment">// set the router address</span>
PoolSwapTest swapRouter <span class="hljs-operator">=</span> PoolSwapTest(<span class="hljs-number">0x01</span>);
<span class="hljs-comment">// slippage tolerance to allow for unlimited price impact</span>
<span class="hljs-keyword">uint160</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">constant</span> MIN_PRICE_LIMIT <span class="hljs-operator">=</span> TickMath.MIN_SQRT_RATIO <span class="hljs-operator">+</span> <span class="hljs-number">1</span>;
<span class="hljs-keyword">uint160</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">constant</span> MAX_PRICE_LIMIT <span class="hljs-operator">=</span> TickMath.MAX_SQRT_RATIO <span class="hljs-operator">-</span> <span class="hljs-number">1</span>;
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">exampleA</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">internal</span></span> </span>{
<span class="hljs-keyword">address</span> token0 <span class="hljs-operator">=</span> <span class="hljs-keyword">address</span>(<span class="hljs-number">0x11</span>);
<span class="hljs-keyword">address</span> token1 <span class="hljs-operator">=</span> <span class="hljs-keyword">address</span>(<span class="hljs-number">0x22</span>);
<span class="hljs-comment">// Using a hookless pool</span>
PoolKey <span class="hljs-keyword">memory</span> pool <span class="hljs-operator">=</span> PoolKey({
currency0: Currency.<span class="hljs-built_in">wrap</span>(token0),
currency1: Currency.<span class="hljs-built_in">wrap</span>(token1),
fee: <span class="hljs-number">3000</span>,
tickSpacing: <span class="hljs-number">60</span>,
hooks: IHooks(<span class="hljs-keyword">address</span>(<span class="hljs-number">0x0</span>))
});
<span class="hljs-comment">// approve tokens to the swap router</span>
IERC20(token0).approve(<span class="hljs-keyword">address</span>(swapRouter), <span class="hljs-keyword">type</span>(<span class="hljs-keyword">uint256</span>).<span class="hljs-built_in">max</span>);
IERC20(token1).approve(<span class="hljs-keyword">address</span>(swapRouter), <span class="hljs-keyword">type</span>(<span class="hljs-keyword">uint256</span>).<span class="hljs-built_in">max</span>);
<span class="hljs-comment">// ---------------------------- //</span>
<span class="hljs-comment">// Swap 1e18 token0 into token1</span>
<span class="hljs-comment">// ---------------------------- //</span>
<span class="hljs-keyword">bool</span> zeroForOne <span class="hljs-operator">=</span> <span class="hljs-literal">true</span>;
IPoolManager.SwapParams <span class="hljs-keyword">memory</span> params <span class="hljs-operator">=</span> IPoolManager.SwapParams({
zeroForOne: zeroForOne,
amountSpecified: <span class="hljs-number">1e18</span>,
sqrtPriceLimitX96: zeroForOne ? MIN_PRICE_LIMIT : MAX_PRICE_LIMIT <span class="hljs-comment">// unlimited impact</span>
});
<span class="hljs-comment">// in v4, users have the option to receieve native ERC20s or wrapped ERC1155 tokens</span>
<span class="hljs-comment">// here, we&#x27;ll take the ERC20s</span>
PoolSwapTest.TestSettings <span class="hljs-keyword">memory</span> testSettings <span class="hljs-operator">=</span>
PoolSwapTest.TestSettings({withdrawTokens: <span class="hljs-literal">true</span>, settleUsingTransfer: <span class="hljs-literal">true</span>});
<span class="hljs-keyword">bytes</span> <span class="hljs-keyword">memory</span> hookData <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-keyword">bytes</span>(<span class="hljs-number">0</span>); <span class="hljs-comment">// no hook data on the hookless pool</span>
swapRouter.swap(key, params, testSettings, hookData);
}
}
<pre><code class="language-solidity">PoolSwapTest swapRouter <span class="hljs-operator">=</span> PoolSwapTest(<span class="hljs-number">0x01</span>);
<span class="hljs-comment">// slippage tolerance to allow for unlimited price impact</span>
<span class="hljs-keyword">uint160</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">constant</span> MIN_PRICE_LIMIT <span class="hljs-operator">=</span> TickMath.MIN_SQRT_RATIO <span class="hljs-operator">+</span> <span class="hljs-number">1</span>;
<span class="hljs-keyword">uint160</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">constant</span> MAX_PRICE_LIMIT <span class="hljs-operator">=</span> TickMath.MAX_SQRT_RATIO <span class="hljs-operator">-</span> <span class="hljs-number">1</span>;
<span class="hljs-keyword">address</span> token0 <span class="hljs-operator">=</span> <span class="hljs-keyword">address</span>(<span class="hljs-number">0x11</span>);
<span class="hljs-keyword">address</span> token1 <span class="hljs-operator">=</span> <span class="hljs-keyword">address</span>(<span class="hljs-number">0x22</span>);
<span class="hljs-keyword">address</span> hookAddr <span class="hljs-operator">=</span> <span class="hljs-keyword">address</span>(<span class="hljs-number">0x33</span>);
<span class="hljs-comment">// Using a hookless pool</span>
PoolKey <span class="hljs-keyword">memory</span> pool <span class="hljs-operator">=</span> PoolKey({
currency0: Currency.<span class="hljs-built_in">wrap</span>(token0),
currency1: Currency.<span class="hljs-built_in">wrap</span>(token1),
fee: <span class="hljs-number">3000</span>,
tickSpacing: <span class="hljs-number">60</span>,
hooks: IHooks(hookAddr)
});
<span class="hljs-comment">// approve tokens to the swap router</span>
IERC20(token0).approve(<span class="hljs-keyword">address</span>(swapRouter), <span class="hljs-keyword">type</span>(<span class="hljs-keyword">uint256</span>).<span class="hljs-built_in">max</span>);
IERC20(token1).approve(<span class="hljs-keyword">address</span>(swapRouter), <span class="hljs-keyword">type</span>(<span class="hljs-keyword">uint256</span>).<span class="hljs-built_in">max</span>);
<span class="hljs-comment">// ---------------------------- //</span>
<span class="hljs-comment">// Swap 1e18 token0 into token1</span>
<span class="hljs-comment">// ---------------------------- //</span>
<span class="hljs-keyword">bool</span> zeroForOne <span class="hljs-operator">=</span> <span class="hljs-literal">true</span>;
IPoolManager.SwapParams <span class="hljs-keyword">memory</span> params <span class="hljs-operator">=</span> IPoolManager.SwapParams({
zeroForOne: zeroForOne,
amountSpecified: <span class="hljs-number">1e18</span>,
sqrtPriceLimitX96: zeroForOne ? MIN_PRICE_LIMIT : MAX_PRICE_LIMIT <span class="hljs-comment">// unlimited impact</span>
});
<span class="hljs-comment">// in v4, users have the option to receieve native ERC20s or wrapped ERC1155 tokens</span>
<span class="hljs-comment">// here, we&#x27;ll take the ERC20s</span>
PoolSwapTest.TestSettings <span class="hljs-keyword">memory</span> testSettings <span class="hljs-operator">=</span>
PoolSwapTest.TestSettings({withdrawTokens: <span class="hljs-literal">true</span>, settleUsingTransfer: <span class="hljs-literal">true</span>});
<span class="hljs-keyword">bytes</span> <span class="hljs-keyword">memory</span> hookData <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-keyword">bytes</span>(<span class="hljs-number">0</span>); <span class="hljs-comment">// no hook data on the hookless pool</span>
swapRouter.swap(key, params, testSettings, hookData);
</code></pre>`

export default html
6 changes: 5 additions & 1 deletion src/pages/swap/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down

0 comments on commit 2eb4461

Please sign in to comment.