Try   HackMD

Uniswap V3 Strategies Code Review

The following strategies are reviewed:

  • Charm Finance
  • Visor Finance

Visor Finance

GitHub Org: https://github.com/VisorFinance

Smart Contracts Repo: private

ETH-USDT Hypervisor: https://etherscan.io/address/0xa08583b36a809934e019574695392b516be9354f

Terminology

  • Hypervisor: They call Vaults or Rebalancer contract as a Hypervisor.

Factory (Etherscan)

  • There is only one imp function called createHypervisor() which allows owner (or governance) to deploy a new Hypervisor.
  • There cannot be two separate Hypervisor contracts for a single Uniswap Pool.
  • While deploying, the owner specifies these initial parameters:
    • Base Lower Tick
    • Base Upper Tick
    • Limit Lower Tick
    • Limit Upper Tick
  • Worth noting that these above names are also present in Charm Finance strategy too.

Hypervisor (Etherscan)

This linked etherscan link is of ETH-USDT 0.3% Pool.

  • When deployed, it sets infinite deposit limit and penalty percent as 2.
  • This contract maintains a whitelist, which allows only certain addresses to use the deposit function.
  • The deposit function:
    • It accepts user deposits in any proportion.
    • To bring the pool into 50-50 asset value proportion, depositors are penalized by 2% for a part of their asset that worsens the proportion.
    • If user's deposit propotion helps to balance the pool then they are not penalized.
    • Whenever anyone deposits, the fees are updated, which increases the share price.
  • Rebalance:
    • It is performed by owner address.
    • The owner manually specifies the base ticks and limit ticks. As well as quantity of tokens to swap into other if required.
    • Fees are claimed.
    • Then the two positions: base and limit are closed.
    • And new base position is created with maximum possible liquidity.
    • If there is any asset remaining then a limit order can be used to create it.
  • Withdraw:
    • The function withdraws partial liquidity from the pool.

Final Comments

  • The rebalance is pretty much manual, a stregist decides on the base ticks and limit ticks. The market conditions may change slightly.
  • Deposit function does not add liquidity on deposit. But withdraw function always withdraws liquidity from the pool. This is not capital efficient as well as vulnerable to this attack vector: A user takes flash loan, deposits and then withdraws. The attacker does not gain anything but majority of liquidity (99.99%) can be moved from uniswap pool to the hypervisor contract keeping it unused until the next rebalance, hence preventing users from making profit.
  • The owner has ability to completely rug the users using the function emergencyWithdraw().
  • The source code is not made public on GitHub. (Though it seems like a private beta testing).

Charm Finance

GitHub Repo: https://github.com/charmfinance/alpha-vaults-contracts/

Contracts:

  • Alpha Vault
  • Alpha Strategy

Alpha Vault (code, etherscan)

A lot of code from Visor is similar to Charm's code. Given that Charm has been public since the start, Visor likely copied this code. Also charm's code is better readable.

  • The deposit function
    • User can only deposit in the vault's proportion of vault's current holdings.
    • Whenever anyone deposits, the fees are updated, which increases the share price.
  • Rebalance
    • The function is only callable by strategy contract, which dynamically calculates values of base and limit ticks.
    • It keeps aside 5% of fees as protocol fees. Doesn't immediately send to some address. There is another function which allows governance to claim the fees.
  • Withdraw
    • Withdraws partial liquidity from pool

Alpha Strategy (code)

  • This contract is used to dynamically calculate the base and limit ticks.
  • Owner/Governance sets some parameters: baseThreshold, limitThreshold, maxTwapDeviation, twapDuration.
  • A keeper address is allowed to call the rebalance function
  • The rebalance function is explained well in this medium blog post.

Final Comments

  • It seems that same vector still lies in deposit and withdraw contracts of Charm too. Though no funds at risk.
  • Visor copied only the Alpha Vaults code from Charm
  • Charm's contracts also have the emergency methods, but there is also a functionality of renouncing those emergency controls.
  • The governance address is a private key wallet (charmfinance.eth).