--- tags: protodao --- # 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](https://etherscan.io/address/0xaaCd0b4B321327B6D9EEc4Ed6F09D640CE218200#code)) - 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](https://etherscan.io/address/0xa08583b36a809934e019574695392b516be9354f#code)) 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](https://github.com/charmfinance/alpha-vaults-contracts/blob/main/contracts/AlphaVault.sol), [etherscan](https://etherscan.io/address/0x55535c4c56f6bf373e06c43e44c0356aafd0d21a#code)) 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](https://github.com/charmfinance/alpha-vaults-contracts/blob/main/contracts/AlphaStrategy.sol)) - 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](https://medium.com/charmfinance/introducing-alpha-vaults-an-lp-strategy-for-uniswap-v3-ebf500b67796). #### 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).