diff --git a/packages/cointags/CHANGELOG.md b/packages/cointags/CHANGELOG.md index bb662c20..08d02a4e 100644 --- a/packages/cointags/CHANGELOG.md +++ b/packages/cointags/CHANGELOG.md @@ -1,5 +1,11 @@ # @zoralabs/cointags-contracts +## 0.1.2 + +### Patch Changes + +- 066c289a: Ensure that cointags can only be created with v3 Uniswap pools + ## 0.1.1 ### Patch Changes diff --git a/packages/cointags/addresses/7777777.json b/packages/cointags/addresses/7777777.json index ce7a3de3..76a4c062 100644 --- a/packages/cointags/addresses/7777777.json +++ b/packages/cointags/addresses/7777777.json @@ -1,7 +1,7 @@ { - "COINTAG": "0x264b731e40691Da5B40aA63AC5c3B7F7DAafA721", + "COINTAG": "0xe72B3547c80C6b7149995bc89918a834d155f378", "COINTAG_FACTORY": "0x7777777BbD0b88aD5F3b5f4c89C6B60D74b9774F", - "COINTAG_FACTORY_IMPL": "0x3764bd00B291c79Ee8912208e279C3Db8A7b89c7", - "COINTAG_VERSION": "0.1.1", + "COINTAG_FACTORY_IMPL": "0xcCe57DFe2cb128a18EF970e6547bB62dd47B1814", + "COINTAG_VERSION": "0.1.2", "UPGRADE_GATE": "0xa1B8447527B993CAbe73B1f3d3d36FC96bABA037" } \ No newline at end of file diff --git a/packages/cointags/addresses/8453.json b/packages/cointags/addresses/8453.json index 83775601..a8638719 100644 --- a/packages/cointags/addresses/8453.json +++ b/packages/cointags/addresses/8453.json @@ -1,7 +1,7 @@ { - "COINTAG": "0x6ec25a679DA11E3a91Edf6a2ffB62D1906075925", + "COINTAG": "0x1585E6FEb5da8AEA107290596F747f81522123dE", "COINTAG_FACTORY": "0x7777777BbD0b88aD5F3b5f4c89C6B60D74b9774F", - "COINTAG_FACTORY_IMPL": "0x68D5a36Af02D303771947C9E55FcfD8998eC769D", - "COINTAG_VERSION": "0.1.1", + "COINTAG_FACTORY_IMPL": "0x1111cfc7A0E39e17C4C2E7cA737B5e3B19b8c881", + "COINTAG_VERSION": "0.1.2", "UPGRADE_GATE": "0x2383770929F8d56e314A449eC5f6812dE27245E6" } \ No newline at end of file diff --git a/packages/cointags/package.json b/packages/cointags/package.json index 8f078636..2d09b51e 100644 --- a/packages/cointags/package.json +++ b/packages/cointags/package.json @@ -1,6 +1,6 @@ { "name": "@zoralabs/cointags-contracts", - "version": "0.1.1", + "version": "0.1.2", "license": "MIT", "type": "module", "main": "./dist/index.cjs", diff --git a/packages/cointags/src/CointagImpl.sol b/packages/cointags/src/CointagImpl.sol index f23cafad..bb58f2cc 100644 --- a/packages/cointags/src/CointagImpl.sol +++ b/packages/cointags/src/CointagImpl.sol @@ -39,7 +39,6 @@ contract CointagImpl is IProtocolRewards public immutable protocolRewards; IWETH public immutable weth; IUpgradeGate public immutable upgradeGate; - uint256 public constant PERCENTAGE_BASIS = 10_000; bytes4 constant REWARD_RECEIVER_REASON = bytes4(keccak256("Cointag split to creator reward recipient")); @@ -93,7 +92,12 @@ contract CointagImpl is cointagSettings.percentageToBuyBurn = percentageToBuyBurn; cointagSettings.erc20 = IBurnableERC20(_getERC20FromPool(IUniswapV3Pool(pool_))); - require(_onePoolTokenIsWeth(IUniswapV3Pool(cointagSettings.pool)), PoolNeedsOneTokenToBeWETH()); + require(_onePoolTokenIsWeth(IUniswapV3Pool(pool_)), PoolNeedsOneTokenToBeWETH()); + // v2 doesn't have a fee() function, so a simple way to prevent non-v3 pools from being used + // is to try to call it and revert if it fails + try IUniswapV3Pool(pool_).fee() returns (uint24) {} catch { + revert NotUniswapV3Pool(); + } emit Initialized({ creatorRewardRecipient: creatorRewardRecipient, diff --git a/packages/cointags/src/interfaces/ICointag.sol b/packages/cointags/src/interfaces/ICointag.sol index e6a6c76f..94082eed 100644 --- a/packages/cointags/src/interfaces/ICointag.sol +++ b/packages/cointags/src/interfaces/ICointag.sol @@ -77,6 +77,9 @@ interface ICointag { /// @notice Thrown when the upgrade to a new implementation has a mismatched contract name error UpgradeToMismatchedContractName(string current, string newName); + /// @notice Thrown when the pool is not a valid Uniswap V3 pool + error NotUniswapV3Pool(); + /// @notice Pulls rewards from protocol rewards and pushes them through the distribution flow function pull() external; diff --git a/packages/cointags/src/version/ContractVersionBase.sol b/packages/cointags/src/version/ContractVersionBase.sol index ab3cea2a..92dfe069 100644 --- a/packages/cointags/src/version/ContractVersionBase.sol +++ b/packages/cointags/src/version/ContractVersionBase.sol @@ -9,6 +9,6 @@ import {IVersionedContract} from "@zoralabs/shared-contracts/interfaces/IVersion contract ContractVersionBase is IVersionedContract { /// @notice The version of the contract function contractVersion() external pure override returns (string memory) { - return "0.1.1"; + return "0.1.2"; } } diff --git a/packages/cointags/test/Cointag.t.sol b/packages/cointags/test/Cointag.t.sol index dbfd064d..863c8664 100644 --- a/packages/cointags/test/Cointag.t.sol +++ b/packages/cointags/test/Cointag.t.sol @@ -96,6 +96,15 @@ contract CointagTest is BaseTest { assertEq(protocolRewards.balanceOf(creatorRewardRecipient), amountToSendToCreator, "creator reward recipient balance"); } + function test_FailNonUniswapV3Pool() public { + setupBaseFork(); + + // this is a uniswap v2 pool - it should revert + IUniswapV3Pool pool = IUniswapV3Pool(vm.parseAddress("0x6d6391B9bD02Eefa00FA711fB1Cb828A6471d283")); + vm.expectRevert(abi.encodeWithSelector(ICointag.NotUniswapV3Pool.selector)); + factory.getOrCreateCointag(creatorRewardRecipient, address(pool), 2000, emptyBytes); + } + // Helper function to get current price from pool function getPrice(address _pool) internal view returns (uint256) { return IUniswapV3Pool(_pool).slot0().sqrtPriceX96;