ntropika-labs / potion-protocol

2 stars 3 forks source link

Potion Protocol

Amazing risk management protocol!
Potion is a decentralized protocol for the creation of price insurance contracts running on the Ethereum network. For more information on how it works, check out the Potion Docs project.

Before getting started please be sure to have installed the Requirements.

Requirements

The following binaries are required to run the project

You can run the bin/check-dependencies script to check if everything is installed correctly

Quick Start

Setup instructions

Some configuration is required before spinning up the environment.
Run cp .env.example .env to copy the environment example file and customize the following variables:

Using ganache databases

The ganache container is configured to use databases from a bind mount, this is used to store our previous interactions and/or restore known states for tests/debugging.
To make prototyping and testing easier to handle, we have prepared a set of database seeds that can be found in the ganache_seeds folder.

Setting up ganache databases

  1. Create a folder that will be used as a bind mount on the host machine (it is higly recommended to set up it outside the monorepo to avoid permissions issues with tools). See example.

  2. Put the path (relative or absolute will both work) inside the .env file into the GANACHE_VOLUME variable. This folder will be mounted to the /opt path within the container. See example.

  3. Put into the DATABASE_PATH variable the path (from inside the container) to the database that you want to use. See example.
    An absolute path inside the ganache container starting with /opt. You can choose any name except those that match a seed name from ganache_seeds as the bootstrapping process needs a fresh copy of the database to initialize properly.
    If you already initialized your environment you can also use a path to any of the available ganache seeds (eg /opt/base) and the test data will be loaded.

Creating/restoring databases

  1. Copy the databases in the ganache_seeds to the bind mount folder (there is a setup-database-seed script into the bin folder that will copy the databases in the correct place using your .env file). It is possible to copy entire folders to "create" a new database (eg, copy the base database to develop).
  2. If you are using the base database ensure that CHAIN_TIME is set to 2021-01-01 09:00:00+00:00

Ganache example config

Available Ganache seeds

You can use any of the pre-made databases by setting DATABASE_PATH="/opt/{database name}" in your .env file, where {database name} is any of the following:

Ganache and block time

IMPORTANT: Ganache by default uses the host local time to determine the timestamp of the next block, this can cause issues with expirations not working because the time turned back or create inconsistency in the charts.
To avoid this issue on the CI the base database has been created with the date 2020-01-01 00:00:00+00:00 but because the deployment script fast forwards one year you should start the blockchain locally from 2021-01-01 09:00:00+00:00.
Every time that you do a fast forward remember to update your starting time to reflect it, otherwise next time that you restart the containers you will incur into a time mismatch.

Testing

unit test

The project implements unit tests for potion-contracts with Hardhat, potion-subgraph with Matchstick and Vitest for potion-dapp and potion-ui. Every package has at least one script (eg, test-unit) to launch them, for more details check the specific package.json of that package.

e2e

The project currently implements e2e testing for potion-dapp and component testing for potion-ui. Both workspaces are configured to use Cypress as a testing tool.

Potion DApp testing

Tests are located within cypress/e2e folder.

yarn nx run potion-dapp:local-test-e2e

yarn nx run potion-dapp:ci-test-e2e

Requires a running docker environment

To have more control over what commands are issues to start the testing environment you can use:

Potion UI testing

Tests are located within each component subfolder and are named as {component}.cy.ts

yarn nx run potion-ui:test-component-ci

yarn nx run potion-ui:cypress

Mocked web3-onboard

In order to test actions involving interaction with a Wallet, a mocked version of web3-onboard is injected at compilation time, based on an environment variable. This is also the difference between the commands yarn nx run potion-dapp:build and yarn nx run potion-dapp:build-test.
This mocked instance implements all the methods available in the original library that are used within potion-dapp, exposing the same interface and also offering the same degree of reactivity. All methods are supposed to be called in an headless environment, thus eliminating the requirement for user interaction. To achieve the statefulness required by the app, this instance uses a local state to store information and its methods refer to this single source of truth to interact with current state.

Inner works of test scripts

This is what happens locally behind the scenes to start and seed the environment:

  1. Spin up the Docker environment with docker compose up -d -V, starting the following services:

    • potion_postgres: PostgreSql database to store indexed data

    • potion_ipfs: local IPFS instance on which to upload the subgraph

    • potion_ganache: Ganache instance for a local blockchain

    • potion_graph_node: Graph Node to index the data from the blockchain and expose it using GraphQL

  2. Once containers are up and ready to accept new connections:

    • If this is the first time running this environment, seeds the database by running the template and deploying both the contracts and the subgraph

    • If the database is already available, only runs the template for the subgraph and deploys it

Monorepo overview

flowchart TD;
  A[potion-dapp];
  B[price-source-benchmark];
  C[(subgraph)];
  D(contracts-core);
  E(gamma-protocol);
  F([contracts-math]);
  G([dapp-types]);
  H([locales]);
  I([potion-router]);
  J([potion-tokenlist]);
  K([potion-ui]);
  L([potion-unocss]);
  M([subgraph-queries]);  
  subgraph PC[Potion contracts];
    E ==> D;
  end
  subgraph PD[Potion Dapp]
    F --> A;
    I --> A;
  end
  subgraph PS[Potion Subgraph]
    C --> M;
  end
  subgraph PU[Potion UI]
    G -.-> K;
    H --> K;
    J --> K;
    L --> K;
  end
  PC -. Provide types .-> PD;
  PC -- Provide ABIs --> PS;
  PS -- Providess data --> PD;
  PU -- Provides UI component and utilities ---> B & PD;

This repository hosts all of the code for the Potion Protocol and as such comprises:

For ease of maintenance we have a single package.json file in the root of the monorepo, which lists all dependencies for all projects.
Each project then has it's own package.json listing all scripts that can be run against that particular project.
To enchance the development experience we are making use of Yarn workspaces togheter with Nx to simplify and coordinate issuing commands for different projects.
For example:

yarn nx run potion-dapp:local-dev

apps/potion-dapp

Read more

Project containing files for the Vue3 app in charge of showing and updating data to and from the protocol.

apps/subgraph

Read more

Local subgraph tracking updates to the protocol entities.

bin

This folder contains all scripts developed to assist in spinning up the environment and running development operations.
These consist of:

contracts/core

Read more

Some tests for the core contracts have been currently modified because of an issue between ethers.js and hardhat where the revert reason emitted by hardhat is not understood by ethers.js. The hardhat team is working on a fix but as of version 2.9.3 the fix is not yet available. The affected files are:

contracts/gamma-protocol

Read more

This workspace provides the Opyn Gamma protocol contracts, required for the core contracts of the Potion Protocol

ganache_seeds

This folder contains a set of subfolders containing seed data for Ganache.
Different seeds are useful for testing different features of the DApp.

libs/contracts-math

This library provides convenient wrappers and type helpers for working with 59x18 bit fixed-point decimals.

libs/dapp-types

This library contains a single index.ts file with types shared among apps and libraries

libs/locales

This library contains all locales and their data available within the app.
For ease of use and to also allow for import within tests those data have been extracted to its own library.

libs/potion-router

This library contains the Potion Router + an helper library to load the required data from the Potion Subgraph

libs/potion-tokenlist

This library hosts configuration files for the tokens available on different networks supported by the protocol.

libs/potion-ui

Read more

This library contains all the UI components used within Potion DApp.

libs/potion-unocss

This library contains the configuration used for UnoCSS.
It's contained in it's own library to share config between apps and libraries.

libs/subgraph-queries

Read more

This library is used to generate useful javascript/typescript bindings to interact with a graphql endpoint.

Customization

The project allows for customizing various aspects of it also affecting different workspaces. Listed here are all the required variables (marked as such) and some of the main ones if you want to further customize your setup:

VITE_SUBGRAPH_ADDRESS="http://localhost:8000/subgraphs/name/potion-subgraph"
VITE_DEVELOPMENT_MNEMONIC="test test test test test test test test test test test junk"
DEPLOYER_MNEMONIC="test test test test test test test test test test test junk"
VITE_BLOCKNATIVE_API_KEY="your BlockNative API key"
VITE_ENDPOINT_PROVIDER="alchemy"
VITE_ALCHEMY_KEY="your Alchemy API key"
VITE_INFURA_KEY=""
GANACHE_VOLUME="../data/ganache"
DATABASE_PATH="/opt/base"
CHAIN_TIME="2021-01-01 08:00:00+00:00"

Environment variables

See .env.example for available environment variables and their purpose.

Updating packages

Packages that shouldn't be updated without a reason

How to perform a dependency update

Known dependencies between packages