{"id":337592,"date":"2022-08-26T21:00:24","date_gmt":"2022-08-26T21:00:24","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=337592"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=337592","title":{"rendered":"<span>Uniswap v3 Single Swaps (\u043f\u0435\u0440\u0435\u0432\u043e\u0434 \u0433\u0430\u0439\u0434\u0430)<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0445\u043e\u0440\u043e\u0448\u0438\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u044b\u0435 \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u044b,\u044f \u043b\u0438\u0448\u044c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0445\u043e\u0447\u0443 \u0440\u0430\u0441\u043a\u0440\u044b\u0442\u044c \u0438\u0445 \u0434\u043b\u044f \u0440\u0443\u043d\u0435\u0442\u0430<\/p>\n<h3>Single Swaps<\/h3>\n<p>\u041f\u0440\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043e\u0431\u043c\u0435\u043d\u0430(\u0441\u0432\u043e\u043f\u044b) \u2014  \u0441\u0430\u043c\u043e\u0435 \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u043e\u043d\u0435\u043d\u043d\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 Uniswap. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c  single-path swap \u0432 \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430\u0445. \u041a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438,\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u043f\u043e\u044d\u0442\u0430\u043f\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c.<\/p>\n<ul>\n<li>\n<p><code>swapExactInputSingle(...)<\/code><\/p>\n<\/li>\n<li>\n<p><code>swapExactOutputSingle(...)<\/code><\/p>\n<\/li>\n<\/ul>\n<p><strong>swapExactInputSingle<\/strong> \u2014  \u043e\u0431\u043c\u0435\u043d\u0438\u0432\u0430\u0435\u0442 \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0434\u043d\u043e\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430 \u043d\u0430 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430.( fix one \u2192 max another  )<\/p>\n<p>\u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u0435\u0442 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 <code>ExactInputSingleParams <\/code>\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>exactInputSingle(...)<\/code>\u0438\u0437 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430<code> ISwapRouter<\/code><\/p>\n<p><strong>swapExactOutputSingle<\/strong> \u2014 \u043e\u0431\u043c\u0435\u043d\u0438\u0432\u0430\u0435\u0442 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0434\u043d\u043e\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430 \u043d\u0430 \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430. ( Min one \u2192 fix another )<\/p>\n<p>\u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u0435\u0442 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443  <code>ExactOutputSingleParams<\/code> \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>exactOutputSingle(...)<\/code> \u0438\u0437 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 <code>ISwapRouter<\/code>.<\/p>\n<p>\u0414\u043b\u044f \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430,\u0430\u0434\u0440\u0435\u0441\u0430 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u0432 \u0442\u043e\u043a\u0435\u043d\u043e\u0432 (\u0442\u0443\u0442 DAI \u0438 <code>WETH9<\/code>) \u0437\u0430\u0445\u0430\u0440\u0434\u043a\u043e\u0434\u0438\u043b\u0438. \u041e\u0447\u0435\u0432\u0438\u0434\u043d\u043e,\u0447\u0442\u043e \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u043c\u043e\u0436\u043d\u043e \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u043f\u0443\u043b\u044b \u0438 \u0442\u043e\u043a\u0435\u043d\u044b \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438. <\/p>\n<h3>Set Up the Contract<\/h3>\n<p>abicoder v2, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u0434\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0435 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u044b \u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0432 calldata, \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0430\u044f \u043f\u0440\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 \u0441\u0432\u043e\u043f\u0430.<\/p>\n<pre><code class=\"cpp\">\/\/ SPDX-License-Identifier: GPL-2.0-or-later pragma solidity =0.7.6; pragma abicoder v2;<\/code><\/pre>\n<p>\u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043f\u0430\u043a\u0435\u0442\u0438\u043a\u0438 (\u0447\u0435\u0440\u0435\u0437 npm \u0438\u043b\u0438 yarn)<\/p>\n<pre><code class=\"cpp\">import '@uniswap\/v3-periphery\/contracts\/interfaces\/ISwapRouter.sol'; import '@uniswap\/v3-periphery\/contracts\/libraries\/TransferHelper.sol';<\/code><\/pre>\n<p>C\u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 SwapExamples, \u0438 \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u043c immutable public \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e swapRouter \u0442\u0438\u043f\u0430 ISwapRouter. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0430\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 ISwapRouter.<\/p>\n<pre><code class=\"cpp\">contract SwapExamples {     \/\/ For the scope of these swap examples,     \/\/ we will detail the design considerations when using `exactInput`, `exactInputSingle`, `exactOutput`, and  `exactOutputSingle`.     \/\/ It should be noted that for the sake of these examples we pass in the swap router as a constructor argument instead of inheriting it.     \/\/ More advanced example contracts will detail how to inherit the swap router safely.     \/\/ This example swaps DAI\/WETH9 for single path swaps and DAI\/USDC\/WETH9 for multi path swaps.      ISwapRouter public immutable swapRouter;<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0445\u0430\u0440\u0434\u043a\u043e\u0434\u0438\u043c \u0430\u0434\u0440\u0435\u0441\u0430 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u0432 \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u0438 \u0443\u0440\u043e\u0432\u043d\u0438 \u043a\u043e\u043c\u0438\u0441\u0441\u0438\u0439 \u043f\u0443\u043b\u0430. <\/p>\n<pre><code class=\"cpp\">    address public constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F;     address public constant WETH9 = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;     address public constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;      \/\/ For this example, we will set the pool fee to 0.3%.     uint24 public constant poolFee = 3000;      constructor(ISwapRouter _swapRouter) {         swapRouter = _swapRouter;     }<\/code><\/pre>\n<h3> Exact Input Swaps<\/h3>\n<p>\u0412\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u0439(\u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c) \u0434\u043e\u043b\u0436\u0435\u043d \u0443\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044c \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u043d\u0430 \u0441\u043d\u044f\u0442\u0438\u0435 \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u0441\u043e \u0441\u0447\u0435\u0442\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0435\u0433\u043e \u0430\u0434\u0440\u0435\u0441\u0430 \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u0432\u043e\u043f\u0430. &#171;\u0423\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044c&#187; \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043d\u0430 \u043d\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>approv\u0435<\/code>.\u041f\u043e\u043c\u043d\u0438\u0442\u0435, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043d\u0430\u0448 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u044d\u0442\u043e \u0441\u0430\u043c \u043f\u043e \u0441\u0435\u0431\u0435 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442, \u0430 \u043d\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0435\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b(\u043d\u0430\u0441) \u0442\u043e, \u043c\u044b \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0434\u043e\u0431\u0440\u0438\u0442\u044c(\u0443\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044c) \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 <code>Uniswap protocol router<\/code>\u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u043e\u043a\u0435\u043d\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0431\u0443\u0434\u0435\u0442 \u0432\u043b\u0430\u0434\u0435\u0442\u044c \u043d\u0430\u0448 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0441\u043d\u044f\u0442\u044b \u0441 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0435\u0433\u043e \u0430\u0434\u0440\u0435\u0441\u0430 (\u043d\u0430\u0441).<\/p>\n<p>\u041d\u0435\u043c\u043d\u043e\u0433\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0432\u0430\u0442\u043e,\u043d\u043e \u043f\u0440\u0438 \u0432\u0434\u0443\u043c\u0447\u0438\u0432\u043e\u043c \u043f\u0440\u043e\u0447\u0442\u0435\u043d\u0438\u0438 \u0432\u0441\u0435 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043d\u0430 \u0441\u0432\u043e\u0438 \u043c\u0435\u0441\u0442\u0430.<\/p>\n<p>\u0412 \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435, \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u043c amount of DAI \u0441 \u0430\u0434\u0440\u0435\u0441\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0435\u0433\u043e \u043d\u0430 \u0430\u0434\u0440\u0435\u0441 \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430.\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 amount \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043e \u0432\u043e \u0432\u0442\u043e\u0440\u043e\u0439 approve.<\/p>\n<p>\u0412 \u043a\u043e\u0434\u0435 \u0432\u0441\u0435 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u043e\u0435 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043f\u0440\u043e\u0449\u0435:<\/p>\n<pre><code class=\"cpp\">\/\/\/ @notice swapExactInputSingle swaps a fixed amount of DAI for a maximum possible amount of WETH \/\/\/ using the DAI\/WETH9 0.3% pool by calling `exactInputSingle` in the swap router. \/\/\/ @dev The calling address must approve this contract to spend at least `amountIn` worth of its DAI for this function to succeed. \/\/\/ @param amountIn The exact amount of DAI that will be swapped for WETH9. \/\/\/ @return amountOut The amount of WETH9 received.     function swapExactInputSingle(uint256 amountIn) external returns (uint256 amountOut) {         \/\/ msg.sender must approve this contract          \/\/ Transfer the specified amount of DAI to this contract.         TransferHelper.safeTransferFrom(DAI, msg.sender, address(this), amountIn);          \/\/ Approve the router to spend DAI.         TransferHelper.safeApprove(DAI, address(swapRouter), amountIn); <\/code><\/pre>\n<h3><\/h3>\n<h3> Swap Input Parameters<\/h3>\n<p>\u0427\u0442\u043e \u0431\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0441\u0432\u043e\u043f\u0430 \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043d\u0430\u0431\u0434\u0438\u0442\u044c  \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 <code>ExactInputSingleParams<\/code>\u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0439 \u0434\u043b\u044f \u0441\u0432\u043e\u043f\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439.<\/p>\n<ul>\n<li>\n<p><code>tokenIn<\/code> \u0430\u0434\u0440\u0435\u0441 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430<\/p>\n<\/li>\n<li>\n<p><code>tokenOut<\/code>\u0430\u0434\u0440\u0435\u0441 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430<\/p>\n<\/li>\n<li>\n<p><code>fee<\/code>\u0423\u0440\u043e\u0432\u0435\u043d\u044c \u043a\u043e\u043c\u0438\u0441\u0441\u0438\u0438 \u043f\u0443\u043b\u0430, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u043f\u0443\u043b\u0430, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0441\u0432\u043e\u043f. <\/p>\n<\/li>\n<li>\n<p><code>recipient <\/code>\u0430\u0434\u0440\u0435\u0441 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430(\u0438\u043b\u0438 \u0430\u0434\u0440\u0435\u0441\u0441 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u044f)<\/p>\n<\/li>\n<li>\n<p><code>deadline <\/code>\u0432\u0440\u0435\u043c\u044f unix, \u043f\u043e \u0438\u0441\u0442\u0435\u0447\u0435\u043d\u0438\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0441\u0432\u043e\u043f \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d,\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0437\u0430\u0449\u0438\u0442\u044b \u043e\u0442 \u0434\u043e\u043b\u0433\u043e \u043e\u0436\u0438\u0434\u0430\u044e\u0449\u0438\u0445 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0439 \u0438 \u0440\u0435\u0437\u043a\u0438\u0445 \u043a\u043e\u043b\u0435\u0431\u0430\u043d\u0438\u0439 \u0446\u0435\u043d<\/p>\n<\/li>\n<li>\n<p><code>amountOutMinimum<\/code>\u043c\u044b \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043d\u0430 \u043d\u043e\u043b\u044c,\u043d\u043e \u0432 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0435 \u044d\u0442\u043e \u0434\u0430\u0435\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0439 \u0440\u0438\u0441\u043a. \u0414\u043b\u044f \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u043d\u043e \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043d\u0430\u0448\u0435\u0433\u043e SDK \u0438\u043b\u0438 \u043e\u0440\u0430\u043a\u0443\u043b\u0430 \u0446\u0435\u043d \u0432 \u0441\u0435\u0442\u0438 \u2014 \u044d\u0442\u043e \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0437\u0430\u0449\u0438\u0442\u0438\u0442\u044c\u0441\u044f \u043e\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u0435\u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u043d\u043e \u043f\u043b\u043e\u0445\u0438\u0445 \u0446\u0435\u043d \u0434\u043b\u044f \u0441\u0434\u0435\u043b\u043a\u0438 ,\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u044f\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u044b \u0444\u0440\u043e\u043d\u0442\u0430 \u0438\u043b\u0438 \u043b\u044e\u0431\u043e\u0433\u043e \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0446\u0435\u043d\u043e\u0439.<\/p>\n<\/li>\n<li>\n<p><code>sqrtPriceLimitX96<\/code>\u041c\u044b \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0432 0 \u2014 \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u044d\u0442\u043e\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u043d\u0442 \u043d\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u043c.\u0412 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0435, \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043f\u0440\u0435\u0434\u0435\u043b\u0430 \u0446\u0435\u043d\u044b, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0441\u0432\u043e\u043f \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442\u044c \u0432 \u043f\u0443\u043b\u0435. <\/p>\n<\/li>\n<\/ul>\n<h4> Call the function<\/h4>\n<pre><code class=\"cpp\">\/\/ Naively set amountOutMinimum to 0. In production, use an oracle or other data source to choose a safer value for amountOutMinimum. \/\/ We also set the sqrtPriceLimitx96 to be 0 to ensure we swap our exact input amount.         ISwapRouter.ExactInputSingleParams memory params =             ISwapRouter.ExactInputSingleParams({                 tokenIn: DAI,                 tokenOut: WETH9,                 fee: poolFee,                 recipient: msg.sender,                 deadline: block.timestamp,                 amountIn: amountIn,                 amountOutMinimum: 0,                 sqrtPriceLimitX96: 0             });          \/\/ The call to `exactInputSingle` executes the swap.         amountOut = swapRouter.exactInputSingle(params);     }<\/code><\/pre>\n<h3> Exact Output Swaps<\/h3>\n<p>Exact Output \u043e\u0431\u043c\u0435\u043d\u0438\u0432\u0430\u0435\u0442 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430 \u043d\u0430 \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430. \u042d\u0442\u043e \u043c\u0435\u043d\u0435\u0435 \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u0439 \u0441\u0442\u0438\u043b\u044c \u043e\u0431\u043c\u0435\u043d\u0430, \u043d\u043e \u043e\u043d \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u0435\u043d .<\/p>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0432 \u044d\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430 \u0432 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043e\u0431\u043c\u0435\u043d\u0430, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0447\u0442\u043e \u0447\u0430\u0441\u0442\u044c \u044d\u0442\u043e\u0433\u043e \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430 \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u0432\u043e\u043f\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0435\u0433\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0435\u043c\u0443 \u0430\u0434\u0440\u0435\u0441\u0443 \u0432 \u043a\u043e\u043d\u0446\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438.<\/p>\n<pre><code class=\"cpp\">\/\/\/ @notice swapExactOutputSingle swaps a minimum possible amount of DAI for a fixed amount of WETH. \/\/\/ @dev The calling address must approve this contract to spend its DAI for this function to succeed. As the amount of input DAI is variable, \/\/\/ the calling address will need to approve for a slightly higher amount, anticipating some variance. \/\/\/ @param amountOut The exact amount of WETH9 to receive from the swap. \/\/\/ @param amountInMaximum The amount of DAI we are willing to spend to receive the specified amount of WETH9. \/\/\/ @return amountIn The amount of DAI actually spent in the swap. function swapExactOutputSingle(uint256 amountOut, uint256 amountInMaximum) external returns (uint256 amountIn) { \/\/ Transfer the specified amount of DAI to this contract. TransferHelper.safeTransferFrom(DAI, msg.sender, address(this), amountInMaximum);          \/\/ Approve the router to spend the specified `amountInMaximum` of DAI.         \/\/ In production, you should choose the maximum amount to spend based on oracles or other data sources to achieve a better swap.         TransferHelper.safeApprove(DAI, address(swapRouter), amountInMaximum);          ISwapRouter.ExactOutputSingleParams memory params =             ISwapRouter.ExactOutputSingleParams({                 tokenIn: DAI,                 tokenOut: WETH9,                 fee: poolFee,                 recipient: msg.sender,                 deadline: block.timestamp,                 amountOut: amountOut,                 amountInMaximum: amountInMaximum,                 sqrtPriceLimitX96: 0             });          \/\/ Executes the swap returning the amountIn needed to spend to receive the desired amountOut.         amountIn = swapRouter.exactOutputSingle(params);          \/\/ For exact output swaps, the amountInMaximum may not have all been spent.         \/\/ If the actual amount spent (amountIn) is less than the specified maximum amount, we must refund the msg.sender and approve the swapRouter to spend 0.         if (amountIn &lt; amountInMaximum) {             TransferHelper.safeApprove(DAI, address(swapRouter), 0);             TransferHelper.safeTransfer(DAI, msg.sender, amountInMaximum - amountIn);         }     }<\/code><\/pre>\n<h2>\u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u043f\u0440\u0438\u043c\u0435\u0440\u0430<\/h2>\n<pre><code class=\"cpp\">\/\/ SPDX-License-Identifier: GPL-2.0-or-later pragma solidity =0.7.6; pragma abicoder v2;  import '@uniswap\/v3-periphery\/contracts\/libraries\/TransferHelper.sol'; import '@uniswap\/v3-periphery\/contracts\/interfaces\/ISwapRouter.sol';  contract SwapExamples {     \/\/ For the scope of these swap examples,     \/\/ we will detail the design considerations when using     \/\/ `exactInput`, `exactInputSingle`, `exactOutput`, and  `exactOutputSingle`.      \/\/ It should be noted that for the sake of these examples, we purposefully pass in the swap router instead of inherit the swap router for simplicity.     \/\/ More advanced example contracts will detail how to inherit the swap router safely.      ISwapRouter public immutable swapRouter;      \/\/ This example swaps DAI\/WETH9 for single path swaps and DAI\/USDC\/WETH9 for multi path swaps.      address public constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F;     address public constant WETH9 = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;     address public constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;      \/\/ For this example, we will set the pool fee to 0.3%.     uint24 public constant poolFee = 3000;      constructor(ISwapRouter _swapRouter) {         swapRouter = _swapRouter;     }      \/\/\/ @notice swapExactInputSingle swaps a fixed amount of DAI for a maximum possible amount of WETH9     \/\/\/ using the DAI\/WETH9 0.3% pool by calling `exactInputSingle` in the swap router.     \/\/\/ @dev The calling address must approve this contract to spend at least `amountIn` worth of its DAI for this function to succeed.     \/\/\/ @param amountIn The exact amount of DAI that will be swapped for WETH9.     \/\/\/ @return amountOut The amount of WETH9 received.     function swapExactInputSingle(uint256 amountIn) external returns (uint256 amountOut) {         \/\/ msg.sender must approve this contract          \/\/ Transfer the specified amount of DAI to this contract.         TransferHelper.safeTransferFrom(DAI, msg.sender, address(this), amountIn);          \/\/ Approve the router to spend DAI.         TransferHelper.safeApprove(DAI, address(swapRouter), amountIn);          \/\/ Naively set amountOutMinimum to 0. In production, use an oracle or other data source to choose a safer value for amountOutMinimum.         \/\/ We also set the sqrtPriceLimitx96 to be 0 to ensure we swap our exact input amount.         ISwapRouter.ExactInputSingleParams memory params =             ISwapRouter.ExactInputSingleParams({                 tokenIn: DAI,                 tokenOut: WETH9,                 fee: poolFee,                 recipient: msg.sender,                 deadline: block.timestamp,                 amountIn: amountIn,                 amountOutMinimum: 0,                 sqrtPriceLimitX96: 0             });          \/\/ The call to `exactInputSingle` executes the swap.         amountOut = swapRouter.exactInputSingle(params);     }      \/\/\/ @notice swapExactOutputSingle swaps a minimum possible amount of DAI for a fixed amount of WETH.     \/\/\/ @dev The calling address must approve this contract to spend its DAI for this function to succeed. As the amount of input DAI is variable,     \/\/\/ the calling address will need to approve for a slightly higher amount, anticipating some variance.     \/\/\/ @param amountOut The exact amount of WETH9 to receive from the swap.     \/\/\/ @param amountInMaximum The amount of DAI we are willing to spend to receive the specified amount of WETH9.     \/\/\/ @return amountIn The amount of DAI actually spent in the swap.     function swapExactOutputSingle(uint256 amountOut, uint256 amountInMaximum) external returns (uint256 amountIn) {         \/\/ Transfer the specified amount of DAI to this contract.         TransferHelper.safeTransferFrom(DAI, msg.sender, address(this), amountInMaximum);          \/\/ Approve the router to spend the specifed `amountInMaximum` of DAI.         \/\/ In production, you should choose the maximum amount to spend based on oracles or other data sources to acheive a better swap.         TransferHelper.safeApprove(DAI, address(swapRouter), amountInMaximum);          ISwapRouter.ExactOutputSingleParams memory params =             ISwapRouter.ExactOutputSingleParams({                 tokenIn: DAI,                 tokenOut: WETH9,                 fee: poolFee,                 recipient: msg.sender,                 deadline: block.timestamp,                 amountOut: amountOut,                 amountInMaximum: amountInMaximum,                 sqrtPriceLimitX96: 0             });          \/\/ Executes the swap returning the amountIn needed to spend to receive the desired amountOut.         amountIn = swapRouter.exactOutputSingle(params);          \/\/ For exact output swaps, the amountInMaximum may not have all been spent.         \/\/ If the actual amount spent (amountIn) is less than the specified maximum amount, we must refund the msg.sender and approve the swapRouter to spend 0.         if (amountIn &lt; amountInMaximum) {             TransferHelper.safeApprove(DAI, address(swapRouter), 0);             TransferHelper.safeTransfer(DAI, msg.sender, amountInMaximum - amountIn);         }     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"v-portal\" style=\"display:none;\"><\/div>\n<\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/684872\/\"> https:\/\/habr.com\/ru\/post\/684872\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0445\u043e\u0440\u043e\u0448\u0438\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u044b\u0435 \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u044b,\u044f \u043b\u0438\u0448\u044c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0445\u043e\u0447\u0443 \u0440\u0430\u0441\u043a\u0440\u044b\u0442\u044c \u0438\u0445 \u0434\u043b\u044f \u0440\u0443\u043d\u0435\u0442\u0430<\/p>\n<h3>Single Swaps<\/h3>\n<p>\u041f\u0440\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043e\u0431\u043c\u0435\u043d\u0430(\u0441\u0432\u043e\u043f\u044b) \u2014  \u0441\u0430\u043c\u043e\u0435 \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u043e\u043d\u0435\u043d\u043d\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 Uniswap. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c  single-path swap \u0432 \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430\u0445. \u041a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438,\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u043f\u043e\u044d\u0442\u0430\u043f\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c.<\/p>\n<ul>\n<li>\n<p><code>swapExactInputSingle(...)<\/code><\/p>\n<\/li>\n<li>\n<p><code>swapExactOutputSingle(...)<\/code><\/p>\n<\/li>\n<\/ul>\n<p><strong>swapExactInputSingle<\/strong> \u2014  \u043e\u0431\u043c\u0435\u043d\u0438\u0432\u0430\u0435\u0442 \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0434\u043d\u043e\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430 \u043d\u0430 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430.( fix one \u2192 max another  )<\/p>\n<p>\u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u0435\u0442 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 <code>ExactInputSingleParams <\/code>\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>exactInputSingle(...)<\/code>\u0438\u0437 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430<code> ISwapRouter<\/code><\/p>\n<p><strong>swapExactOutputSingle<\/strong> \u2014 \u043e\u0431\u043c\u0435\u043d\u0438\u0432\u0430\u0435\u0442 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0434\u043d\u043e\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430 \u043d\u0430 \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430. ( Min one \u2192 fix another )<\/p>\n<p>\u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u0435\u0442 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443  <code>ExactOutputSingleParams<\/code> \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>exactOutputSingle(...)<\/code> \u0438\u0437 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 <code>ISwapRouter<\/code>.<\/p>\n<p>\u0414\u043b\u044f \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430,\u0430\u0434\u0440\u0435\u0441\u0430 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u0432 \u0442\u043e\u043a\u0435\u043d\u043e\u0432 (\u0442\u0443\u0442 DAI \u0438 <code>WETH9<\/code>) \u0437\u0430\u0445\u0430\u0440\u0434\u043a\u043e\u0434\u0438\u043b\u0438. \u041e\u0447\u0435\u0432\u0438\u0434\u043d\u043e,\u0447\u0442\u043e \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u043c\u043e\u0436\u043d\u043e \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u043f\u0443\u043b\u044b \u0438 \u0442\u043e\u043a\u0435\u043d\u044b \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438. <\/p>\n<h3>Set Up the Contract<\/h3>\n<p>abicoder v2, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u0434\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0435 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u044b \u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0432 calldata, \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0430\u044f \u043f\u0440\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 \u0441\u0432\u043e\u043f\u0430.<\/p>\n<pre><code class=\"cpp\">\/\/ SPDX-License-Identifier: GPL-2.0-or-later pragma solidity =0.7.6; pragma abicoder v2;<\/code><\/pre>\n<p>\u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043f\u0430\u043a\u0435\u0442\u0438\u043a\u0438 (\u0447\u0435\u0440\u0435\u0437 npm \u0438\u043b\u0438 yarn)<\/p>\n<pre><code class=\"cpp\">import '@uniswap\/v3-periphery\/contracts\/interfaces\/ISwapRouter.sol'; import '@uniswap\/v3-periphery\/contracts\/libraries\/TransferHelper.sol';<\/code><\/pre>\n<p>C\u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 SwapExamples, \u0438 \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u043c immutable public \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e swapRouter \u0442\u0438\u043f\u0430 ISwapRouter. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0430\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 ISwapRouter.<\/p>\n<pre><code class=\"cpp\">contract SwapExamples {     \/\/ For the scope of these swap examples,     \/\/ we will detail the design considerations when using `exactInput`, `exactInputSingle`, `exactOutput`, and  `exactOutputSingle`.     \/\/ It should be noted that for the sake of these examples we pass in the swap router as a constructor argument instead of inheriting it.     \/\/ More advanced example contracts will detail how to inherit the swap router safely.     \/\/ This example swaps DAI\/WETH9 for single path swaps and DAI\/USDC\/WETH9 for multi path swaps.      ISwapRouter public immutable swapRouter;<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0445\u0430\u0440\u0434\u043a\u043e\u0434\u0438\u043c \u0430\u0434\u0440\u0435\u0441\u0430 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u0432 \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u0438 \u0443\u0440\u043e\u0432\u043d\u0438 \u043a\u043e\u043c\u0438\u0441\u0441\u0438\u0439 \u043f\u0443\u043b\u0430. <\/p>\n<pre><code class=\"cpp\">    address public constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F;     address public constant WETH9 = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;     address public constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;      \/\/ For this example, we will set the pool fee to 0.3%.     uint24 public constant poolFee = 3000;      constructor(ISwapRouter _swapRouter) {         swapRouter = _swapRouter;     }<\/code><\/pre>\n<h3> Exact Input Swaps<\/h3>\n<p>\u0412\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u0439(\u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c) \u0434\u043e\u043b\u0436\u0435\u043d \u0443\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044c \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u043d\u0430 \u0441\u043d\u044f\u0442\u0438\u0435 \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u0441\u043e \u0441\u0447\u0435\u0442\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0435\u0433\u043e \u0430\u0434\u0440\u0435\u0441\u0430 \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u0432\u043e\u043f\u0430. &#171;\u0423\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044c&#187; \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043d\u0430 \u043d\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>approv\u0435<\/code>.\u041f\u043e\u043c\u043d\u0438\u0442\u0435, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043d\u0430\u0448 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u044d\u0442\u043e \u0441\u0430\u043c \u043f\u043e \u0441\u0435\u0431\u0435 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442, \u0430 \u043d\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0435\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b(\u043d\u0430\u0441) \u0442\u043e, \u043c\u044b \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0434\u043e\u0431\u0440\u0438\u0442\u044c(\u0443\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044c) \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 <code>Uniswap protocol router<\/code>\u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u043e\u043a\u0435\u043d\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0431\u0443\u0434\u0435\u0442 \u0432\u043b\u0430\u0434\u0435\u0442\u044c \u043d\u0430\u0448 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0441\u043d\u044f\u0442\u044b \u0441 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0435\u0433\u043e \u0430\u0434\u0440\u0435\u0441\u0430 (\u043d\u0430\u0441).<\/p>\n<p>\u041d\u0435\u043c\u043d\u043e\u0433\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0432\u0430\u0442\u043e,\u043d\u043e \u043f\u0440\u0438 \u0432\u0434\u0443\u043c\u0447\u0438\u0432\u043e\u043c \u043f\u0440\u043e\u0447\u0442\u0435\u043d\u0438\u0438 \u0432\u0441\u0435 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043d\u0430 \u0441\u0432\u043e\u0438 \u043c\u0435\u0441\u0442\u0430.<\/p>\n<p>\u0412 \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435, \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u043c amount of DAI \u0441 \u0430\u0434\u0440\u0435\u0441\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0435\u0433\u043e \u043d\u0430 \u0430\u0434\u0440\u0435\u0441 \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430.\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 amount \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043e \u0432\u043e \u0432\u0442\u043e\u0440\u043e\u0439 approve.<\/p>\n<p>\u0412 \u043a\u043e\u0434\u0435 \u0432\u0441\u0435 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u043e\u0435 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043f\u0440\u043e\u0449\u0435:<\/p>\n<pre><code class=\"cpp\">\/\/\/ @notice swapExactInputSingle swaps a fixed amount of DAI for a maximum possible amount of WETH \/\/\/ using the DAI\/WETH9 0.3% pool by calling `exactInputSingle` in the swap router. \/\/\/ @dev The calling address must approve this contract to spend at least `amountIn` worth of its DAI for this function to succeed. \/\/\/ @param amountIn The exact amount of DAI that will be swapped for WETH9. \/\/\/ @return amountOut The amount of WETH9 received.     function swapExactInputSingle(uint256 amountIn) external returns (uint256 amountOut) {         \/\/ msg.sender must approve this contract          \/\/ Transfer the specified amount of DAI to this contract.         TransferHelper.safeTransferFrom(DAI, msg.sender, address(this), amountIn);          \/\/ Approve the router to spend DAI.         TransferHelper.safeApprove(DAI, address(swapRouter), amountIn); <\/code><\/pre>\n<h3><\/h3>\n<h3> Swap Input Parameters<\/h3>\n<p>\u0427\u0442\u043e \u0431\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0441\u0432\u043e\u043f\u0430 \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043d\u0430\u0431\u0434\u0438\u0442\u044c  \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 <code>ExactInputSingleParams<\/code>\u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0439 \u0434\u043b\u044f \u0441\u0432\u043e\u043f\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439.<\/p>\n<ul>\n<li>\n<p><code>tokenIn<\/code> \u0430\u0434\u0440\u0435\u0441 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430<\/p>\n<\/li>\n<li>\n<p><code>tokenOut<\/code>\u0430\u0434\u0440\u0435\u0441 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430<\/p>\n<\/li>\n<li>\n<p><code>fee<\/code>\u0423\u0440\u043e\u0432\u0435\u043d\u044c \u043a\u043e\u043c\u0438\u0441\u0441\u0438\u0438 \u043f\u0443\u043b\u0430, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u043f\u0443\u043b\u0430, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0441\u0432\u043e\u043f. <\/p>\n<\/li>\n<li>\n<p><code>recipient <\/code>\u0430\u0434\u0440\u0435\u0441 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430(\u0438\u043b\u0438 \u0430\u0434\u0440\u0435\u0441\u0441 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u044f)<\/p>\n<\/li>\n<li>\n<p><code>deadline <\/code>\u0432\u0440\u0435\u043c\u044f unix, \u043f\u043e \u0438\u0441\u0442\u0435\u0447\u0435\u043d\u0438\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0441\u0432\u043e\u043f \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d,\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0437\u0430\u0449\u0438\u0442\u044b \u043e\u0442 \u0434\u043e\u043b\u0433\u043e \u043e\u0436\u0438\u0434\u0430\u044e\u0449\u0438\u0445 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0439 \u0438 \u0440\u0435\u0437\u043a\u0438\u0445 \u043a\u043e\u043b\u0435\u0431\u0430\u043d\u0438\u0439 \u0446\u0435\u043d<\/p>\n<\/li>\n<li>\n<p><code>amountOutMinimum<\/code>\u043c\u044b \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043d\u0430 \u043d\u043e\u043b\u044c,\u043d\u043e \u0432 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0435 \u044d\u0442\u043e \u0434\u0430\u0435\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0439 \u0440\u0438\u0441\u043a. \u0414\u043b\u044f \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u043d\u043e \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043d\u0430\u0448\u0435\u0433\u043e SDK \u0438\u043b\u0438 \u043e\u0440\u0430\u043a\u0443\u043b\u0430 \u0446\u0435\u043d \u0432 \u0441\u0435\u0442\u0438 \u2014 \u044d\u0442\u043e \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0437\u0430\u0449\u0438\u0442\u0438\u0442\u044c\u0441\u044f \u043e\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u0435\u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u043d\u043e \u043f\u043b\u043e\u0445\u0438\u0445 \u0446\u0435\u043d \u0434\u043b\u044f \u0441\u0434\u0435\u043b\u043a\u0438 ,\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u044f\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u044b \u0444\u0440\u043e\u043d\u0442\u0430 \u0438\u043b\u0438 \u043b\u044e\u0431\u043e\u0433\u043e \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0446\u0435\u043d\u043e\u0439.<\/p>\n<\/li>\n<li>\n<p><code>sqrtPriceLimitX96<\/code>\u041c\u044b \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0432 0 \u2014 \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u044d\u0442\u043e\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u043d\u0442 \u043d\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u043c.\u0412 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0435, \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043f\u0440\u0435\u0434\u0435\u043b\u0430 \u0446\u0435\u043d\u044b, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0441\u0432\u043e\u043f \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442\u044c \u0432 \u043f\u0443\u043b\u0435. <\/p>\n<\/li>\n<\/ul>\n<h4> Call the function<\/h4>\n<pre><code class=\"cpp\">\/\/ Naively set amountOutMinimum to 0. In production, use an oracle or other data source to choose a safer value for amountOutMinimum. \/\/ We also set the sqrtPriceLimitx96 to be 0 to ensure we swap our exact input amount.         ISwapRouter.ExactInputSingleParams memory params =             ISwapRouter.ExactInputSingleParams({                 tokenIn: DAI,                 tokenOut: WETH9,                 fee: poolFee,                 recipient: msg.sender,                 deadline: block.timestamp,                 amountIn: amountIn,                 amountOutMinimum: 0,                 sqrtPriceLimitX96: 0             });          \/\/ The call to `exactInputSingle` executes the swap.         amountOut = swapRouter.exactInputSingle(params);     }<\/code><\/pre>\n<h3> Exact Output Swaps<\/h3>\n<p>Exact Output \u043e\u0431\u043c\u0435\u043d\u0438\u0432\u0430\u0435\u0442 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430 \u043d\u0430 \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430. \u042d\u0442\u043e \u043c\u0435\u043d\u0435\u0435 \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u0439 \u0441\u0442\u0438\u043b\u044c \u043e\u0431\u043c\u0435\u043d\u0430, \u043d\u043e \u043e\u043d \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u0435\u043d .<\/p>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0432 \u044d\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430 \u0432 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043e\u0431\u043c\u0435\u043d\u0430, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0447\u0442\u043e \u0447\u0430\u0441\u0442\u044c \u044d\u0442\u043e\u0433\u043e \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430 \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u0432\u043e\u043f\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0435\u0433\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0435\u043c\u0443 \u0430\u0434\u0440\u0435\u0441\u0443 \u0432 \u043a\u043e\u043d\u0446\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438.<\/p>\n<pre><code class=\"cpp\">\/\/\/ @notice swapExactOutputSingle swaps a minimum possible amount of DAI for a fixed amount of WETH. \/\/\/ @dev The calling address must approve this contract to spend its DAI for this function to succeed. As the amount of input DAI is variable, \/\/\/ the calling address will need to approve for a slightly higher amount, anticipating some variance. \/\/\/ @param amountOut The exact amount of WETH9 to receive from the swap. \/\/\/ @param amountInMaximum The amount of DAI we are willing to spend to receive the specified amount of WETH9. \/\/\/ @return amountIn The amount of DAI actually spent in the swap. function swapExactOutputSingle(uint256 amountOut, uint256 amountInMaximum) external returns (uint256 amountIn) { \/\/ Transfer the specified amount of DAI to this contract. TransferHelper.safeTransferFrom(DAI, msg.sender, address(this), amountInMaximum);          \/\/ Approve the router to spend the specified `amountInMaximum` of DAI.         \/\/ In production, you should choose the maximum amount to spend based on oracles or other data sources to achieve a better swap.         TransferHelper.safeApprove(DAI, address(swapRouter), amountInMaximum);          ISwapRouter.ExactOutputSingleParams memory params =             ISwapRouter.ExactOutputSingleParams({                 tokenIn: DAI,                 tokenOut: WETH9,                 fee: poolFee,                 recipient: msg.sender,                 deadline: block.timestamp,                 amountOut: amountOut,                 amountInMaximum: amountInMaximum,                 sqrtPriceLimitX96: 0             });          \/\/ Executes the swap returning the amountIn needed to spend to receive the desired amountOut.         amountIn = swapRouter.exactOutputSingle(params);          \/\/ For exact output swaps, the amountInMaximum may not have all been spent.         \/\/ If the actual amount spent (amountIn) is less than the specified maximum amount, we must refund the msg.sender and approve the swapRouter to spend 0.         if (amountIn &lt; amountInMaximum) {             TransferHelper.safeApprove(DAI, address(swapRouter), 0);             TransferHelper.safeTransfer(DAI, msg.sender, amountInMaximum - amountIn);         }     }<\/code><\/pre>\n<h2>\u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u043f\u0440\u0438\u043c\u0435\u0440\u0430<\/h2>\n<pre><code class=\"cpp\">\/\/ SPDX-License-Identifier: GPL-2.0-or-later pragma solidity =0.7.6; pragma abicoder v2;  import '@uniswap\/v3-periphery\/contracts\/libraries\/TransferHelper.sol'; import '@uniswap\/v3-periphery\/contracts\/interfaces\/ISwapRouter.sol';  contract SwapExamples {     \/\/ For the scope of these swap examples,     \/\/ we will detail the design considerations when using     \/\/ `exactInput`, `exactInputSingle`, `exactOutput`, and  `exactOutputSingle`.      \/\/ It should be noted that for the sake of these examples, we purposefully pass in the swap router instead of inherit the swap router for simplicity.     \/\/ More advanced example contracts will detail how to inherit the swap router safely.      ISwapRouter public immutable swapRouter;      \/\/ This example swaps DAI\/WETH9 for single path swaps and DAI\/USDC\/WETH9 for multi path swaps.      address public constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F;     address public constant WETH9 = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;     address public constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;      \/\/ For this<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-337592","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/337592","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=337592"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/337592\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=337592"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=337592"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=337592"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}