An open API service indexing awesome lists of open source software.

https://github.com/clean-423/amm-tswap

Automated Market Maker(AMM) based on Constant Pricing Model
https://github.com/clean-423/amm-tswap

amm-dex audit automated-market-maker decentralized-exchange defi dex smart-contract solidity

Last synced: 7 months ago
JSON representation

Automated Market Maker(AMM) based on Constant Pricing Model

Awesome Lists containing this project

README

          

# TSwap Audit
- [Audit Report](#audit-report)
- [Diagram](#diagram)
- [What's TSwap?](#whats-tswap)
- [TSwap Pools](#tswap-pools)
- [Liquidity Providers](#liquidity-providers)
- [Why would I want to add tokens to the pool?](#why-would-i-want-to-add-tokens-to-the-pool)
- [LP Example](#lp-example)
- [Core Invariant - Math behind AMM](#core-invariant-math-behind-amm)
- [Make a swap](#make-a-swap)

## Audit Report

[Audit-Report-HERE](./audit-data/report.pdf)

## Diagram

![t-swap](./images/diagrams/t-swap-with-factory.png)

## What's TSwap?

This project is meant to be a permissionless way for users to swap assets between each other at a fair price. You can think of T-Swap as a decentralized asset/token exchange (DEX).
T-Swap is known as an [Automated Market Maker (AMM)](https://chain.link/education-hub/what-is-an-automated-market-maker-amm) because it doesn't use a normal "order book" style exchange, instead it uses "Pools" of an asset.

## TSwap Pools

The protocol starts as simply a `PoolFactory` contract. This contract is used to create new "pools" of tokens. It helps make sure every pool token uses the correct logic. But all the magic is in each `TSwapPool` contract.

You can think of each `TSwapPool` contract as it's own exchange between exactly 2 assets. Any ERC20 and the [WETH](https://etherscan.io/token/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2) token. These pools allow users to permissionlessly swap between an ERC20 that has a pool and WETH. Once enough pools are created, users can easily "hop" between supported ERC20s.

![t-swap](./images/diagrams/tswap-basic.png)

For example:
1. User A has 10 USDC
2. They want to use it to buy DAI
3. They `swap` their 10 USDC -> WETH in the USDC/WETH pool
4. Then they `swap` their WETH -> DAI in the DAI/WETH pool

Every pool is a pair of `TOKEN X` & `WETH`.

There are 2 functions users can call to swap tokens in the pool.
- `swapExactInput`
- `swapExactOutput`

We will talk about what those do in a little.

## Liquidity Providers

![with-lps](images/diagrams/liquidity-providers.png)

In order for the system to work, users have to provide liquidity, aka, "add tokens into the pool".

### Why would I want to add tokens to the pool?
The TSwap protocol accrues fees from users who make swaps. Every swap has a `0.3` fee, represented in `getInputAmountBasedOnOutput` and `getOutputAmountBasedOnInput`. Each applies a `997` out of `1000` multiplier. That fee stays in the protocol.

When you deposit tokens into the protocol, you are rewarded with an LP token. You'll notice `TSwapPool` inherits the `ERC20` contract. This is because the `TSwapPool` gives out an ERC20 when Liquidity Providers (LP)s deposit tokens. This represents their share of the pool, how much they put in. When users swap funds, 0.03% of the swap stays in the pool, netting LPs a small profit.

### LP Example
1. LP A adds 1,000 WETH & 1,000 USDC to the USDC/WETH pool
- They gain 1,000 LP tokens
2. LP B adds 500 WETH & 500 USDC to the USDC/WETH pool
- They gain 500 LP tokens
3. There are now 1,500 WETH & 1,500 USDC in the pool
4. User A swaps 100 USDC -> 100 WETH.
- The pool takes 0.3%, aka 0.3 USDC.
- The pool balance is now 1,400.3 WETH & 1,600 USDC
- aka: They send the pool 100 USDC, and the pool sends them 99.7 WETH

Note, in practice, the pool would have slightly different values than 1,400.3 WETH & 1,600 USDC due to the math below.

## Core Invariant (Math behind AMM)

Our system works because the ratio of Token A & WETH will always stay the same. Well, for the most part. Since we add fees, our invariant technially increases.

![uniswap-delta-x](images/diagrams/uniswap-delta-x.png)

`x * y = k`
- x = Token Balance X
- y = Token Balance Y
- k = The constant ratio between X & Y

```javascript
y = Token Balance Y
x = Token Balance X
x * y = k
x * y = (x + ∆x) * (y − ∆y)
∆x = Change of token balance X
∆y = Change of token balance Y
β = (∆y / y)
α = (∆x / x)

Final invariant equation without fees:
∆x = (β/(1-β)) * x
∆y = (α/(1+α)) * y

Invariant with fees
ρ = fee (between 0 & 1, aka a percentage)
γ = (1 - p) (pronounced gamma)
∆x = (β/(1-β)) * (1/γ) * x
∆y = (αγ/1+αγ) * y
```

Our protocol should always follow this invariant in order to keep swapping correctly!

## Make a swap

![amm-basic](images/diagrams/amm-basic.png)

After a pool has liquidity, there are 2 functions users can call to swap tokens in the pool.
- `swapExactInput`
- `swapExactOutput`

A user can either choose exactly how much to input (ie: I want to use 10 USDC to get however much WETH the market says it is), or they can choose exactly how much they want to get out (ie: I want to get 10 WETH from however much USDC the market says it is.