facebook

Utilizing the new Uniswap v2 in Your Smart Contract

Posted By : Himanshu

Nov 01, 2020

In case you're inexperienced with Uniswap yet, it's a completely decentralized convention for computerized liquidity arrangement on Ethereum. A more clear depiction would be that it's a decentralized trade (DEX) depending on outside liquidity suppliers that can add tokens to shrewd agreement pools and clients can exchange those straightforwardly. 

 

Since it's running on Ethereum, what we can exchange are Ethereum ERC-20 tokens. For every token, there is its own savvy agreement and liquidity pool. Uniswap - being completely decentralized - has no limitations to which tokens can be added. On the off chance that no agreements for a symbolic pair exist yet, anybody can make one utilizing their production line and anybody can give liquidity to a pool. A charge of 0.3% for each exchange is given to those liquidity suppliers as motivation. 

 

The cost of a token is controlled by the liquidity in a pool. For instance, if a client is purchasing TOKEN1 with TOKEN2, the flexibility of TOKEN1 in the pool will diminish while the use of TOKEN2 will increase and the cost of TOKEN1 will also increase. Moreover, if a client is selling TOKEN1, the cost of TOKEN1 will diminish. Thusly the symbolic cost consistently mirrors the flexibility and request. 

 

Also, obviously, a client doesn't need to be an individual, it tends to be a keen agreement. That permits us to add Uniswap to our own agreements for adding extra installment choices for clients of our agreements. Uniswap makes this cycle exceptionally helpful, see beneath for how to coordinate it.

 

What's happening in UniSwap v2?

 

  • ERC20/ERC20 Pairs: In the primary form any token must be combined with ETH. To exchange a token with another token, one needed to initially trade the initial token into ETH and afterward utilize that ETH to buy the other token. Presently you can legitimately exchange those!
  • Value Oracles: While hypothetically one could utilize Uniswap v1 as a prophet, it wasn't suggested as costs could fluctuate by a great deal in a brief timeframe making it simple to control. Presently there are a few instruments to forestall this like utilizing the last square cost and an aggregate value that is weighted when past costs existed.
  • Streak Swaps: The Uniswap Flash Swaps are like the Aave Flash Loans that you may be comfortable with. A similar idea is currently conceivable in Uniswap permitting you to hopefully get tokens as long as you either 1. return them 2. pay for them or 3. somewhat return/pay for them toward the finish of the exchange.
  • Way to Sustainability: An alternative was added that once enacted adds a 0.05% exchanging charge planned for convention administration. It's not intended to actuate this soon.

 

Integrating UniSwap v2 :- 

 

One reason Uniswap is so well known might be the basic method of incorporating them into your own keen agreement. Suppose you have a framework where clients pay with DAI. With Uniswap in only a couple of lines of code, you could add the alternative for them to likewise pay in ETH. The ETH can be consequently changed over into DAI before the genuine rationale. It would look something like this 

 

 

function pay(uint paymentAmountInDai) public payable {
      if (msg.value > 0) {
          convertEthToDai(paymentAmountInDai);
      } else {
          require(daiToken.transferFrom(msg.sender, address(this), paymentAmountInDai);
      }
      // do something with that DAI
      ...
}

 

A straightforward check toward the start of your capacity will be sufficient. Presently with respect to the convertEthToDai work, it will look like something this:

 

 

function convertEthToDai(uint daiAmount, uint deadline) public payable {
    address[] memory path = new address[](2);
    path[0] = uniswapRouter.WETH();
    path[1] = daiToken;

    uniswapRouter.swapETHForExactTokens.value(msg.value)(daiAmount, path, address(this), deadline);
    
    // refund leftover ETH to user
    msg.sender.call.value(address(this).balance)("");
  }

 

There are several things to unpack here

 

Uniswap Router

 

The uniswapRouter will be a wrapper contract provided by Uniswap that has several safety mechanisms and convenience functions. Currently, it is recommended to use the Router02 contract. You can instantiate it using IUniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D) for any main or testnet. The interface code can be found here.

 

Path

 

Any swap needs to have a starting and end path. While in Uniswap v2 you can have a direct token to token pairs, it is not always guaranteed that such a pair actually exists. But you may still be able to trade them as long as you can find a path, e.g., Token1 → Token2 → WETH → Token3. In that case, you can still trade Token1 for Token3, it will only cost a little bit more than a direct swap.

 

WETH

 

You might notice that we are using WETH here. In Uniswap v2 there are no more direct ETH pairs, all ETH must be converted to WETH first. In our case, this is done by the router.

 

swapETHForExactToken

 

This function can be used to use ETH and receive an exact amount of tokens for it. Any leftover ETH will be refunded, so make sure you have a fallback function in your contract to receive ETH: receive() payable external {}. The deadline parameter will ensure that miners cannot withhold a swap and use it at a later, more profitable time. Make sure to pass this UNIX timestamp from your frontend, don't use it now inside the contract.

 

Refund

 

Once the trade is finished, we can return any leftover ETH to the user. This sends out all ETH from the contract, so if your contract might have an ETH balance for other reasons, make sure to change this.

 

Instructions to utilize it in the frontend

 

One issue we have now is the point at which a client calls the compensation capacity and needs to pay in ETH, we don't have the foggiest idea of the amount ETH he needs. We can utilize the getAmountsIn capacity to figure precisely that.

 

function getEstimatedETHforDAI(uint daiAmount) public view returns (uint[] memory) {
    address[] memory path = new address[](2);
    path[0] = uniswapRouter.WETH();
    path[1] = multiDaiKovan;

    return uniswapRouter.getAmountsIn(daiAmount, path);
}

 

Presently we can call getEstimatedETHforDAI in our frontend. To guarantee we are sending enough ETH and that the exchange won't get returned, we can expand the assessed measure of ETH by a tad:

 

const requiredEth = (await myContract.getEstimatedETHforDAI(daiAmount))[0];
const sendEth = requiredEth * 1.1;

 

Completely working model for Remix 

 

Here's a complete working model you can utilize straightforwardly on Remix. It permits you to exchange ETH for Multi-collateralized Kovan DAI:

 

pragma solidity 0.7.1;

import "https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/interfaces/IUniswapV2Router02.sol";

contract UniswapExample {
  address internal constant UNISWAP_ROUTER_ADDRESS = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D ;

  IUniswapV2Router02 public uniswapRouter;
  address private multiDaiKovan = 0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa;

  constructor() {
    uniswapRouter = IUniswapV2Router02(UNISWAP_ROUTER_ADDRESS);
  }

  function convertEthToDai(uint daiAmount) public payable {
    uint deadline = block.timestamp + 15; // using 'now' for convenience, for mainnet pass deadline from frontend!
    uniswapRouter.swapETHForExactTokens{ value: msg.value }(daiAmount, getPathForETHtoDAI(), address(this), deadline);
    
    // refund leftover ETH to user
    (bool success,) = msg.sender.call{ value: address(this).balance }("");
    require(success, "refund failed");
  }
  
  function getEstimatedETHforDAI(uint daiAmount) public view returns (uint[] memory) {
    return uniswapRouter.getAmountsIn(daiAmount, getPathForETHtoDAI());
  }

  function getPathForETHtoDAI() private view returns (address[] memory) {
    address[] memory path = new address[](2);
    path[0] = uniswapRouter.WETH();
    path[1] = multiDaiKovan;
    
    return path;
  }
  
  // important to receive ETH
  receive() payable external {}
}

 

Leave a

Comment

Name is required

Invalid Name

Comment is required

Recaptcha is required.

blog-detail

December 17, 2024 at 05:11 pm

Your comment is awaiting moderation.

By using this site, you allow our use of cookies. For more information on the cookies we use and how to delete or block them, please read our cookie notice.

Chat with Us
Telegram Button
Youtube Button

Contact Us

Oodles | Blockchain Development Company

Name is required

Please enter a valid Name

Please enter a valid Phone Number

Please remove URL from text