Functions: The Graph and Uniswap

Overview

This use case demonstrates how to connect the Graph API and Uniswap router using Chainlink Functions to implement a trading strategy.

In particular, the example demonstrates how to retrieve three-day trading volume data from the WETH-USD pool in Uniswap V3 through a subgraph. It then uses Chainlink Functions to evaluate the liquidity based on the trading volume data.

If the liquidity of the pair is increasing, Chainlink functions triggers a function in FunctionsConsumer.sol to swap Wrapped Matic in the contract balance to Wrapped Ether.

Original idea behind the use case is that strong liquidity implies relatively safer assets as high liquidity assets are more easily traded and typically have lower price volatility. Therefore, decisions based on liquidity data from Uniswap pools can provide more reliable information to assess the risk asset swaps.

Under the scenario, using Chainlink Functions allows for a more accurate assessment of whether to exchange Wrapped Matic for WETH based on the current liquidity conditions, enabling better risk management.

In this use case, the reason for choosing to swap Wrapped matic to Wrapped Ether is that in the Polygon Mumbai testnet, only the the pair has sufficient liquidity for testing purposes. In production, you can choose any token pair to swap based on your needs and strategies.

Quick Start

Requirements

Install both of the following:

  • Node.js version 18.18.0 (or the latest release of Node.js v18 if a later one is available)
  • Deno version 1.36 (or the latest release of Deno v1 if a later one is available)

Steps

  1. Clone this repository to your local machine

  2. Open this directory in your command line, then run npm install to install all dependencies.

  3. Aquire a Graph key which allows reading data indexed by subgraphs. Please do not forget to claim queries and make sure FREE REMAINING: 1000 displayed in column "QUERIES TOTAL" of the key.

  4. Set the required environment variables.

    1. Set an encryption password for your environment variables to a secure password by running:
      npx env-enc set-pw
    2. Use the command npx env-enc set to set the required environment variables (see Environment Variable Management):
      • GRAPH_KEY for Graph key obtained from step 4
      • PRIVATE_KEY for your development wallet
      • POLYGON_MUMBAI_RPC_URL, ETHEREUM_SEPOLIA_RPC_URL
    3. If desired, the POLYGONSCAN_API_KEY can be set in order to verify contracts`.

  5. There are two files to notice that the example will use:

    • contracts/FunctionsConsumer.sol contains the smart contract that will receive the data and make the swap
    • graph_request.js contains JavaScript code that will be executed by each node of the DON

  6. Test an end-to-end request and fulfillment locally by simulating it using:
    npx hardhat functions-simulate-script

  7. Deploy and verify the client contract to an actual blockchain network by running:
    npx hardhat functions-deploy-consumer --network polygonMumbai --verify true
    Note: Make sure POLYGONSCAN_API_KEY is set if using --verify true, depending on which network is used.

  8. Create, fund & authorize a new Functions billing subscription by running:
    npx hardhat functions-sub-create --network polygonMumbai --amount 5 --contract <contract_address>

    Note 1: You have to go to the Chainlink Functions Webapp to sign the term of use in the first time. .

    Note 2: Ensure your wallet has 5 LINK in your balance before running this command. Testnet LINK can be obtained at faucets.chain.link.

    Note 3: Please make sure that you are using polygon mumbai testnet. If you want to use the contract in other networks, change the line if (block.chainid != 80001) in the file FunctionsConsumer.sol.

  9. Transfer at least 0.1 WMATIC to contract FunctionsConsumer to make sure there is some WMATIC tokens in balance can be swapped. You need to add WMATIC into your Metamask before transfering, and the address of WMATIC on Polygon Mumbai is 0x9c3C9283D3e44854697Cd22D3Faa240Cfb032889.
    Matic on Mumbai can be obtained at alchemy faucet, and Matic can be swapped to Wrapped Matic(WMATIC) at Uniswap on Mumbai.

    . If you visit your deployed contract in polygonscan you will see that it has a token balance equal to the amount of WMATIC you sent it.

  10. Make an on-chain request by running:
    npx hardhat functions-request --network polygonMumbai --contract <contract_address> --subid <subId> --callbackgaslimit 300000. Please make sure you add the parameter --callbackgaslimit and set it as 300k.

  11. Since the contract is verified you can read the s_lastResponse or s_lastError storage variables in FunctionsConsumer.sol once Chainlink Functions has fulfilled the request. If everything has worked as expected, s_lastResponse should have a hex string and s_lastError should be empty bytes, i.e. 0x. If there was an increase in the WETH/USD pool's liquidity then we would expect that s_lastResponse would be 0x......001 (the decimal 1) - meaning that the FunctionsConsumer.sol would swap the contract balance WMATIC for WETH.

  12. Lastly, check your contract token balance on polygonscan by refreshing that page. The WMatic should have have been swapped for WETH, meaning that your contract now only has a WETH balance. Success!

For Beginners

Disclaimer

This tutorial offers educational examples of how to use a Chainlink system, product, or service and is provided to demonstrate how to interact with Chainlink’s systems, products, and services to integrate them into your own. This template is provided “AS IS” and “AS AVAILABLE” without warranties of any kind, it has not been audited, and it may be missing key checks or error handling to make the usage of the system, product, or service more clear. Do not use the code in this example in a production environment without completing your own audits and application of best practices. Neither Chainlink Labs, the Chainlink Foundation, nor Chainlink node operators are responsible for unintended outputs that are generated due to errors in code