diff --git a/contracts/BNBPartyFactory.sol b/contracts/BNBPartyFactory.sol index b1f7af6..84abd9f 100644 --- a/contracts/BNBPartyFactory.sol +++ b/contracts/BNBPartyFactory.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.0; import "./token/ERC20Token.sol"; import "./BNBPartyLiquidity.sol"; +import "./interfaces/IUniswapV3Factory.sol"; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@bnb-party/v3-periphery/contracts/interfaces/IPeripheryPayments.sol"; @@ -79,6 +80,7 @@ contract BNBPartyFactory is BNBPartyLiquidity, ReentrancyGuard { address tokenOut, uint256 amountOutMinimum ) external payable notZeroAddress(tokenOut) notZeroValue { + _tokenValidation(tokenOut); (ISwapRouter router, uint24 fee) = _getRouterAndFee(tokenOut); ISwapRouter.ExactInputParams memory params = ISwapRouter .ExactInputParams({ @@ -100,6 +102,7 @@ contract BNBPartyFactory is BNBPartyLiquidity, ReentrancyGuard { uint256 amountIn, uint256 amountOutMinimum ) external notZeroAddress(tokenIn) notZeroAmount(amountIn) { + _tokenValidation(tokenIn); IERC20(tokenIn).safeTransferFrom(msg.sender, address(this), amountIn); (ISwapRouter router, uint24 fee) = _getRouterAndFee(tokenIn); IERC20(tokenIn).safeIncreaseAllowance(address(router), amountIn); @@ -115,4 +118,10 @@ contract BNBPartyFactory is BNBPartyLiquidity, ReentrancyGuard { _executeSwap(router, params); IPeripheryPayments(address(router)).unwrapWETH9(amountOutMinimum, msg.sender); } + + function _tokenValidation(address token) internal view { + address factory = INonfungiblePositionManager(BNBPositionManager).factory(); + address pool = IUniswapV3Factory(factory).getPool(token, address(WBNB), party.partyLpFee);// getPool implements position checking by itself + if (!isParty[pool]) revert LPNotAtParty(); + } } diff --git a/contracts/interfaces/INonfungiblePositionManager.sol b/contracts/interfaces/INonfungiblePositionManager.sol index de31f41..2a6719c 100644 --- a/contracts/interfaces/INonfungiblePositionManager.sol +++ b/contracts/interfaces/INonfungiblePositionManager.sol @@ -182,4 +182,7 @@ interface INonfungiblePositionManager is IPoolInitializer { function burn(uint256 tokenId) external payable; function WETH9() external view returns (address); + + ///@notice Returns the address of the v3-factory + function factory() external view returns (address); } diff --git a/contracts/interfaces/IUniswapV3Factory.sol b/contracts/interfaces/IUniswapV3Factory.sol new file mode 100644 index 0000000..b50aa77 --- /dev/null +++ b/contracts/interfaces/IUniswapV3Factory.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity >=0.5.0; + +/// @title The interface for the Uniswap V3 Factory +/// @notice The Uniswap V3 Factory facilitates creation of Uniswap V3 pools and control over the protocol fees +interface IUniswapV3Factory { + /// @notice Returns the pool address for a given pair of tokens and a fee, or address 0 if it does not exist + /// @dev tokenA and tokenB may be passed in either token0/token1 or token1/token0 order + /// @param tokenA The contract address of either token0 or token1 + /// @param tokenB The contract address of the other token + /// @param fee The fee collected upon every swap in the pool, denominated in hundredths of a bip + /// @return pool The pool address + function getPool( + address tokenA, + address tokenB, + uint24 fee + ) external view returns (address pool); +}