From 5556a9113b38a6558e018020a468a99f4c2fd095 Mon Sep 17 00:00:00 2001 From: "Alex.Karys" Date: Thu, 15 Sep 2022 15:39:06 -0400 Subject: [PATCH 1/5] Adding new local set up doc --- src/pages/index.js | 10 +- .../guides/flash-integrations/_category_.json | 2 +- .../guides/liquidity-mining/_category_.json | 2 +- .../version-V3/guides/local-environment.mdx | 208 +++++++++--------- 4 files changed, 114 insertions(+), 108 deletions(-) diff --git a/src/pages/index.js b/src/pages/index.js index 22cb166f0b..eae648ee85 100644 --- a/src/pages/index.js +++ b/src/pages/index.js @@ -74,6 +74,11 @@ export const github = [ ] export const Guides = [ + { + title: 'Integration Quick Start', + text: 'Build your first on chain integration with the Uniswap Protocol.', + to: './protocol/guides/quickstart', + }, { title: 'SDK Quick Start', text: 'Integrate with the Uniswap Protocol using JavaScript', @@ -84,11 +89,6 @@ export const Guides = [ text: 'Let your users trade tokens without leaving your dApp', to: './sdk/widgets/swap-widget', }, - { - title: 'Implementing a Swap', - text: 'Start swapping from a smart contract in Solidity', - to: './protocol/guides/swaps/single-swaps', - }, { title: 'Providing Liquidity', text: 'Provide liquidity from a smart contract in Solidity', diff --git a/versioned_docs/version-V3/guides/flash-integrations/_category_.json b/versioned_docs/version-V3/guides/flash-integrations/_category_.json index 2232324309..da104a9d13 100644 --- a/versioned_docs/version-V3/guides/flash-integrations/_category_.json +++ b/versioned_docs/version-V3/guides/flash-integrations/_category_.json @@ -1,4 +1,4 @@ { "label": "Implement Flash Swaps", - "position": 3 + "position": 4 } diff --git a/versioned_docs/version-V3/guides/liquidity-mining/_category_.json b/versioned_docs/version-V3/guides/liquidity-mining/_category_.json index e61434ae7f..b0119da777 100644 --- a/versioned_docs/version-V3/guides/liquidity-mining/_category_.json +++ b/versioned_docs/version-V3/guides/liquidity-mining/_category_.json @@ -1,5 +1,5 @@ { "label": "Liquidity Mining", - "position": 1, + "position": 3, "collapsed": true } diff --git a/versioned_docs/version-V3/guides/local-environment.mdx b/versioned_docs/version-V3/guides/local-environment.mdx index e891232eaf..a85ad0163f 100644 --- a/versioned_docs/version-V3/guides/local-environment.mdx +++ b/versioned_docs/version-V3/guides/local-environment.mdx @@ -4,142 +4,148 @@ title: Set Up Your Local Environment sidebar_position: 0.5 --- -This guide describes how to set up your environment using a specific toolset: `Node.js` + `npm` + `hardhat`. It also shows you how to install the Uniswap V3 Periphery contracts, which are required for the contract examples in the Uniswap Docs V3 guides. +One of the most common questions we get asked is what development toolset to use to build on-chain integrations with Uniswap. There’s no right answer to this question but for this guide we’ll recommend a common one: `Node.js` , `NPM` and `Hardhat`. -Once you have set up your environment, read the guides on liquidity mining, implementing swaps, and so on, which provide example contracts for those interactions. +At the end of this guide you’ll have a development environment set up that you can use to build the rest of the examples in the Guides section of the docs, or start your own integration project! -## Create a Node.js Project +To get you started as quickly as possible, we have provided the `Quick Start` section below where you can clone some boiler plate and get building. To start from scratch and learn the underlying concepts, jump to the `Start from Scratch` section. -1. Download and install [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm). +# Quick Start -2. Create a new directory and navigate to it. Also, create a new node project with `npm init`. - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; - - - +The Uniswap [boilerplate repo](https://github.com/Uniswap/uniswap-first-contract-example) provides a basic Hardhat environment with required imports already pre-loaded for you. You can simply clone it and install the dependencies: ```bash - $ mkdir swap-example - $ cd swap-example - $ npm init - ``` - - - - - -```bash - $ mkdir swap-example - $ cd swap-example - $ yarn init - ``` - - - - -## Install Hardhat and the Periphery Contracts - -1. Install [Hardhat](https://hardhat.org/), a development environment to compile, deploy, test, and debug your Smart Contracts. - - - +git clone https://github.com/Uniswap/uniswap-first-contract-example +cd uniswap-first-contract-example +npm install +``` - ```bash - $ npm add --save-dev hardhat - ``` +Then hop to the `Local Node with a Mainnet Fork` to complete your set up and start developing. - +# Start from Scratch - +In the following sections, we’ll walk through the steps to create the environment set up as the boiler plate from scratch and learn the underlying concepts. - ```bash - $ yarn add --dev hardhat - ``` +## Set Up Dependencies - - +Node is one of the most common Javascript runtimes. For our purposes it will provide scripting we can use to compile and test our contracts. If you haven’t already, install NodeJS and its package manager NPM ([instructions](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)). Once those dependencies are set up, we can initialize our project: -2. Install the V3 Periphery contracts so that you can inherit what you need from them in your Smart Contracts. +```bash +$ npm init +``` - - +[Hardhat](https://hardhat.org/) is an Ethereum development toolset that provides a number of powerful features including Solidity compilation, testing and deployment, all in a single convenient wrapper. We’ll use NPM to add Hardhat to our project: - ```bash - $ npm add @uniswap/v3-periphery - ``` +```bash +$ npm add --save-dev hardhat +``` - +With Hardhat installed we can invoke it to scaffold our development environment. When you first run Hardhat you’ll have the option of starting with a templated Javascript or Typescript project or an empty project. Since Hardhat relies heavily on folder structure, we recommend starting with either of the templated options. Initialize Hardhat and follow the prompts to make your selection and answer yes to the follow up prompts: - +```bash +$ npx hardhat init +``` - ```bash - $ yarn add @uniswap/v3-periphery - ``` +Once the Hardhat initialization completes, take a look around at what got set up. The folder structure should be intuitive, `./contracts` is where you’ll write your Solidity contracts, `./test` is where you’ll write your tests and `./scripts` is where you can write scripts to perform actions like deploying. Out of the box, Hardhat is configured to use this folder structure so don’t change it unless you know what you’re doing! - - +Next we’ll use NPM to add the Uniswap V3 contracts which will allow us to seamlessly integrate with the protocol in our new contracts: -3. Create a new hardhat config file, which you can use for compiling and testing contracts. For an example of how a typical smart contract repo is structure, select the "create a sample project" option during setup. +```bash +$ npm add @uniswap/v3-periphery @uniswap/v3-core +``` - - +The Uniswap V3 contracts were written using a past version of the solidity compiler. Since we’re building integrations on V3 we have to tell Hardhat to use the correct compiler to build these files. Go to the `./hardhat.config.js` file and change the Solidity version to “0.7.6”: - ```bash - $ npx hardhat - ``` +```jsx +// ... +module.exports = { + solidity: "0.7.6", +}; +``` - +That’s it! You should now have a functional development environment to start building on chain Uniswap integrations. Let’s run a quick test to confirm everything is set up properly. + +## Compile a Basic Contract + +To confirm that our environment is configured correctly we’ll attempt to compile a basic Swap contract. Create a new file, `./contracts/Swap.sol` and paste the following code into it (a detailed guide to this contract can be found [here](https://docs.uniswap.org/protocol/guides/swaps/single-swaps)): + +```jsx +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity =0.7.6; +pragma abicoder v2; + +import '@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol'; +import '@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol'; + +contract SimpleSwap { + ISwapRouter public immutable swapRouter; + address public constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F; + address public constant WETH9 = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; + uint24 public constant feeTier = 3000; + + constructor(ISwapRouter _swapRouter) { + swapRouter = _swapRouter; + } + + function swapWETHForDAI(uint amountIn) external returns (uint256 amountOut) { + + // Transfer the specified amount of WETH9 to this contract. + TransferHelper.safeTransferFrom(WETH9, msg.sender, address(this), amountIn); + // Approve the router to spend WETH9. + TransferHelper.safeApprove(WETH9, address(swapRouter), amountIn); + // Create the params that will be used to execute the swap + ISwapRouter.ExactInputSingleParams memory params = + ISwapRouter.ExactInputSingleParams({ + tokenIn: WETH9, + tokenOut: DAI, + fee: feeTier, + recipient: msg.sender, + deadline: block.timestamp, + amountIn: amountIn, + amountOutMinimum: 0, + sqrtPriceLimitX96: 0 + }); + // The call to `exactInputSingle` executes the swap. + amountOut = swapRouter.exactInputSingle(params); + return amountOut; + } +} +``` - +To compile all the contracts in the `./contracts` folder, we’ll use the Hardhat compile command: ```bash -$ yarn hardhat -``` - - - - - -## Set the Solidity Version for Hardhat +$ npx hardhat compile +``` -For this example, we'll need to change ./hardhat.config.js to include the appropriate solidity version for compiling the Uniswap V3 contracts. If you are using Hardhat's example project, you can skip this step. +If the environment is compiled correctly you should see the message: -```js -/** - * @type import('hardhat/config').HardhatUserConfig - */ -module.exports = { - solidity: '0.7.6', -} +```bash +Compiled { x } Solidity files successfully ``` -## Compile Your Contracts +# Local Node with a Mainnet Fork - - +When building and testing integrations with on chain protocols, developers often hit a problem: the liquidity on the live chain is critical to thoroughly testing their code but testing against a live network like Mainnet can be extremely expensive. - ```bash - $ npx hardhat compile - ``` +Luckily, Hardhat has a powerful feature that allows developers to run a local Ethereum test node that uses a fork of Mainnet. This allows us to test against simulated liquidity for free. - +As a prerequisite we’ll need an RPC that supports [Forking](https://hardhat.org/hardhat-network/docs/guides/forking-other-networks). [Alchemy](https://www.alchemy.com/) includes forking in its free tier so it’s a great place to start (sign up and get an API key [here](https://www.alchemy.com/)). You can then run the following Hardhat command to start your node: - +```bash +$ npx hardhat node --fork https://eth-mainnet.alchemyapi.io/v2/{YOUR_API_KEY} +``` - ```bash - $ yarn hardhat compile - ``` +With your local node up and running, you can use the `--network localhost` flag in tests to point the Hardhat testing suite to that local node: - - +```bash +$ npx hardhat test --network localhost +``` -If everything worked correctly, and you used hardhat's simple example project, you should see the following output: +# Next Steps -```console -Downloading compiler 0.8.4 -Compiled 2 Solidity files successfully -✨ Done in 6.75s. -``` +With your environment set up you’re ready to start building. Jump over to the guides section to learn about the Uniswap functions you can integrate with. Remember to add all contracts (.sol files) to the `./contracts` folder and their subsequent tests to the `./tests` folder. You can then test them against your local forked node by running: +```bash +$ npx hardhat test --network localhost +``` \ No newline at end of file From 123f79c3601bf302366293769fa0e2d00ce9f96d Mon Sep 17 00:00:00 2001 From: "Alex.Karys" Date: Thu, 15 Sep 2022 15:42:21 -0400 Subject: [PATCH 2/5] Removing changes to front page --- src/pages/index.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/pages/index.js b/src/pages/index.js index eae648ee85..3472b32648 100644 --- a/src/pages/index.js +++ b/src/pages/index.js @@ -74,16 +74,16 @@ export const github = [ ] export const Guides = [ - { - title: 'Integration Quick Start', - text: 'Build your first on chain integration with the Uniswap Protocol.', - to: './protocol/guides/quickstart', - }, { title: 'SDK Quick Start', text: 'Integrate with the Uniswap Protocol using JavaScript', to: './sdk/guides/quick-start', }, + { + title: 'Implementing a Swap', + text: 'Start swapping from a smart contract in Solidity', + to: './protocol/guides/swaps/single-swaps', + }, { title: 'Embedding a Swap Widget', text: 'Let your users trade tokens without leaving your dApp', From 2c3c2bf038c080316c7df6f383ae6eb38b4b9c97 Mon Sep 17 00:00:00 2001 From: Alex Karys Date: Thu, 15 Sep 2022 15:48:15 -0400 Subject: [PATCH 3/5] Update local-environment.mdx --- versioned_docs/version-V3/guides/local-environment.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/versioned_docs/version-V3/guides/local-environment.mdx b/versioned_docs/version-V3/guides/local-environment.mdx index a85ad0163f..0a60dc2502 100644 --- a/versioned_docs/version-V3/guides/local-environment.mdx +++ b/versioned_docs/version-V3/guides/local-environment.mdx @@ -24,7 +24,7 @@ Then hop to the `Local Node with a Mainnet Fork` to complete your set up and sta # Start from Scratch -In the following sections, we’ll walk through the steps to create the environment set up as the boiler plate from scratch and learn the underlying concepts. +In the following sections, we’ll walk through the steps to create the same environment set up as the boiler plate from scratch and learn the underlying concepts. ## Set Up Dependencies @@ -148,4 +148,4 @@ With your environment set up you’re ready to start building. Jump over to the ```bash $ npx hardhat test --network localhost -``` \ No newline at end of file +``` From c3c15a713f45efac2cf7a7583e619a0aebb0e0c4 Mon Sep 17 00:00:00 2001 From: Alex Karys Date: Thu, 15 Sep 2022 17:52:08 -0400 Subject: [PATCH 4/5] Update local-environment.mdx --- versioned_docs/version-V3/guides/local-environment.mdx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/versioned_docs/version-V3/guides/local-environment.mdx b/versioned_docs/version-V3/guides/local-environment.mdx index 0a60dc2502..1ffe21b3df 100644 --- a/versioned_docs/version-V3/guides/local-environment.mdx +++ b/versioned_docs/version-V3/guides/local-environment.mdx @@ -87,7 +87,7 @@ contract SimpleSwap { swapRouter = _swapRouter; } - function swapWETHForDAI(uint amountIn) external returns (uint256 amountOut) { + function swapWETHForDAI(uint256 amountIn) external returns (uint256 amountOut) { // Transfer the specified amount of WETH9 to this contract. TransferHelper.safeTransferFrom(WETH9, msg.sender, address(this), amountIn); @@ -107,7 +107,6 @@ contract SimpleSwap { }); // The call to `exactInputSingle` executes the swap. amountOut = swapRouter.exactInputSingle(params); - return amountOut; } } ``` From 989fb0838142005ea05139107a4b70ea014d8129 Mon Sep 17 00:00:00 2001 From: Alex Karys Date: Thu, 15 Sep 2022 18:11:55 -0400 Subject: [PATCH 5/5] Update local-environment.mdx --- versioned_docs/version-V3/guides/local-environment.mdx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/versioned_docs/version-V3/guides/local-environment.mdx b/versioned_docs/version-V3/guides/local-environment.mdx index 1ffe21b3df..64450b1b5f 100644 --- a/versioned_docs/version-V3/guides/local-environment.mdx +++ b/versioned_docs/version-V3/guides/local-environment.mdx @@ -93,6 +93,9 @@ contract SimpleSwap { TransferHelper.safeTransferFrom(WETH9, msg.sender, address(this), amountIn); // Approve the router to spend WETH9. TransferHelper.safeApprove(WETH9, address(swapRouter), amountIn); + // Note: To use this example, you should explicitly set slippage limits, omitting for simplicity + const minOut = /* Calculate min output */ 0; + const priceLimit = /* Calculate price limit */ 0; // Create the params that will be used to execute the swap ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams({ @@ -102,8 +105,8 @@ contract SimpleSwap { recipient: msg.sender, deadline: block.timestamp, amountIn: amountIn, - amountOutMinimum: 0, - sqrtPriceLimitX96: 0 + amountOutMinimum: minOut, + sqrtPriceLimitX96: priceLimit }); // The call to `exactInputSingle` executes the swap. amountOut = swapRouter.exactInputSingle(params);