Skip to content

Commit

Permalink
Add mermaid diagrams to README & other small tweaks
Browse files Browse the repository at this point in the history
  • Loading branch information
wildmolasses authored and apbendi committed Feb 21, 2024
1 parent df81191 commit 7922ea5
Showing 1 changed file with 48 additions and 4 deletions.
52 changes: 48 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
# UniStaker

<div align="center">
<img width="500" src="readme/unistaker.webp" alt="Delegated Liquidity Banner">
<img width="500" src="readme/unistaker.webp" alt="UniStaker Banner">
<br />
</div>

<p align="center">
<b>Uniswap V3 protocol fee collection and distribution via UNI staking.</b>
</p>


## What it does

This repository contains contracts which allow Uniswap Governance to enable and manage protocol fees on Uniswap V3. If Uniswap Governance chooses to upgrade to these contracts, it will retain the right to set protocol fees on Uniswap V3 Pools but it will not control the fee assets themselves. Instead, the revenue generated by the fees is trustlessly distributed to those UNI holders who choose to delegate and stake their tokens.
Expand All @@ -32,18 +31,63 @@ The staking system allows for other contracts to be added as revenue sources for

The system consists of two core contracts which are designed to be deployed into, and interact with, the existing ecosystem of Uniswap contracts operating onchain. The two new contracts are `V3FactoryOwner.sol` and the `UniStaker.sol`. The former manages ownership of the existing Uniswap V3 Factory contract, while the latter manages staking mechanics and the distribution of rewards to stakers.

```mermaid
flowchart TD
A[Uniswap Governance] -->|"
Can set fees on specific pools
Can not collect fees
Can not transfer ownership
"| A1[V3FactoryOwner]:::new
A1 --> B["Uniswap V3 Factory"]
B --> C[(Pool 1)]
B --> D[(Pool 2)]
B --> E[...]
style E fill:transparent,stroke:transparent,stroke-width:4px
classDef new stroke:#F7F,padding:10px,stroke-width:3px,line-height:3.5,font-weight:bold
B --> F[(Pool N)]
B ..-> |"Collect fees on fee-enabled pools via V3FactoryOwner.claimFees"|A1
A1 ..-> |"Rewards immediately deposited into UniStaker"|GG[UniStaker]:::new
G((UNI holders)) --> |"
Delegate and stake UNI to
earn rewards from fee-enabled pools
"|GG
G ---> |Vote on governance proposals|A
M((MEV searcher)) <..-> |"Collect fees by sending WETH
to be used as rewards"|A1
```

### `V3FactoryOwner`

The [`V3FactoryOwner`](src/V3FactoryOwner.sol) contract is designed to act as the owner of the Uniswap V3 Factory. Governance can opt to transfer ownership of the factory to an instance of this contract. While the owner of the factory becomes the `V3FactoryOwner`, the admin of the `V3FactoryOwner` will be governance. In this way, governance retains the right to configure pool protocol fees via permissioned passthrough methods.

The `V3FactoryOwner` has a public method which enables *anyone* to claim the protocol fees which have accrued for a given pool. In order to claim the fees, the caller must pay a fixed amount of a token defined when the `V3FactoryOwner` is deployed (the `PAYOUT_TOKEN`). This sets up a continuous "race" wherein external parties will compete to claim the fees accrued by each pool once it becomes profitable to do so.
The `V3FactoryOwner` has a public method which enables _anyone_ to claim the protocol fees which have accrued for a given pool. In order to claim the fees, the caller must pay a fixed amount of a token defined when the `V3FactoryOwner` is deployed (the `PAYOUT_TOKEN`). This sets up a continuous "race" wherein external parties will compete to claim the fees accrued by each pool once it becomes profitable to do so.

Concretely, if the `PAYOUT_TOKEN` was WETH, a third party would claim a pool's fees by paying for them in WETH, which would be sent to the staking contract for distribution to stakers.

### `UniStaker`

The mechanics of the [`UniStaker`](src/UniStaker.sol) contract are heavily inspired by the Synthetix [`StakingRewards.sol`](https://github.com/Synthetixio/synthetix/blob/develop/contracts/StakingRewards.sol) implementation. The contract manages the distribution of rewards to stakers by dripping those rewards out over a fixed period of time. This period restarts if more rewards are distributed (e.g. by the public fee claiming mechanism on `V3FactoryOwner` detailed above). This Synthetix style staking mechanism has been widely discussed in the DeFi ecosystem and should be reviewed by any party seeking to understand the mechanics of UniStaker.

```mermaid
flowchart LR
A[UniStaker] --> |"Hold deposit tokens and
delegate on behalf of depositor"|SurrogateFork
SurrogateFork --> |Yes|Surrogate["Surrogate contract for delegate
(Holds stake deposits, delegates
to delegate address)"]
SurrogateFork --> |"No, deploy new surrogate"|Surrogate
A1((UNI holder)) --> |"Stake UNI
Withdraw UNI"|A
A .-> |Earns rewards|B(("Beneficiary
(original holder or
other address)"))
SurrogateFork{{"Was a surrogate contract previously
deployed for this delegate?"}}
```

The UniStaker contract diverges from `StakingRewards.sol` in several ways:

First, UniStaker enfranchises depositors by allowing them to retain their UNI governance rights. It does this by depositing staked tokens to an instance of [`DelegationSurrogate`](src/DelegationSurrogate.sol), a dummy contract whose sole purpose is to delegate voting weight to a designated entity. UniStaker requires stakers to delegate to themselves or another address. They cannot delegate to the zero address.
Expand All @@ -60,7 +104,7 @@ Finally, UniStaker is designed to accept rewards from any number of addresses de

These contracts were built and tested with care by the team at [ScopeLift](https://scopelift.co).

### Build and test
### Build and test

This project uses [Foundry](https://github.com/foundry-rs/foundry). Follow [these instructions](https://github.com/foundry-rs/foundry#installation) to install it.

Expand Down

0 comments on commit 7922ea5

Please sign in to comment.