Skip to content

Commit

Permalink
public-prep
Browse files Browse the repository at this point in the history
  • Loading branch information
LPX55 authored and LPX55 committed Apr 26, 2023
1 parent 613e992 commit 97a6d6c
Show file tree
Hide file tree
Showing 16 changed files with 132 additions and 105 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ yarn-error.log*
# vercel
.vercel

# vscode
.vscode

# typescript
*.tsbuildinfo
next-env.d.ts
Expand Down
97 changes: 10 additions & 87 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,17 @@
- [Tailwind](https://tailwindcss.com/) for CSS styling
- [Planetscale](https://planetscale.com/) for data persistence
- [Prisma](https://www.prisma.io/) for ORM
- [NextAuth](https://next-auth.js.org/) for authentication via GitHub
- [NextAuth](https://next-auth.js.org/) for wallet authentication via WAGMI / SIWE
- [Mux](https://mux.com) for video streaming and thumbnail generation
- [Mux Player](https://docs.mux.com/guides/video/mux-player) for video playback
- [Mux Uploader](https://github.com/muxinc/elements/tree/main/packages/mux-uploader-react) for video uploading

## Progressive Decentralization

I'm a cheapskate, everything will hopefully move to IPFS or Arweave. But ain't got time fo dat now.

### Create a `.env.local` file

This project uses several secrets to access the different accounts used throughout the codebase. You can configure these values locally by copying the `.env.local.example` file to a new file called `.env.local` and filling out the values as you receive them in the steps below.

Also, don't forget to add the values to the project's environment variables in production on Vercel.

### Mux account setup

To authenticate this application with your Mux account, [create a new access token](https://dashboard.mux.com/settings/access-tokens) within the Mux dashboard and copy the access token ID and secret into your `.env.local` file and into your Vercel environment variables.

### Database Setup

First, make sure you have `mysql-client` installed locally so you can take full advantage of the `pscale` CLI tool down the road. On MacOS with Homebrew installed, you can run the following command in your terminal:
First, make sure you have `mysql-client` installed locally so you can take full advantage of the `pscale` CLI tool down the road.

```
brew install mysql-client
Expand All @@ -45,99 +34,33 @@ Next, authorize the Planetscale CLI with your newly created account by running:
pscale auth
```

Create a new database in your Planetscale account called `video-course-starter-kit`
```
pscale database create video-course-starter-kit
```
Follow the link provided to you as a result of running this command to get the connection string for your database.

![Click to get your connection string](public/images/pscale-connect.png)
![Change your connection method to Prisma](public/images/pscale-prisma.png)
![Copy the value and paste into your .env.local file](public/images/pscale-string.png)

Copy the resulting authenticated database url value into your `.env.local` file and into your Vercel environment variables.

We'll connect to this database locally by opening a connection to it on a local port. Here's how you can connect to the Planetscale database `video-course-starter-kit` on port 3309:

Create a new database in your Planetscale account.
```
pscale connect video-course-starter-kit main --port 3309
pscale database create `your db`
```

## Modifying the database schema

If you'd like to make any changes to the database schema, you can do so by following these steps:

```
pscale branch create video-course-starter-kit my-new-branch
pscale branch create `your-db` `you-new-branch`
# after a few moments, close and reopen db proxy to the new branch
pscale connect video-course-starter-kit my-new-branch --port 3309
pscale connect your-db your-new-branch --port 3309
# change your schema in the prisma/schema.prisma file... then,
npx prisma generate
npx prisma db push
# when ready, make a deploy request
pscale deploy-request create video-course-starter-kit my-new-branch
# deploy when ready
pscale deploy-request your-db my-new-branch
# shipit
pscale deploy-request deploy video-course-starter-kit 1
pscale deploy-request deploy your-db 1
```

## Inspecting the database
Prisma provides a nice interface to be able to load up your database contents and see the data that is powering your application. When you've connected to your Planetscale database, you can load up the Prisma GUI with the following command:

```
npx prisma studio
```

## Handling webhooks

Mux uses webhooks to communicate the status of your uploaded video assets back to your application. To handle these webhooks locally, you'll first need to install [ngrok](https://ngrok.com/download).

```shell
brew install ngrok/ngrok/ngrok
ngrok config add-authtoken <YOUR_NGROK_TOKEN>
ngrok http 3000
```

Now, we need to make Mux aware of your ngrok URL. Visit [https://dashboard.mux.com/settings/webhooks](https://dashboard.mux.com/settings/webhooks) and add the tunnel URL listed in your terminal as a URL that Mux should notify with new events.

> Make sure to append `/api/webhooks/mux` to the end of your tunnel URL.
Then, copy the Webhook signing secret value and paste it into your `.env.local` file under `MUX_WEBHOOK_SECRET`

### Run the development server

Starting up the dev server is a simple one line command:

```
yarn dev
```

### GitHub OAuth setup

End users of this video course application can authenticate with their GitHub account. As a prerequisite, you'll need to create an OAuth App on GitHub that associates a user's access to your application with your GitHub account.

To create your OAuth app, follow these steps:

1. Go to [https://github.com/settings/developers](https://github.com/settings/developers)

2. Click "OAuth Apps" and create an Oauth application to use in Development:

![Github Oauth Application Setup](./screenshots/github-oauth.png)

| Application name | Homepage URL | Authorization callback URL |
|--------------------------------|----------------------------------------------------|----------------------------|
| Video Course Starter Kit (dev) | https://github.com/muxinc/video-course-starter-kit | http://localhost:3000/ |

3. Copy the `GITHUB_ID` and `GITHUB_SECRET` and paste them into your environment variables on Vercel and in your `.env.local` file.

> Note: when you deploy a production copy of this application, you'll need to create another GitHub OAuth app which uses your production URL as the "Authorization callback URL" value.
## Recommended VS code extensions
### Prisma
The [Prisma extension](https://marketplace.visualstudio.com/items?itemName=Prisma.prisma) adds syntax highlighting, formatting, auto-completion, jump-to-definition and linting for .prisma files.

## Questions? Comments?

Tweet us [@MuxHQ](https://twitter.com/muxhq) or email [email protected] with anything you need help with.
```
4 changes: 2 additions & 2 deletions components/Nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@ return (
</div>
<Link href="/" passHref>
<a className="flex justify-center items-center">
<Image alt="ForgeDEX" height={40} src="https://testnet.forge.trade/images/ForgeIcon.png" width={40} />
<Image alt="ForgeDEX" height={40} src="https://app.forge.trade/images/ForgeIcon.png" width={40} />
</a>
</Link>
<a className="hidden md:flex ml-3 normal-case text-2xl font-bold mr-1">FORGE<span className="font-medium">MASTERY</span></a>
<div className="hidden lg:flex divider divider-horizontal"></div>
<ul className="hidden lg:flex menu menu-horizontal rounded-sm text-sm uppercase">
<li className="indicator">
<span className="indicator-item indicator-start badge badge-primary rounded-full p-1 top-2 left-2 leading-3 text-[0.7rem] z-0"></span>
<span className="indicator-item indicator-start badge badge-primary rounded-full p-1 top-2 left-2 leading-3 text-[0.7rem] z-0 cursor-none hover:animate-pulse"></span>
<Link href="/courses/1-basic-training">Bootcamp</Link>
</li>
<li><Link href="/resources/tools-resources">Tools & Resources</Link></li>
Expand Down
2 changes: 1 addition & 1 deletion next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ module.exports = withNextra({
reactStrictMode: true,
swcMinify: true,
images: {
domains: ['image.mux.com', 'testnet.forge.trade', 'docs.forge.trade'],
domains: ['image.mux.com', 'app.forge.trade', 'docs.forge.trade'],
},
})
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
{
"name": "forge-video-tuts",
"name": "forge-mastery",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "npx prisma generate && next dev",
"build": "npx prisma generate && npx prisma db push && next build",
"start": "next start",
"lint": "next lint",
"db:proxy": "pscale connect video-course-starter-kit main --port 3309"
"lint": "next lint"
},
"dependencies": {
"@mux/blurhash": "^0.1.2",
Expand Down
2 changes: 1 addition & 1 deletion pages/resources/_meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"index": "Forge Introduction",
"protocol": "The Protocol",
"concepts": "Important Concepts",
"Tokenomics": "Tokenomics",
"Tokenomics": "Community Owned DEX",
"governance": "Governance",
"partnership-grants": "Partnerships & Grants",
"listing": "Project Listing",
Expand Down
8 changes: 5 additions & 3 deletions pages/resources/concepts/_meta.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
{
"concentrated-liquidity": "Concentrated Liquidity",
"fees": "Fee Tiers",
"range-orders": "Range Orders"

"range-orders": "Range Orders",
"fees": "Multiple Fee Tiers",
"capital-efficiency": "Capital Efficiency",
"nonfungible": "Non-Fungible Positions",
"advanced": "Advanced Strategies"
}
21 changes: 19 additions & 2 deletions pages/resources/concepts/advanced.mdx
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
# Advanced
# Advanced Strategies

WIP
<section>
<div className="px-4 py-12 mx-auto max-w-7xl sm:px-6 md:px-12 lg:px-24 lg:py-32">
<div className="flex flex-col w-full mb-12 text-center">
<div className="inline-flex items-center justify-center flex-shrink-0 w-20 h-20 mx-auto mb-1 text-[#e04b34] rounded-full">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" className="w-12 h-12 animate-spin transition ease-linear delay-100">
<path strokeLinecap="round" strokeLinejoin="round" d="M10.343 3.94c.09-.542.56-.94 1.11-.94h1.093c.55 0 1.02.398 1.11.94l.149.894c.07.424.384.764.78.93.398.164.855.142 1.205-.108l.737-.527a1.125 1.125 0 011.45.12l.773.774c.39.389.44 1.002.12 1.45l-.527.737c-.25.35-.272.806-.107 1.204.165.397.505.71.93.78l.893.15c.543.09.94.56.94 1.109v1.094c0 .55-.397 1.02-.94 1.11l-.893.149c-.425.07-.765.383-.93.78-.165.398-.143.854.107 1.204l.527.738c.32.447.269 1.06-.12 1.45l-.774.773a1.125 1.125 0 01-1.449.12l-.738-.527c-.35-.25-.806-.272-1.203-.107-.397.165-.71.505-.781.929l-.149.894c-.09.542-.56.94-1.11.94h-1.094c-.55 0-1.019-.398-1.11-.94l-.148-.894c-.071-.424-.384-.764-.781-.93-.398-.164-.854-.142-1.204.108l-.738.527c-.447.32-1.06.269-1.45-.12l-.773-.774a1.125 1.125 0 01-.12-1.45l.527-.737c.25-.35.273-.806.108-1.204-.165-.397-.505-.71-.93-.78l-.894-.15c-.542-.09-.94-.56-.94-1.109v-1.094c0-.55.398-1.02.94-1.11l.894-.149c.424-.07.765-.383.93-.78.165-.398.143-.854-.107-1.204l-.527-.738a1.125 1.125 0 01.12-1.45l.773-.773a1.125 1.125 0 011.45-.12l.737.527c.35.25.807.272 1.204.107.397-.165.71-.505.78-.929l.15-.894z" />
<path strokeLinecap="round" strokeLinejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>

</div>
<h1 className="max-w-5xl text-2xl font-bold leading-none text-neutral-600 md:text-5xl lg:text-6xl lg:max-w-7xl lg:mt-12">
Check back soon!
</h1>

<p className="max-w-xl mx-auto mt-8 text-base leading-relaxed text-center uppercase text-gray-500">Page is still under development.</p>
</div>
</div>
</section>
75 changes: 75 additions & 0 deletions pages/resources/concepts/capital-efficiency.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
---
id: capital-efficiency
title: Maximum Capital Efficiency
sidebar_position: 2
---

# Maximum Capital Efficiency with Forge

<img src="/animations/capital-efficiency.webp" class="w-full mt-8"/>

Through concentrated liquidity, LPs can provide the <strong>same liquidity depth as other v2 DEXs</strong> within specified price ranges while <strong>putting far less capital at risk.</strong> The capital saved can be held externally, invested in different assets, deposited elsewhere in DeFi, or used to increase exposure within the specified price range to earn more trading fees.

## A Simple Illustration of the Power of Concentrated Liquidity

The power of concentrated liquidity can be easily understood by simple math and some common sense. Let's take an example scenario:

- <b>Alicia and Bob</b> both want to broaden their horizons and diversify their positions via the IBC ecosystem.
- They both decide that they want to provide liquidity in an ETH/USDC pool on an IBC and Cosmos native DEX.
- They each have $1 million at their disposal. The bears seem to be weakening and they are both cautiously optimistic.
- We assume that the price of ETH is 1,500 USDC at the time of this example.

Alicia decides to deploy her capital across the entire price range on Osmosis (or any other DEX using Uniswap v2-like contracts). She deposits 500,000 USDC and 333.33 ETH <b>(worth a total of about $1 million).</b>

Bob, however, is a bit more well-versed in trading and DeFi and is already familiar with the concept of Uniswap v3 and concentrated liquidity. He heads over to Forge and creates a concentrated position, depositing only within the price range from 1,000 to 2,250. He reasons that while he is slightly more optimistic and believes that the price of Ethereum will remain within his range, he does not want to put his entire capital at risk.

Ultimately, Bob decides to deposits 91,751 USDC and 61.17 ETH, <b>worth a total of about $183,500.</b> He keeps the other $816,500 himself, investing and spending it however he prefers.

---

<b>A year has passed since Alicia and Bob deployed their capital. As Bob predicted, the price of Ethereum stayed within the $1,000 and $2,250 range throughout the entirety of the time. While both made a pretty impressive profit, Bob came out on top as the clear winner in this example.</b>

Although Alicia invested <b>5.44x more capital</b> than Bob:

- They ended up earning the same amount of profit from fees, but Bob's APR on his position was 314% while Alicia was limited to a 50% return.
- Bob's position was protected the entire time through his range order, which acted as a stop-loss order.
- Alicia's entire $1 million position was exposed to risk, including severe impermanent loss (Bob also took some IL risk, but a much smaller amount of his capital was exposed).
- Bob was able to spend his remaining $816,500 on so much more, i.e. hedging his position, participating in other protocols and pools, buying himself a nice condo, and of course, a small bag of high risk altcoins with much bigger upside potential for the next run.

<p class="mt-8"><b>So how did Bob end up making the same amount from fees as Alicia?</b></p>

While Alicia's contribution to her liquidity pool was much larger in amount, most of it ended up being worthless in the macro scope as her capital provided liquidity from a price of $0 to infinity. In other words, her capital was deployed in a much more inefficient manner than Bob's.

<p class="mt-8"><b>What if Bob deployed his full $1 million into his position?</b></p>

Well, he would have obviously turned a much bigger profit, but his risk to reward ratio would have been significantly different.

Instead of providing equivalent liquidity depth as a v2 LPs with less capital, v3 LPs can choose to provide greater depth with the same amount of capital as their v2 counterparts. <b>However</b> this requires taking on more risk and impermanent loss to the LPs capital. Of course, with more risk comes higher potential fees, while supporting a greater range of trading. It is ultimately up to each individual and their risk profile to decide what approach he or she wants to take.

## Liquidity in Stable Pools

LPs in more stable pools, such as a stablecoin-to-stablecoin pair, will rarely need to provide liquidity outside of a very narrow range. For this reason, most LPs will provide liquidity at the lowest tier of 0.01%, because of the tick size and the nature of ... *stable*coins. Uniswap v2 and most other DEXs' stablecoin pools are effectively providing liquidity in an infinite range for a pool like USDC/USDT. Inefficiency aside, however, if a stablecoin begins to depeg more than 5% and continues to deviate, then we've got much bigger problems.

If the bulk of Luna's UST liqudity was on capital efficient DEXs, UST would have stood a much better chance at surviving its depegging death spiral. Not because the liquidity would have been much more concentrated near the peg (though it certainly helps), but because outside a certain range there would have been little to no liquidity left for the massive sell-offs. Interesting case to ponder.

A single pool of $25m held in a UST/USDC pair would have had the liquidity depth equivalent to $5*billion* concentrated between 0.99 — 1.01. If we break it down further, a $25m pool concentrated into the 0.999 - 1.001 range would have provided the same depth as $50*billion.*

Forge is currently capable of capital efficiency gains at 4000x from our non-concentrated counterparts. However, the Uniswap v3 pool factory is technically capable of supporting ranges as granular as 0.02%, translating to a maximum 20,000x capital efficiency gains relative to v2. Now that's efficiency.

## Liquid Staked Evmos as Base Currency

Forge and Evmos is currently in a very unique position as the **first and only** Uniswap v3 DEX that's implemented an LSD of the native chain asset to serve as the base currency for the DEX. You might have wondered why our pools seemed to be so focused on liquid staked assets - it was intended and by design!

### Significance for the Evmos Network

As a layer-1 chain that uses Tendermint and Cosmos SDK, staking is in our blood. And we mean business when it comes to staking - our native staking APR is one of the highest in the Cosmos ecosystem, and will continue to be considered extremely high even after the halvening that is due shortly. There are some problems *as well as opportunities* that arise from our above-average emission rates, and everyone will have different opinions on the right path forward. However, when it comes to liquidity providing and staking, we're pretty certain that much of the network stakeholders, community members, and daily users are struggling to find the right balance of native staking and participating in Evmos DeFi.

### Capital Efficiency on Steroids

With Forge, you can don't have to choose between staking rewards and liquidity rewards. When you provide liquidity on Forge with LSDs (stEVMOS, stATOM, etc.), you accrue staking rewards while earning fees and future incentives. The stEVMOS/EVMOS ratio is constantly changing to reflect staking rewards, which means that Forge will be a very attractive hunting ground for arbitrage bots and opportunity seekers.

This constant changing of the stEVMOS and EVMOS pair ratio will play a crucial role in various ways:

---

[^1]: Tick interval refers to the area of price space between two nearest active ticks
5 changes: 4 additions & 1 deletion pages/resources/concepts/concentrated-liquidity.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ title: Concentrated Liquidity
sidebar_position: 1
---

## Introduction
## Introduction to Concentrated Liquidity

<img src="/animations/concentrated-liquidity.webp" class="w-full mt-8"/>

The defining idea of Uniswap v3 is concentrated liquidity: liquidity that is allocated within a custom price range.
In earlier versions, liquidity was distributed uniformly along the price curve between 0 and infinity.
Expand All @@ -15,6 +17,7 @@ Consider stablecoin pairs, where the relative price of the two assets stays rela

With v3, liquidity providers may concentrate their capital to smaller price intervals than (0, ∞). In a stablecoin/stablecoin pair, for example, an LP may choose to allocate capital solely to the 0.99 - 1.01 range. As a result, traders are offered deeper liquidity around the mid-price, and LPs earn more trading fees with their capital. We call liquidity concentrated to a finite interval a position. LPs may have many different positions per pool, creating individualized price curves that reflect the preferences of each LP.


## Active Liquidity

As the price of an asset rises or falls, it may exit the price bounds that LPs have set in a position. When the price exits a position's interval, the position's liquidity is no longer active and no longer earns fees.
Expand Down
Loading

0 comments on commit 97a6d6c

Please sign in to comment.