Important: There are two source code repositories for the project: https://github.com/opz/DALP-core and https://github.com/opz/DALP-frontend. The source code link will only show you the smart contract code. The problem: Adding liquidity to Uniswap to earn fees is not as simple as lending money on Compound or Aave. You need the correct proportions of each asset to start, and moving from one Uniswap pair to another that is generating more fees is especially time consuming. Today, this requires you pull out liquidity, swap to new assets, try to get the correct proportions of those assets, add new liquidity, and then deal with all the token dust left behind. Zapper can help with some of this for Uniswap v1, but not v2. Regardless, you would still need to monitor your liquidity and manually invest in a different token pair if it starts generating better fees. The solution: The Decentralized Autonomous Liquidity Provider, or DALP, solves all these problems. A user simply buys DALP tokens and the DALP manages their liquidity for them, always seeking the Uniswap pairs that can generate the most fees. How it works: The DALP contract performs on-chain calculations to rate Uniswap pairs by their ability to generate fees. This is done by comparing the percent growth of a pair’s square rooted k value to the total notional value of the pair’s reserves. The notional value is calculated using the new Uniswap v2 oracles. In theory this tells us which pairs generate the most fees for the least liquidity. When a user purchases DALP tokens, the ether they spend is added to the liquidity managed by the DALP. This liquidity is swapped to the appropriate tokens so the DALP can add it to the highest rated pair. If the DALP discovers a new pair that has a higher rating, it will remove its liquidity from the old pair and swap to the tokens required for the new pair. When a user wants to cash out, they can redeem their DALP tokens. An amount of liquidity is removed from the active Uniswap pair that is proportional to the number of DALP tokens redeemed and the tokens are swapped to ETH before being transferred to the user. The risks: Impermanent loss is always a risk when adding liquidity to AMM exchanges and the DALP faces the same risk. We want to explore ways to hedge against that risk with techniques such as depositing Uniswap share tokens as collateral on Aave to borrow stablecoins the DALP can use to purchase other assets such as leveraged longs, shorts, or options. How it benefits Uniswap: With some refactoring polish, a number of the functions developed for the DALP can be broken out into useful standalone periphery contracts that could benefit others trying to develop on top of Uniswap. These functions are built on top of the UniswapV2Router01 and UniswapV2Library. They simplify the process of adding liquidity from a single balance of ether as well as simplify certain types of swaps. Where we are going: In addition to supporting more protocols, we want to improve the DALP’s decentralization. Right now there are a couple of function calls that require a contract owner and we believe we can completely eliminate the need for an owner at all. Because we were able to perform our rating calculations on-chain, we believe the DALP could be capable of operating truly autonomously, with zero or at most very minimal governance. With some extra work, the DALP could exist completely independent and immutable, with no external entity in control.
How It's Made
Smart contract stack: - Solidity - Buidler - Waffle - Ethers.js - Uniswap v2 periphery contracts - OpenZeppelin contracts Frontend stack: - React - Web3Modal - MetaMask The DALP is comprised of three contracts, the DALP ERC-20 token, the DALPManager, and the OracleManager. The DALPManager issues DALP tokens to users and adds liquidity to Uniswap v2 pairs. The OracleManager uses Uniswap v2 oracles to price tokens on behalf of the DALPManager. A function of particular interest in the DALPManager is _getUniswapV2PairRating(IUniswapV2Pair pair). This is the function that rates a Uniswap v2 pair based on its ability to generate fees. The function reallocateLiquidity() will move all liquidity to the pair with the highest rating.