@@ -10,28 +10,10 @@ import {Pausable} from "@openzeppelin/contracts/utils/Pausable.sol";
1010import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol " ;
1111
1212import {CookieJarLib} from "./libraries/CookieJarLib.sol " ;
13- import {CookieJarValidation} from "./libraries/CookieJarValidation.sol " ;
1413import {UniversalSwapAdapter} from "./libraries/UniversalSwapAdapter.sol " ;
1514import {Streaming} from "./libraries/Streaming.sol " ;
1615import {ISuperfluid, ISuperToken, IConstantFlowAgreementV1} from "@superfluid-finance/ethereum-contracts/interfaces/superfluid/ISuperfluid.sol " ;
1716
18- // Protocol interfaces
19- interface IPOAP {
20- function ownerOf (uint256 tokenId ) external view returns (address );
21- }
22-
23- interface IPublicLock {
24- function getHasValidKey (address _user ) external view returns (bool );
25- }
26-
27- interface IHypercertToken {
28- function balanceOf (address account , uint256 id ) external view returns (uint256 );
29- }
30-
31- interface IHats {
32- function isWearerOfHat (address user , uint256 hatId ) external view returns (bool );
33- }
34-
3517/// @title CookieJar - Optimized Version
3618/// @notice Decentralized funding pools with simplified access control
3719/// @dev Supports Allowlist, ERC721, and ERC1155 access types with optimized storage and validation
@@ -121,7 +103,13 @@ contract CookieJar is AccessControl, Pausable, ReentrancyGuard {
121103 if (config.feeCollector == address (0 )) revert CookieJarLib.FeeCollectorAddressCannotBeZeroAddress ();
122104
123105 // Initialize Superfluid host and CFA using Streaming library
124- (superfluidHost, cfa) = Streaming.initializeSuperfluidContracts (_superfluidHost);
106+ if (_superfluidHost != address (0 )) {
107+ (superfluidHost, cfa) = Streaming.initializeSuperfluidContracts (_superfluidHost);
108+ } else {
109+ // For testing - use placeholder addresses
110+ superfluidHost = ISuperfluid (address (0 ));
111+ cfa = IConstantFlowAgreementV1 (address (0 ));
112+ }
125113
126114 // Set immutable configuration
127115 accessType = config.accessType;
@@ -142,7 +130,10 @@ contract CookieJar is AccessControl, Pausable, ReentrancyGuard {
142130 if (accessType == CookieJarLib.AccessType.Allowlist) {
143131 _setupAllowlist (accessConfig.allowlist);
144132 } else {
145- // For ERC721 and ERC1155, use unified NFT requirement
133+ // For ERC721 and ERC1155, validate NFT requirement
134+ if (accessConfig.nftRequirement.nftContract == address (0 )) {
135+ revert CookieJarLib.NoNFTAddressesProvided ();
136+ }
146137 nftRequirement = accessConfig.nftRequirement;
147138 }
148139
@@ -232,7 +223,7 @@ contract CookieJar is AccessControl, Pausable, ReentrancyGuard {
232223 if (withdrawalOption == CookieJarLib.WithdrawalTypeOptions.Fixed) revert CookieJarLib.InvalidWithdrawalType ();
233224 if (_maxWithdrawal == 0 ) revert CookieJarLib.ZeroAmount ();
234225 maxWithdrawal = _maxWithdrawal;
235- emit CookieJarLib.MaxWithdrawalUpdated ( _maxWithdrawal);
226+ emit CookieJarLib.ParameterUpdated (CookieJarLib.PARAM_MAX_WITHDRAWAL, _maxWithdrawal);
236227 }
237228
238229 /// @notice Updates the fixed withdrawal amount, only works if withdrawalOption is Fixed.
@@ -243,15 +234,15 @@ contract CookieJar is AccessControl, Pausable, ReentrancyGuard {
243234 }
244235 if (_fixedAmount == 0 ) revert CookieJarLib.ZeroAmount ();
245236 fixedAmount = _fixedAmount;
246- emit CookieJarLib.FixedWithdrawalAmountUpdated ( _fixedAmount);
237+ emit CookieJarLib.ParameterUpdated (CookieJarLib.PARAM_FIXED_AMOUNT, _fixedAmount);
247238 }
248239
249240 /// @notice Updates the withdrawal interval.
250241 /// @param _withdrawalInterval The new withdrawal interval.
251242 function updateWithdrawalInterval (uint256 _withdrawalInterval ) external onlyRole (CookieJarLib.JAR_OWNER) {
252243 if (_withdrawalInterval == 0 ) revert CookieJarLib.ZeroAmount ();
253244 withdrawalInterval = _withdrawalInterval;
254- emit CookieJarLib.WithdrawalIntervalUpdated ( _withdrawalInterval);
245+ emit CookieJarLib.ParameterUpdated (CookieJarLib.PARAM_WITHDRAWAL_INTERVAL, _withdrawalInterval);
255246 }
256247
257248 // === MULTI-TOKEN & STREAMING ADMIN FUNCTIONS ===
@@ -348,39 +339,34 @@ contract CookieJar is AccessControl, Pausable, ReentrancyGuard {
348339 emit CookieJarLib.FeeCollected (feeCollector, fee, currency);
349340 }
350341
351- /// @notice Withdraws funds for allowlisted users
342+ /// @notice Unified withdrawal function for all access types
343+ /// @dev Consolidated function reduces bytecode by eliminating duplicate logic
352344 /// @param amount The amount to withdraw
353345 /// @param purpose A description for the withdrawal
354- function withdrawAllowlistMode (
346+ function withdraw (
355347 uint256 amount ,
356348 string calldata purpose
357- ) external onlyRole (CookieJarLib.JAR_ALLOWLISTED) whenNotPaused nonReentrant {
358- if (accessType != CookieJarLib.AccessType.Allowlist) revert CookieJarLib.InvalidAccessType ();
349+ ) public whenNotPaused nonReentrant {
350+ // Validate access based on jar type
351+ _checkAccess ();
352+
353+ // Validate and execute withdrawal
359354 _validateAndWithdraw (amount, purpose);
360355 }
361-
362- /// @notice Withdraw funds with ERC721 NFT verification
363- /// @param amount The amount to withdraw
364- /// @param purpose A description for the withdrawal
365- function withdrawWithERC721 (
366- uint256 amount ,
367- string calldata purpose
368- ) external whenNotPaused nonReentrant {
369- if (accessType != CookieJarLib.AccessType.ERC721 ) revert CookieJarLib.InvalidAccessType ();
370- _validateAccess ();
371- _validateAndWithdraw (amount, purpose);
356+
357+ /// @notice Legacy function for allowlist mode (backwards compatibility)
358+ function withdrawAllowlistMode (uint256 amount , string calldata purpose ) external {
359+ this .withdraw (amount, purpose);
372360 }
373-
374- /// @notice Withdraw funds with ERC1155 NFT verification (covers Hypercerts, Hats Protocol)
375- /// @param amount The amount to withdraw
376- /// @param purpose A description for the withdrawal
377- function withdrawWithERC1155 (
378- uint256 amount ,
379- string calldata purpose
380- ) external whenNotPaused nonReentrant {
381- if (accessType != CookieJarLib.AccessType.ERC1155 ) revert CookieJarLib.InvalidAccessType ();
382- _validateAccess ();
383- _validateAndWithdraw (amount, purpose);
361+
362+ /// @notice Legacy function for ERC721 mode (backwards compatibility)
363+ function withdrawWithERC721 (uint256 amount , string calldata purpose ) external {
364+ this .withdraw (amount, purpose);
365+ }
366+
367+ /// @notice Legacy function for ERC1155 mode (backwards compatibility)
368+ function withdrawWithERC1155 (uint256 amount , string calldata purpose ) external {
369+ this .withdraw (amount, purpose);
384370 }
385371
386372 // --- View Functions ---
@@ -393,59 +379,31 @@ contract CookieJar is AccessControl, Pausable, ReentrancyGuard {
393379
394380 // === INTERNAL VALIDATION FUNCTIONS ===
395381
396- /// @notice Unified access validation for all access types
397- /// @dev Replaces multiple protocol-specific validation functions
398- function _validateAccess () internal view {
382+ /// @notice Optimized inline access validation for all access types
383+ /// @dev Consolidated validation logic to reduce bytecode size
384+ function _checkAccess () internal view {
399385 if (accessType == CookieJarLib.AccessType.Allowlist) {
400- if (! hasRole (CookieJarLib.JAR_ALLOWLISTED, msg .sender )) {
386+ if (! hasRole (CookieJarLib.JAR_ALLOWLISTED, msg .sender ))
401387 revert CookieJarLib.NotAuthorized ();
402- }
403388 } else if (accessType == CookieJarLib.AccessType.ERC721 ) {
404- _validateERC721Access ();
389+ // Inline ERC721 validation
390+ if (nftRequirement.nftContract == address (0 )) revert CookieJarLib.InvalidTokenAddress ();
391+ if (nftRequirement.tokenId == 0 ) revert CookieJarLib.NotAuthorized (); // Require specific token
392+ try IERC721 (nftRequirement.nftContract).ownerOf (nftRequirement.tokenId) returns (address owner ) {
393+ if (owner != msg .sender ) revert CookieJarLib.NotAuthorized ();
394+ } catch { revert CookieJarLib.NotAuthorized (); }
405395 } else if (accessType == CookieJarLib.AccessType.ERC1155 ) {
406- _validateERC1155Access ();
396+ // Inline ERC1155 validation
397+ if (nftRequirement.nftContract == address (0 )) revert CookieJarLib.InvalidTokenAddress ();
398+ uint256 minBal = nftRequirement.minBalance > 0 ? nftRequirement.minBalance : 1 ;
399+ try IERC1155 (nftRequirement.nftContract).balanceOf (msg .sender , nftRequirement.tokenId) returns (uint256 bal ) {
400+ if (bal < minBal) revert CookieJarLib.NotAuthorized ();
401+ } catch { revert CookieJarLib.NotAuthorized (); }
407402 } else {
408403 revert CookieJarLib.InvalidAccessType ();
409404 }
410405 }
411406
412- /// @notice Validate ERC721 ownership (covers POAP, Unlock, etc.)
413- /// @dev Simplified from complex protocol-specific validation
414- function _validateERC721Access () internal view {
415- address nftContract = nftRequirement.nftContract;
416- uint256 tokenId = nftRequirement.tokenId;
417-
418- if (nftContract == address (0 )) revert CookieJarLib.InvalidTokenAddress ();
419-
420- if (tokenId > 0 ) {
421- // Specific token ID required
422- try IERC721 (nftContract).ownerOf (tokenId) returns (address owner ) {
423- if (owner != msg .sender ) revert CookieJarLib.NotAuthorized ();
424- } catch {
425- revert CookieJarLib.NotAuthorized ();
426- }
427- } else {
428- // Any token from contract - fallback for contracts that don't implement ownerOf properly
429- revert CookieJarLib.NotAuthorized (); // For now, require specific token ID
430- }
431- }
432-
433- /// @notice Validate ERC1155 balance (covers Hypercerts, Hats Protocol)
434- /// @dev Unified validation for all ERC1155-based protocols
435- function _validateERC1155Access () internal view {
436- address nftContract = nftRequirement.nftContract;
437- uint256 tokenId = nftRequirement.tokenId;
438- uint256 minBalance = nftRequirement.minBalance > 0 ? nftRequirement.minBalance : 1 ;
439-
440- if (nftContract == address (0 )) revert CookieJarLib.InvalidTokenAddress ();
441-
442- try IERC1155 (nftContract).balanceOf (msg .sender , tokenId) returns (uint256 balance ) {
443- if (balance < minBalance) revert CookieJarLib.NotAuthorized ();
444- } catch {
445- revert CookieJarLib.NotAuthorized ();
446- }
447- }
448-
449407 /// @notice Validate withdrawal constraints and execute withdrawal
450408 /// @dev Unified validation replacing multiple protocol-specific functions
451409 function _validateAndWithdraw (uint256 amount , string calldata purpose ) internal {
0 commit comments