From e67c5dcfd40eee24b5be983cd83ecd991303318c Mon Sep 17 00:00:00 2001 From: TechnoGeek01 Date: Thu, 2 Nov 2023 17:57:41 +0530 Subject: [PATCH] modularized sushi v3 and uni v3 codes --- contracts/sushiswapV3/Demeter_SushiV3Farm.sol | 233 ------------------ .../sushiswapV3/tests/SushiswapV3Test.sol | 55 ----- ...emeter_UniV3Farm.sol => BaseUniV3Farm.sol} | 35 ++- .../sushiswap/Demeter_SushiV3Farm.sol | 33 +++ .../Demeter_SushiV3FarmDeployer.sol | 19 +- contracts/uniswapV3/tests/UniswapV3Test.sol | 19 +- .../uniswapV3/uniswap/Demeter_UniV3Farm.sol | 33 +++ .../Demeter_UniV3FarmDeployer.sol | 2 +- 8 files changed, 107 insertions(+), 322 deletions(-) delete mode 100644 contracts/sushiswapV3/Demeter_SushiV3Farm.sol delete mode 100644 contracts/sushiswapV3/tests/SushiswapV3Test.sol rename contracts/uniswapV3/{Demeter_UniV3Farm.sol => BaseUniV3Farm.sol} (89%) create mode 100644 contracts/uniswapV3/sushiswap/Demeter_SushiV3Farm.sol rename contracts/{sushiswapV3 => uniswapV3/sushiswap}/Demeter_SushiV3FarmDeployer.sol (82%) create mode 100644 contracts/uniswapV3/uniswap/Demeter_UniV3Farm.sol rename contracts/uniswapV3/{ => uniswap}/Demeter_UniV3FarmDeployer.sol (97%) diff --git a/contracts/sushiswapV3/Demeter_SushiV3Farm.sol b/contracts/sushiswapV3/Demeter_SushiV3Farm.sol deleted file mode 100644 index 01b09d03..00000000 --- a/contracts/sushiswapV3/Demeter_SushiV3Farm.sol +++ /dev/null @@ -1,233 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.16; - -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@// -//@@@@@@@@&....(@@@@@@@@@@@@@..../@@@@@@@@@// -//@@@@@@........../@@@@@@@........../@@@@@@// -//@@@@@............(@@@@@............(@@@@@// -//@@@@@(............@@@@@(...........&@@@@@// -//@@@@@@@...........&@@@@@@.........@@@@@@@// -//@@@@@@@@@@@@@@%..../@@@@@@@@@@@@@@@@@@@@@// -//@@@@@@@@@@@@@@@@@@@...@@@@@@@@@@@@@@@@@@@// -//@@@@@@@@@@@@@@@@@@@@@......(&@@@@@@@@@@@@// -//@@@@@@#.........@@@@@@#...........@@@@@@@// -//@@@@@/...........%@@@@@............%@@@@@// -//@@@@@............#@@@@@............%@@@@@// -//@@@@@@..........#@@@@@@@/.........#@@@@@@// -//@@@@@@@@@&/.(@@@@@@@@@@@@@@&/.(&@@@@@@@@@// -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@// - -import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; -import {INonfungiblePositionManager as INFPM, IUniswapV3Factory, IUniswapV3TickSpacing, CollectParams} from "../uniswapV3/interfaces/UniswapV3.sol"; -import {PositionValue} from "../uniswapV3/libraries/PositionValue.sol"; -import {BaseFarm, RewardTokenData} from "../BaseFarm.sol"; - -// Defines the sushiswap pool init data for constructor. -// tokenA - Address of tokenA -// tokenB - Address of tokenB -// feeTier - Fee tier for the sushiswap pool -// tickLowerAllowed - Lower bound of the tick range for farm -// tickUpperAllowed - Upper bound of the tick range for farm -struct SushiswapPoolData { - address tokenA; - address tokenB; - uint24 feeTier; - int24 tickLowerAllowed; - int24 tickUpperAllowed; -} - -contract Demeter_SushiV3Farm is BaseFarm, IERC721Receiver { - // constants - string public constant FARM_ID = "Demeter_SushiV3_v3"; - address public constant NFPM = 0xF0cBce1942A68BEB3d1b73F0dd86C8DCc363eF49; - address public constant SUSHIV3_FACTORY = - 0x1af415a1EbA07a4986a52B6f2e7dE7003D82231e; - - // SushiswapV3 params - int24 public tickLowerAllowed; - int24 public tickUpperAllowed; - address public sushiswapPool; - - event PoolFeeCollected( - address indexed recipient, - uint256 tokenId, - uint256 amt0Recv, - uint256 amt1Recv - ); - - // Custom Errors - error InvalidSushiswapPoolConfig(); - error NotASushiV3NFT(); - error NoData(); - error NoFeeToClaim(); - error IncorrectPoolToken(); - error IncorrectTickRange(); - error InvalidTickRange(); - - /// @notice constructor - /// @param _farmStartTime - time of farm start - /// @param _cooldownPeriod - cooldown period for locked deposits in days - /// @dev _cooldownPeriod = 0 Disables lockup functionality for the farm. - /// @param _sushiswapPoolData - init data for SushiswapV3 pool - /// @param _rwdTokenData - init data for reward tokens - function initialize( - uint256 _farmStartTime, - uint256 _cooldownPeriod, - SushiswapPoolData memory _sushiswapPoolData, - RewardTokenData[] memory _rwdTokenData - ) external initializer { - // initialize sushiswap related data - sushiswapPool = IUniswapV3Factory(SUSHIV3_FACTORY).getPool( - _sushiswapPoolData.tokenB, - _sushiswapPoolData.tokenA, - _sushiswapPoolData.feeTier - ); - if (sushiswapPool == address(0)) { - revert InvalidSushiswapPoolConfig(); - } - _validateTickRange( - _sushiswapPoolData.tickLowerAllowed, - _sushiswapPoolData.tickUpperAllowed - ); - tickLowerAllowed = _sushiswapPoolData.tickLowerAllowed; - tickUpperAllowed = _sushiswapPoolData.tickUpperAllowed; - - _setupFarm(_farmStartTime, _cooldownPeriod, _rwdTokenData); - } - - /// @notice Function is called when user transfers the NFT to the contract. - /// @param _from The address of the owner. - /// @param _tokenId nft Id generated by sushiswap v3. - /// @param _data The data should be the lockup flag (bool). - function onERC721Received( - address, // unused variable. not named - address _from, - uint256 _tokenId, - bytes calldata _data - ) external override returns (bytes4) { - if (msg.sender != NFPM) { - revert NotASushiV3NFT(); - } - if (_data.length == 0) { - revert NoData(); - } - uint256 liquidity = _getLiquidity(_tokenId); - // Validate the position and get the liquidity - - _deposit(_from, abi.decode(_data, (bool)), _tokenId, liquidity); - return this.onERC721Received.selector; - } - - /// @notice Function to lock a staked deposit - /// @param _depositId The id of the deposit to be locked - /// @dev _depositId is corresponding to the user's deposit - function initiateCooldown(uint256 _depositId) external nonReentrant { - _initiateCooldown(_depositId); - } - - /// @notice Function to withdraw a deposit from the farm. - /// @param _depositId The id of the deposit to be withdrawn - function withdraw(uint256 _depositId) external nonReentrant { - _isValidDeposit(msg.sender, _depositId); - Deposit memory userDeposit = deposits[msg.sender][_depositId]; - - _withdraw(msg.sender, _depositId, userDeposit); - // Transfer the nft back to the user. - INFPM(NFPM).safeTransferFrom( - address(this), - msg.sender, - userDeposit.tokenId - ); - } - - /// @notice Claim sushiswap pool fee for a deposit. - /// @dev Only the deposit owner can claim the fee. - /// @param _depositId Id of the deposit - function claimSushiswapFee(uint256 _depositId) external nonReentrant { - _farmNotClosed(); - _isValidDeposit(msg.sender, _depositId); - uint256 tokenId = deposits[msg.sender][_depositId].tokenId; - - INFPM pm = INFPM(NFPM); - (uint256 amt0, uint256 amt1) = PositionValue.fees(pm, tokenId); - if (amt0 == 0 && amt1 == 0) { - revert NoFeeToClaim(); - } - (uint256 amt0Recv, uint256 amt1Recv) = pm.collect( - CollectParams({ - tokenId: tokenId, - recipient: msg.sender, - amount0Max: uint128(amt0), - amount1Max: uint128(amt1) - }) - ); - emit PoolFeeCollected(msg.sender, tokenId, amt0Recv, amt1Recv); - } - - /// @notice Get the accrued sushiswap fee for a deposit. - /// @return amount0 The amount of token0 - /// @return amount1 The amount of token1 - function computeSushiswapFee(uint256 _tokenId) - external - view - returns (uint256 amount0, uint256 amount1) - { - // Validate token. - _getLiquidity(_tokenId); - return PositionValue.fees(INFPM(NFPM), _tokenId); - } - - /// @notice Validate the position for the pool and get Liquidity - /// @param _tokenId The tokenId of the position - /// @dev the position must adhere to the price ranges - /// @dev Only allow specific pool token to be staked. - function _getLiquidity(uint256 _tokenId) private view returns (uint256) { - /// @dev Get the info of the required token - ( - , - , - address token0, - address token1, - uint24 fee, - int24 tickLower, - int24 tickUpper, - uint128 liquidity, - , - , - , - - ) = INFPM(NFPM).positions(_tokenId); - - /// @dev Check if the token belongs to correct pool - - if ( - sushiswapPool != - IUniswapV3Factory(SUSHIV3_FACTORY).getPool(token0, token1, fee) - ) { - revert IncorrectPoolToken(); - } - - /// @dev Check if the token adheres to the tick range - if (tickLower != tickLowerAllowed || tickUpper != tickUpperAllowed) { - revert IncorrectTickRange(); - } - - return uint256(liquidity); - } - - function _validateTickRange(int24 _tickLower, int24 _tickUpper) - private - view - { - int24 spacing = IUniswapV3TickSpacing(sushiswapPool).tickSpacing(); - if ( - !(_tickLower < _tickUpper && - _tickLower >= -887272 && - _tickLower % spacing == 0 && - _tickUpper <= 887272 && - _tickUpper % spacing == 0) - ) { - revert InvalidTickRange(); - } - } -} diff --git a/contracts/sushiswapV3/tests/SushiswapV3Test.sol b/contracts/sushiswapV3/tests/SushiswapV3Test.sol deleted file mode 100644 index 260efa59..00000000 --- a/contracts/sushiswapV3/tests/SushiswapV3Test.sol +++ /dev/null @@ -1,55 +0,0 @@ -// This contract is for testing purpose (Arbitrum) -// SPDX-License-Identifier: UNLICENSED -pragma solidity 0.8.16; -pragma experimental ABIEncoderV2; - -import {SafeERC20, IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import {ISwapRouter} from "../../uniswapV3/tests/ISwapRouter.sol"; -import {INonfungiblePositionManager} from "../../uniswapV3/interfaces/UniswapV3.sol"; - -/** - * @title Token Swapping on SushiswapV3 Arbitrum - * @notice Sushiswap V3 is a fork of Uniswap V3 with some modifications so the below reference is still valid - * @dev reference: https://docs.uniswap.org/protocol/guides/swaps/single-swaps - * @author Sperax Foundation - */ -contract SushiswapV3Test { - using SafeERC20 for IERC20; - INonfungiblePositionManager public nonfungiblePositionManager = - INonfungiblePositionManager(0xF0cBce1942A68BEB3d1b73F0dd86C8DCc363eF49); - - ISwapRouter public constant SWAP_ROUTER = - ISwapRouter(0x8A21F6768C1f8075791D08546Dadf6daA0bE820c); - - event SwapTest( - address inputToken, - address outputToken, - uint256 amountIn, - uint256 amountOut - ); - - /** - * @notice swaps a fixed amount of inputToken for a maximum possible amount of outputToken on Sushiswap V3 - */ - function swap( - address inputToken, - address outputToken, - uint24 poolFee, - uint256 amountIn - ) external returns (uint256 amountOut) { - IERC20(inputToken).safeApprove(address(SWAP_ROUTER), amountIn); - ISwapRouter.ExactInputSingleParams memory params = ISwapRouter - .ExactInputSingleParams({ - tokenIn: inputToken, - tokenOut: outputToken, - fee: poolFee, - recipient: msg.sender, - amountIn: amountIn, - amountOutMinimum: 0, - sqrtPriceLimitX96: 0 - }); - // Executes the swap. - amountOut = SWAP_ROUTER.exactInputSingle(params); - emit SwapTest(inputToken, outputToken, amountIn, amountOut); - } -} diff --git a/contracts/uniswapV3/Demeter_UniV3Farm.sol b/contracts/uniswapV3/BaseUniV3Farm.sol similarity index 89% rename from contracts/uniswapV3/Demeter_UniV3Farm.sol rename to contracts/uniswapV3/BaseUniV3Farm.sol index c9b22d65..7477be36 100644 --- a/contracts/uniswapV3/Demeter_UniV3Farm.sol +++ b/contracts/uniswapV3/BaseUniV3Farm.sol @@ -36,12 +36,7 @@ struct UniswapPoolData { int24 tickUpperAllowed; } -contract Demeter_UniV3Farm is BaseFarm, IERC721Receiver { - // constants - string public constant FARM_ID = "Demeter_UniV3_v3"; - address public constant NFPM = 0xC36442b4a4522E871399CD717aBDD847Ab11FE88; - address public constant UNIV3_FACTORY = - 0x1F98431c8aD98523631AE4a59f267346ea31F984; +abstract contract BaseUniV3Farm is BaseFarm, IERC721Receiver { // UniswapV3 params int24 public tickLowerAllowed; @@ -77,7 +72,7 @@ contract Demeter_UniV3Farm is BaseFarm, IERC721Receiver { RewardTokenData[] memory _rwdTokenData ) external initializer { // initialize uniswap related data - uniswapPool = IUniswapV3Factory(UNIV3_FACTORY).getPool( + uniswapPool = IUniswapV3Factory(UNIV3_FACTORY()).getPool( _uniswapPoolData.tokenB, _uniswapPoolData.tokenA, _uniswapPoolData.feeTier @@ -105,7 +100,7 @@ contract Demeter_UniV3Farm is BaseFarm, IERC721Receiver { uint256 _tokenId, bytes calldata _data ) external override returns (bytes4) { - if (msg.sender != NFPM) { + if (msg.sender != NFPM()) { revert NotAUniV3NFT(); } if (_data.length == 0) { @@ -133,7 +128,7 @@ contract Demeter_UniV3Farm is BaseFarm, IERC721Receiver { _withdraw(msg.sender, _depositId, userDeposit); // Transfer the nft back to the user. - INFPM(NFPM).safeTransferFrom( + INFPM(NFPM()).safeTransferFrom( address(this), msg.sender, userDeposit.tokenId @@ -148,7 +143,7 @@ contract Demeter_UniV3Farm is BaseFarm, IERC721Receiver { _isValidDeposit(msg.sender, _depositId); uint256 tokenId = deposits[msg.sender][_depositId].tokenId; - INFPM pm = INFPM(NFPM); + INFPM pm = INFPM(NFPM()); (uint256 amt0, uint256 amt1) = PositionValue.fees(pm, tokenId); if (amt0 == 0 && amt1 == 0) { revert NoFeeToClaim(); @@ -174,7 +169,7 @@ contract Demeter_UniV3Farm is BaseFarm, IERC721Receiver { { // Validate token. _getLiquidity(_tokenId); - return PositionValue.fees(INFPM(NFPM), _tokenId); + return PositionValue.fees(INFPM(NFPM()), _tokenId); } /// @notice Validate the position for the pool and get Liquidity @@ -196,13 +191,13 @@ contract Demeter_UniV3Farm is BaseFarm, IERC721Receiver { , , - ) = INFPM(NFPM).positions(_tokenId); + ) = INFPM(NFPM()).positions(_tokenId); /// @dev Check if the token belongs to correct pool if ( uniswapPool != - IUniswapV3Factory(UNIV3_FACTORY).getPool(token0, token1, fee) + IUniswapV3Factory(UNIV3_FACTORY()).getPool(token0, token1, fee) ) { revert IncorrectPoolToken(); } @@ -221,13 +216,17 @@ contract Demeter_UniV3Farm is BaseFarm, IERC721Receiver { { int24 spacing = IUniswapV3TickSpacing(uniswapPool).tickSpacing(); if ( - !(_tickLower < _tickUpper && - _tickLower >= -887272 && - _tickLower % spacing == 0 && - _tickUpper <= 887272 && - _tickUpper % spacing == 0) + _tickLower >= _tickUpper || + _tickLower < -887272 || + _tickLower % spacing != 0 || + _tickUpper > 887272 || + _tickUpper % spacing != 0 ) { revert InvalidTickRange(); } } + + function NFPM() internal pure virtual returns (address); + + function UNIV3_FACTORY() internal pure virtual returns (address); } diff --git a/contracts/uniswapV3/sushiswap/Demeter_SushiV3Farm.sol b/contracts/uniswapV3/sushiswap/Demeter_SushiV3Farm.sol new file mode 100644 index 00000000..072c735b --- /dev/null +++ b/contracts/uniswapV3/sushiswap/Demeter_SushiV3Farm.sol @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.16; + +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@// +//@@@@@@@@&....(@@@@@@@@@@@@@..../@@@@@@@@@// +//@@@@@@........../@@@@@@@........../@@@@@@// +//@@@@@............(@@@@@............(@@@@@// +//@@@@@(............@@@@@(...........&@@@@@// +//@@@@@@@...........&@@@@@@.........@@@@@@@// +//@@@@@@@@@@@@@@%..../@@@@@@@@@@@@@@@@@@@@@// +//@@@@@@@@@@@@@@@@@@@...@@@@@@@@@@@@@@@@@@@// +//@@@@@@@@@@@@@@@@@@@@@......(&@@@@@@@@@@@@// +//@@@@@@#.........@@@@@@#...........@@@@@@@// +//@@@@@/...........%@@@@@............%@@@@@// +//@@@@@............#@@@@@............%@@@@@// +//@@@@@@..........#@@@@@@@/.........#@@@@@@// +//@@@@@@@@@&/.(@@@@@@@@@@@@@@&/.(&@@@@@@@@@// +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@// + +import {BaseUniV3Farm, RewardTokenData, UniswapPoolData} from "../BaseUniV3Farm.sol"; + +contract Demeter_SushiV3Farm is BaseUniV3Farm { + // constants + string public constant FARM_ID = "Demeter_SushiV3_v3"; + + function NFPM() internal pure override returns (address) { + return 0xF0cBce1942A68BEB3d1b73F0dd86C8DCc363eF49; + } + + function UNIV3_FACTORY() internal pure override returns (address) { + return 0x1af415a1EbA07a4986a52B6f2e7dE7003D82231e; + } +} diff --git a/contracts/sushiswapV3/Demeter_SushiV3FarmDeployer.sol b/contracts/uniswapV3/sushiswap/Demeter_SushiV3FarmDeployer.sol similarity index 82% rename from contracts/sushiswapV3/Demeter_SushiV3FarmDeployer.sol rename to contracts/uniswapV3/sushiswap/Demeter_SushiV3FarmDeployer.sol index 78e7dbba..8dbc662b 100644 --- a/contracts/sushiswapV3/Demeter_SushiV3FarmDeployer.sol +++ b/contracts/uniswapV3/sushiswap/Demeter_SushiV3FarmDeployer.sol @@ -17,24 +17,24 @@ pragma solidity 0.8.16; //@@@@@@@@@&/.(@@@@@@@@@@@@@@&/.(&@@@@@@@@@// //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@// -import {BaseFarmDeployer, IFarmFactory} from "../BaseFarmDeployer.sol"; -import {Demeter_SushiV3Farm, RewardTokenData, SushiswapPoolData} from "./Demeter_SushiV3Farm.sol"; +import {BaseFarmDeployer, IFarmFactory} from "../../BaseFarmDeployer.sol"; +import {Demeter_SushiV3Farm, RewardTokenData, UniswapPoolData} from "./Demeter_SushiV3Farm.sol"; import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol"; import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; -contract Demeter_SushiV3FarmDeployer is BaseFarmDeployer, ReentrancyGuard { +contract Demeter_UniV3FarmDeployer is BaseFarmDeployer, ReentrancyGuard { // farmAdmin - Address to which ownership of farm is transferred to post deployment // farmStartTime - Time after which the rewards start accruing for the deposits in the farm. // cooldownPeriod - cooldown period for locked deposits (in days) // make cooldownPeriod = 0 for disabling lockup functionality of the farm. - // sushiswapPoolData - Init data for SushiswapV3 pool. + // uniswapPoolData - Init data for UniswapV3 pool. // (tokenA, tokenB, feeTier, tickLower, tickUpper) // rewardTokenData - [(rewardTokenAddress, tknManagerAddress), ... ] struct FarmData { address farmAdmin; uint256 farmStartTime; uint256 cooldownPeriod; - SushiswapPoolData sushiswapPoolData; + UniswapPoolData uniswapPoolData; RewardTokenData[] rewardData; } @@ -45,7 +45,7 @@ contract Demeter_SushiV3FarmDeployer is BaseFarmDeployer, ReentrancyGuard { farmImplementation = address(new Demeter_SushiV3Farm()); } - /// @notice Deploys a new SushiswapV3 farm. + /// @notice Deploys a new UniswapV3 farm. /// @param _data data for deployment. function createFarm(FarmData memory _data) external @@ -59,16 +59,13 @@ contract Demeter_SushiV3FarmDeployer is BaseFarmDeployer, ReentrancyGuard { farmInstance.initialize( _data.farmStartTime, _data.cooldownPeriod, - _data.sushiswapPoolData, + _data.uniswapPoolData, _data.rewardData ); farmInstance.transferOwnership(_data.farmAdmin); address farm = address(farmInstance); // Calculate and collect fee if required - _collectFee( - _data.sushiswapPoolData.tokenA, - _data.sushiswapPoolData.tokenB - ); + _collectFee(_data.uniswapPoolData.tokenA, _data.uniswapPoolData.tokenB); emit FarmCreated(farm, msg.sender, _data.farmAdmin); IFarmFactory(factory).registerFarm(farm, msg.sender); return farm; diff --git a/contracts/uniswapV3/tests/UniswapV3Test.sol b/contracts/uniswapV3/tests/UniswapV3Test.sol index 4593f313..133ac59e 100644 --- a/contracts/uniswapV3/tests/UniswapV3Test.sol +++ b/contracts/uniswapV3/tests/UniswapV3Test.sol @@ -14,11 +14,9 @@ import {INonfungiblePositionManager} from "../interfaces/UniswapV3.sol"; */ contract UniswapV3Test { using SafeERC20 for IERC20; - INonfungiblePositionManager public nonfungiblePositionManager = - INonfungiblePositionManager(0xC36442b4a4522E871399CD717aBDD847Ab11FE88); + INonfungiblePositionManager public nonfungiblePositionManager; - ISwapRouter public constant SWAP_ROUTER = - ISwapRouter(0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45); + ISwapRouter public immutable SWAP_ROUTER; event SwapTest( address inputToken, @@ -27,6 +25,19 @@ contract UniswapV3Test { uint256 amountOut ); + // uniswap-v3 data + // nonfungiblePositionManager address -> 0xC36442b4a4522E871399CD717aBDD847Ab11FE88 + // SWAP_ROUTER address -> 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45 + + // sushiswap-v3 data + // nonfungiblePositionManager address -> 0xF0cBce1942A68BEB3d1b73F0dd86C8DCc363eF49 + // SWAP_ROUTER address -> 0x8A21F6768C1f8075791D08546Dadf6daA0bE820c + + constructor(address _nfpm, address _swapRouter) { + nonfungiblePositionManager = INonfungiblePositionManager(_nfpm); + SWAP_ROUTER = ISwapRouter(_swapRouter); + } + /** * @notice swaps a fixed amount of inputToken for a maximum possible amount of outputToken on Uniswap V3 */ diff --git a/contracts/uniswapV3/uniswap/Demeter_UniV3Farm.sol b/contracts/uniswapV3/uniswap/Demeter_UniV3Farm.sol new file mode 100644 index 00000000..af59208a --- /dev/null +++ b/contracts/uniswapV3/uniswap/Demeter_UniV3Farm.sol @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.16; + +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@// +//@@@@@@@@&....(@@@@@@@@@@@@@..../@@@@@@@@@// +//@@@@@@........../@@@@@@@........../@@@@@@// +//@@@@@............(@@@@@............(@@@@@// +//@@@@@(............@@@@@(...........&@@@@@// +//@@@@@@@...........&@@@@@@.........@@@@@@@// +//@@@@@@@@@@@@@@%..../@@@@@@@@@@@@@@@@@@@@@// +//@@@@@@@@@@@@@@@@@@@...@@@@@@@@@@@@@@@@@@@// +//@@@@@@@@@@@@@@@@@@@@@......(&@@@@@@@@@@@@// +//@@@@@@#.........@@@@@@#...........@@@@@@@// +//@@@@@/...........%@@@@@............%@@@@@// +//@@@@@............#@@@@@............%@@@@@// +//@@@@@@..........#@@@@@@@/.........#@@@@@@// +//@@@@@@@@@&/.(@@@@@@@@@@@@@@&/.(&@@@@@@@@@// +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@// + +import {BaseUniV3Farm, RewardTokenData, UniswapPoolData} from "../BaseUniV3Farm.sol"; + +contract Demeter_UniV3Farm is BaseUniV3Farm { + // constants + string public constant FARM_ID = "Demeter_UniV3_v3"; + + function NFPM() internal pure override returns (address) { + return 0xC36442b4a4522E871399CD717aBDD847Ab11FE88; + } + + function UNIV3_FACTORY() internal pure override returns (address) { + return 0x1F98431c8aD98523631AE4a59f267346ea31F984; + } +} diff --git a/contracts/uniswapV3/Demeter_UniV3FarmDeployer.sol b/contracts/uniswapV3/uniswap/Demeter_UniV3FarmDeployer.sol similarity index 97% rename from contracts/uniswapV3/Demeter_UniV3FarmDeployer.sol rename to contracts/uniswapV3/uniswap/Demeter_UniV3FarmDeployer.sol index 2a7625af..b94f0464 100644 --- a/contracts/uniswapV3/Demeter_UniV3FarmDeployer.sol +++ b/contracts/uniswapV3/uniswap/Demeter_UniV3FarmDeployer.sol @@ -17,7 +17,7 @@ pragma solidity 0.8.16; //@@@@@@@@@&/.(@@@@@@@@@@@@@@&/.(&@@@@@@@@@// //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@// -import {BaseFarmDeployer, IFarmFactory} from "../BaseFarmDeployer.sol"; +import {BaseFarmDeployer, IFarmFactory} from "../../BaseFarmDeployer.sol"; import {Demeter_UniV3Farm, RewardTokenData, UniswapPoolData} from "./Demeter_UniV3Farm.sol"; import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol"; import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol";