mirror of
				https://github.com/Instadapp/dsa-resolvers-deprecated.git
				synced 2024-07-29 22:38:16 +00:00 
			
		
		
		
	Merge pull request #23 from Instadapp/Gelato-Uniswap-v3-pool
add Gelato Uniswap v3 resolver
This commit is contained in:
		
						commit
						ce22635739
					
				
							
								
								
									
										244
									
								
								contracts/protocols/mainnet/GelatoUniV3pool.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										244
									
								
								contracts/protocols/mainnet/GelatoUniV3pool.sol
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,244 @@ | |||
| pragma solidity ^0.6.0; | ||||
| pragma experimental ABIEncoderV2; | ||||
| 
 | ||||
| 
 | ||||
| interface IERC20 { | ||||
|     function balanceOf(address) external view returns (uint256); | ||||
|     function totalSupply() external view returns (uint256); | ||||
|     function decimals() external view returns (uint256); | ||||
| } | ||||
| 
 | ||||
| interface IUniswapV3Pool { | ||||
| 
 | ||||
|     function slot0() | ||||
|         external | ||||
|         view | ||||
|         returns ( | ||||
|             uint160 sqrtPriceX96, | ||||
|             int24 tick, | ||||
|             uint16 observationIndex, | ||||
|             uint16 observationCardinality, | ||||
|             uint16 observationCardinalityNext, | ||||
|             uint8 feeProtocol, | ||||
|             bool unlocked | ||||
|         ); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| interface IGUniPool { | ||||
|     function token0() external view returns (IERC20); | ||||
| 
 | ||||
|     function token1() external view returns (IERC20); | ||||
| 
 | ||||
|     function pool() external view returns (IUniswapV3Pool); | ||||
| 
 | ||||
|     function totalSupply() external view returns (uint256); | ||||
| 
 | ||||
|     function balanceOf(address account) external view returns (uint256); | ||||
| 
 | ||||
|     function getMintAmounts(uint256 amount0Max, uint256 amount1Max) | ||||
|         external | ||||
|         view | ||||
|         returns ( | ||||
|             uint256 amount0, | ||||
|             uint256 amount1, | ||||
|             uint256 mintAmount | ||||
|         ); | ||||
| 
 | ||||
|     function getPositionID() external view returns (bytes32 positionID); | ||||
| 
 | ||||
|     function lowerTick() external view returns (int24); | ||||
| 
 | ||||
|     function upperTick() external view returns (int24); | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| interface GUniResolver { | ||||
| 
 | ||||
|     function getPoolUnderlyingBalances(IGUniPool pool) | ||||
|         external | ||||
|         view | ||||
|         returns (uint256 amount0, uint256 amount1); | ||||
| 
 | ||||
|     function getUnderlyingBalances( | ||||
|         IGUniPool pool, | ||||
|         uint256 balance | ||||
|     ) external view returns (uint256 amount0, uint256 amount1); | ||||
| 
 | ||||
|     function getRebalanceParams( | ||||
|         IGUniPool pool, | ||||
|         uint256 amount0In, | ||||
|         uint256 amount1In, | ||||
|         uint16 slippageBPS | ||||
|     ) external view returns ( | ||||
|         bool zeroForOne, | ||||
|         uint256 swapAmount, | ||||
|         uint160 swapThreshold | ||||
|     ); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| struct StakingRewardsInfo { | ||||
|     address stakingRewards; | ||||
|     uint rewardAmount; | ||||
| } | ||||
| interface StakingFactoryInterface { | ||||
| 
 | ||||
|     function stakingRewardsInfoByStakingToken(address) external view returns(StakingRewardsInfo memory); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| interface StakingInterface { | ||||
|     function totalSupply() external view returns (uint256); | ||||
|     function rewardRate() external view returns (uint256); | ||||
|     function balanceOf(address account) external view returns (uint256); | ||||
|     function earned(address account) external view returns (uint256); | ||||
|     function rewardPerToken() external view returns (uint256); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| contract DSMath { | ||||
| 
 | ||||
|     function add(uint x, uint y) internal pure returns (uint z) { | ||||
|         require((z = x + y) >= x, "math-not-safe"); | ||||
|     } | ||||
| 
 | ||||
|     function mul(uint x, uint y) internal pure returns (uint z) { | ||||
|         require(y == 0 || (z = x * y) / y == x, "math-not-safe"); | ||||
|     } | ||||
| 
 | ||||
|     uint constant WAD = 10 ** 18; | ||||
| 
 | ||||
|     function wmul(uint x, uint y) internal pure returns (uint z) { | ||||
|         z = add(mul(x, y), WAD / 2) / WAD; | ||||
|     } | ||||
| 
 | ||||
|     function wdiv(uint x, uint y) internal pure returns (uint z) { | ||||
|         z = add(mul(x, WAD), y / 2) / y; | ||||
|     } | ||||
| 
 | ||||
|     function sub(uint x, uint y) internal pure returns (uint z) { | ||||
|         require((z = x - y) <= x, "ds-math-sub-underflow"); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| contract Helpers is DSMath { | ||||
| 
 | ||||
|     StakingFactoryInterface public constant getStakingFactory = StakingFactoryInterface(0xf39eC5a471edF20Ecc7db1c2c34B4C73ab4B2C19); | ||||
|     GUniResolver public constant gelatoRouter = GUniResolver(0xC8b92036cf2bfc5aD2116c9b9Fb3cee2d3b3dc89); | ||||
| 
 | ||||
|     struct UserData { | ||||
|         address pool; // address of pool contract | ||||
|         address staking; // address of staking contract | ||||
|         address token0Addr; // address of token 0 | ||||
|         address token1Addr; // address of token 1 | ||||
|         uint poolTokenSupply; // Total supply of Pool token | ||||
|         uint poolToken0Bal; // balance of total pool for token0 | ||||
|         uint poolToken1Bal; // balance of total pool for token1 | ||||
|         uint poolTokenSupplyStaked; // total pool token locked in staking contract | ||||
|         uint stakingToken0Bal; // total balance of token0 in Staking | ||||
|         uint stakingToken1Bal; // total balance of token1 in Staking | ||||
|         uint rewardRate; // INST distributing per second | ||||
|         uint token0Bal; // balance of token 0 of user | ||||
|         uint token1Bal; // balance of token 1 of user | ||||
|         uint earned; // INST earned from staking | ||||
|         uint stakedBal; // user's pool token bal in staking contract | ||||
|         uint poolBal; // ideal pool token in user's DSA | ||||
|         uint totalBal; // stakedBal + poolTknBal | ||||
|         uint token0Decimals; // token0 decimals | ||||
|         uint token1Decimals; // token1 decimals | ||||
|         int24 currentTick; // Current price of 1 token w.r.t to other | ||||
|         int24 lowerTick; // Price of 1 token w.r.t to other at lower tick | ||||
|         int24 upperTick; // Price of 1 token w.r.t to other at upper tick | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| contract Resolver is Helpers { | ||||
| 
 | ||||
|     function getSinglePosition(address user, address pool) public view returns(UserData memory _data) { | ||||
|         _data.pool = pool; | ||||
|         StakingInterface stakingContract = StakingInterface(getStakingFactory.stakingRewardsInfoByStakingToken(pool).stakingRewards); | ||||
|         _data.staking = address(stakingContract); | ||||
|         IGUniPool poolContract = IGUniPool(pool); | ||||
|         _data.token0Addr = address(poolContract.token0()); | ||||
|         _data.token1Addr = address(poolContract.token1()); | ||||
|         if (_data.staking == address(0)) { | ||||
|             _data.earned = 0; | ||||
|             _data.stakedBal = 0; | ||||
|         } else { | ||||
|             _data.earned = stakingContract.earned(user); | ||||
|             _data.stakedBal = stakingContract.balanceOf(user); | ||||
|         } | ||||
|         _data.poolBal = poolContract.balanceOf(user); | ||||
|         _data.totalBal = add(_data.stakedBal, _data.poolBal); | ||||
|         (_data.token0Bal, _data.token1Bal) = gelatoRouter.getUnderlyingBalances(poolContract, _data.totalBal); | ||||
|         _data.poolTokenSupply = poolContract.balanceOf(user); | ||||
|         (_data.poolToken0Bal, _data.poolToken1Bal) = gelatoRouter.getPoolUnderlyingBalances(poolContract); | ||||
|         _data.poolTokenSupplyStaked = stakingContract.totalSupply(); | ||||
|         (_data.stakingToken0Bal, _data.stakingToken1Bal) = gelatoRouter.getUnderlyingBalances(poolContract, _data.poolTokenSupplyStaked); | ||||
|         _data.rewardRate = stakingContract.rewardRate(); | ||||
| 
 | ||||
|         _data.token0Decimals = poolContract.token0().decimals(); | ||||
|         _data.token1Decimals = poolContract.token1().decimals(); | ||||
| 
 | ||||
|         IUniswapV3Pool uniNft = poolContract.pool(); | ||||
|         (, _data.currentTick, , , , , ) = uniNft.slot0(); | ||||
|         _data.lowerTick = poolContract.lowerTick(); | ||||
|         _data.upperTick = poolContract.upperTick(); | ||||
|     } | ||||
| 
 | ||||
|     function getPosition(address user, address[] memory pools) public view returns(UserData[] memory _data) { | ||||
|         _data = new UserData[](pools.length); | ||||
|         for (uint i = 0; i < pools.length; i++) { | ||||
|             _data[i] = getSinglePosition(user, pools[i]); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|     * @param pool - gelato pool address. | ||||
|     * @param amount0In - amount of token0 user wants to deposit. | ||||
|     * @param amount1In - amount of token1 user wants to deposit. | ||||
|     * @param slippage in 18 decimal where 100% = 1e18. | ||||
|     * @return zeroForOne - if true swap token0 for token1 else vice versa | ||||
|     * @return swapAmount - Amount of tokens to swap. | ||||
|     * @return swapThreshold - Max slippage that the swap can take. | ||||
|     */ | ||||
|     function getSwapAndDepositParams( | ||||
|         address pool,  | ||||
|         uint amount0In, | ||||
|         uint amount1In, | ||||
|         uint slippage | ||||
|     ) public view returns ( | ||||
|         bool zeroForOne, | ||||
|         uint256 swapAmount, | ||||
|         uint160 swapThreshold | ||||
|     ) { | ||||
|         uint slippageBPS = slippage / 1e16; | ||||
|         (zeroForOne, swapAmount, swapThreshold) = gelatoRouter.getRebalanceParams(IGUniPool(pool), amount0In, amount1In, uint16(slippageBPS)); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param user - address of user. | ||||
|      * @param pool - address of Gelato Pool. | ||||
|      * @param burnPercent - in 18 decimal where 100% = 1e18. | ||||
|      * @param slippage in 18 decimal where 100% = 1e18. | ||||
|      * @return burnAmt - Amount of pool tokens to burn. | ||||
|      * @return amount0 - Amount of token0 user will get. | ||||
|      * @return amount1 - Amount of token1 user will get. | ||||
|      * @return amount0Min - Min amount of token0 user should get. | ||||
|      * @return amount1Min - Min amount of token1 user should get. | ||||
|     */ | ||||
|     function getWithdrawParams(address user, address pool, uint burnPercent, uint slippage) public view returns (uint burnAmt, uint amount0, uint amount1, uint amount0Min, uint amount1Min) { | ||||
|         UserData memory _data = getSinglePosition(user, pool); | ||||
|         burnPercent = burnPercent > 1e18 ? 1e18 : burnPercent; | ||||
|         burnAmt = wmul(_data.totalBal, burnPercent); | ||||
|         amount0 = wmul(_data.token0Bal, burnPercent); | ||||
|         amount1 = wmul(_data.token1Bal, burnPercent); | ||||
|         amount0Min = wmul(amount0, sub(1e18, slippage)); | ||||
|         amount1Min = wmul(amount1, sub(1e18, slippage)); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Samyak Jain
						Samyak Jain