feat(account): Add DM gating facet with modular criteria system#4832
feat(account): Add DM gating facet with modular criteria system#4832giuseppecrj wants to merge 5 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughIntroduces a new DMGating facet system enabling per-account direct messaging criteria management. Includes DMGatingFacet, DMGatingMod library, ICriteria/IDMGating interfaces, AllowlistCriteria implementation, deployment helpers, and comprehensive tests with AND/OR combination logic support. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~30 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In @packages/contracts/src/account/criteria/AllowlistCriteria.sol:
- Around line 22-23: The declared error AllowlistCriteria__Unauthorized is
unused; implement access control in the onInstall and onUninstall functions to
revert with AllowlistCriteria__Unauthorized when callers are not permitted
(e.g., onlyOwner or a specific manager role), or remove the error if access
control is not required; locate the onInstall and onUninstall functions in
AllowlistCriteria.sol and add a require/check (using owner(), onlyOwner
modifier, or IERC173/IERC165 role check) that reverts with
AllowlistCriteria__Unauthorized on unauthorized calls so the declared error is
actually used.
- Around line 57-67: onInstall currently allows any caller to add addresses for
any account; restrict it by verifying the caller before calling _addAddresses.
Add an authorization check in onInstall (e.g., require(msg.sender == account ||
msg.sender == authorizedGatingFacet) or call into the contract's policy/registry
to confirm the caller is the DMGatingFacet) and revert with a clear error
message if unauthorized; reference the onInstall function and the _addAddresses
call when making the change and ensure the chosen authorized address/lookup is
initialized or fetched from your existing registry/facet lookup logic.
- Around line 69-77: The onUninstall function currently allows anyone to wipe an
account's allowlist; add the same access control check used in onInstall to
prevent unauthorized callers from clearing _allowlists[account]. Specifically,
in onUninstall (which manipulates EnumerableSetLib.AddressSet storage allowlist,
address[] memory addresses, and calls allowlist.remove), guard the function with
the same require/authorization logic present in onInstall so only the account
owner or an authorized installer can call it; implement the identical
access-check code path as in onInstall before iterating and removing addresses.
🧹 Nitpick comments (1)
packages/contracts/src/account/facets/dm/DMGatingMod.sol (1)
173-184: Consider defensive handling for reverting criteria in view function.If a criteria contract reverts in
canDM(), the entirecanReceiveDMFromcall fails. A malicious or buggy criteria could DoS the view. Consider wrapping in try-catch and treating reverts asfalse(for AND) or skipping (for OR).♻️ Optional defensive approach
for (uint256 i; i < length; ++i) { - bool result = ICriteria(criteriaList[i]).canDM( - sender, - account, - extraData - ); + bool result; + try ICriteria(criteriaList[i]).canDM(sender, account, extraData) returns (bool r) { + result = r; + } catch { + // Treat reverting criteria as failing + result = false; + } // Early exit on success for OR mode if (mode == CombinationMode.OR && result) return true;
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
packages/contracts/scripts/deployments/diamonds/DeployAccountModules.s.solpackages/contracts/scripts/deployments/facets/DeployDMGatingFacet.s.solpackages/contracts/src/account/criteria/AllowlistCriteria.solpackages/contracts/src/account/facets/dm/DMGatingFacet.solpackages/contracts/src/account/facets/dm/DMGatingMod.solpackages/contracts/src/account/facets/dm/ICriteria.solpackages/contracts/src/account/facets/dm/IDMGating.solpackages/contracts/test/account/DMGating.t.sol
🧰 Additional context used
📓 Path-based instructions (12)
packages/contracts/**/*.sol
📄 CodeRabbit inference engine (packages/contracts/.cursor/rules/design-philosophy.mdc)
packages/contracts/**/*.sol: Minimize complexity in software structure, prioritizing obviousness and ease of modification in Solidity contracts and facets
Invest time in design upfront rather than quick tactical fixes; prioritize long-term structure over short-term convenience when adding new facets or features
Design code to be obvious: developers should quickly understand existing code and confidently make changes without requiring multiple file traces and dependency navigation
Minimize coupling between modules; use events and interfaces to decouple components so changes in one facet rarely require changes in others
Name entities precisely and document non-obvious behavior; if a function's purpose isn't clear from its signature and name, the design needs improvement
Avoid change amplification: small logical changes should not require modifying many files; high coupling indicates architecture problems
Reduce cognitive load by making facet interfaces self-documenting and isolating storage layouts so developers don't need extensive context to complete tasks
Make it obvious which code must be modified for a given change through clear module boundaries and interfaces to prevent hidden dependencies
Strive for deep modules in Solidity: provide powerful functionality through simple interfaces while hiding complex implementation details
Design facet interfaces to be minimal and clear, hiding internal complexity such as cross-chain calls, rule evaluation, and caching logic
Design facets to be somewhat general-purpose; separate specialized logic from general mechanisms to maximize code reusability
Implement information hiding to ensure each facet has isolated storage slots and facets communicate through libraries, abstracts, or well-defined interfaces rather than shared knowledge
Do not expose storage layout details of one facet to another; each facet must have isolated storage and communicate through interfaces
Avoid temporal decomposition: do not structure code solely ba...
Files:
packages/contracts/scripts/deployments/diamonds/DeployAccountModules.s.solpackages/contracts/src/account/facets/dm/ICriteria.solpackages/contracts/src/account/facets/dm/DMGatingFacet.solpackages/contracts/src/account/criteria/AllowlistCriteria.solpackages/contracts/src/account/facets/dm/IDMGating.solpackages/contracts/test/account/DMGating.t.solpackages/contracts/src/account/facets/dm/DMGatingMod.solpackages/contracts/scripts/deployments/facets/DeployDMGatingFacet.s.sol
packages/contracts/scripts/deployments/**/*.s.sol
📄 CodeRabbit inference engine (packages/contracts/AGENTS.md)
Add deployment scripts in
scripts/deployments/[type]/Deploy[Feature].s.solwhen adding new facets or core contracts
Files:
packages/contracts/scripts/deployments/diamonds/DeployAccountModules.s.solpackages/contracts/scripts/deployments/facets/DeployDMGatingFacet.s.sol
packages/contracts/scripts/**/*.sol
📄 CodeRabbit inference engine (packages/contracts/.cursor/rules/contracts.mdc)
packages/contracts/scripts/**/*.sol: Document upgrade procedures
Use modular facet deployment that can be customized by passing different facet lists
Files:
packages/contracts/scripts/deployments/diamonds/DeployAccountModules.s.solpackages/contracts/scripts/deployments/facets/DeployDMGatingFacet.s.sol
packages/contracts/scripts/**/*Deploy*.sol
📄 CodeRabbit inference engine (packages/contracts/.cursor/rules/contracts.mdc)
Each facet deployment library must provide selectors and cut data
Files:
packages/contracts/scripts/deployments/diamonds/DeployAccountModules.s.solpackages/contracts/scripts/deployments/facets/DeployDMGatingFacet.s.sol
**/*.{ts,tsx,js,jsx,yaml,yml,sol,json,md}
📄 CodeRabbit inference engine (AGENTS.md)
All non-Go files must pass Prettier formatting, run bun run prettier:fix to automatically format TypeScript, JavaScript, YAML, Solidity, and other supported files
Files:
packages/contracts/scripts/deployments/diamonds/DeployAccountModules.s.solpackages/contracts/src/account/facets/dm/ICriteria.solpackages/contracts/src/account/facets/dm/DMGatingFacet.solpackages/contracts/src/account/criteria/AllowlistCriteria.solpackages/contracts/src/account/facets/dm/IDMGating.solpackages/contracts/test/account/DMGating.t.solpackages/contracts/src/account/facets/dm/DMGatingMod.solpackages/contracts/scripts/deployments/facets/DeployDMGatingFacet.s.sol
packages/contracts/src/**/*.sol
📄 CodeRabbit inference engine (packages/contracts/AGENTS.md)
Organize contract code with separate Storage library, Base contract with internal logic, and Facet contract with external interface
Files:
packages/contracts/src/account/facets/dm/ICriteria.solpackages/contracts/src/account/facets/dm/DMGatingFacet.solpackages/contracts/src/account/criteria/AllowlistCriteria.solpackages/contracts/src/account/facets/dm/IDMGating.solpackages/contracts/src/account/facets/dm/DMGatingMod.sol
packages/contracts/src/**/*/{I[A-Z]*.sol,I*.sol}
📄 CodeRabbit inference engine (packages/contracts/AGENTS.md)
Create interface contracts in
I[Feature].solfor all facet contracts
Files:
packages/contracts/src/account/facets/dm/ICriteria.solpackages/contracts/src/account/facets/dm/IDMGating.sol
packages/contracts/src/**/facets/**/*.sol
📄 CodeRabbit inference engine (packages/contracts/.cursor/rules/contracts.mdc)
packages/contracts/src/**/facets/**/*.sol: Split facet implementation into Storage Library, Base Contract, Facet Contract, and Interfaces for upgrade safety
Place business logic in a base contract and expose only protected/external calls in the facet contract
Files:
packages/contracts/src/account/facets/dm/ICriteria.solpackages/contracts/src/account/facets/dm/DMGatingFacet.solpackages/contracts/src/account/facets/dm/IDMGating.solpackages/contracts/src/account/facets/dm/DMGatingMod.sol
packages/contracts/src/**/facets/**/*Facet.sol
📄 CodeRabbit inference engine (packages/contracts/AGENTS.md)
Create facet contracts with external functions in
[Feature]Facet.solthat inherit from corresponding[Feature]Basecontracts
Files:
packages/contracts/src/account/facets/dm/DMGatingFacet.sol
packages/contracts/test/**/*.t.sol
📄 CodeRabbit inference engine (packages/contracts/AGENTS.md)
packages/contracts/test/**/*.t.sol: Write comprehensive unit tests for all functionality with fuzz testing for numeric inputs using 4096 test runs minimum
Test permission and access control logic thoroughly including edge cases and unauthorized access attempts
Use fork tests to test cross-chain functionality against actual deployed contracts
Test upgrade paths for diamond facets when modifying existing facet contracts
Files:
packages/contracts/test/account/DMGating.t.sol
packages/contracts/**/*.t.sol
📄 CodeRabbit inference engine (packages/contracts/.cursor/rules/contracts.mdc)
packages/contracts/**/*.t.sol: Write comprehensive unit tests
Test all edge cases
Test permission/access control logic
Test cross-chain functionality
Test upgrade paths
Files:
packages/contracts/test/account/DMGating.t.sol
packages/contracts/scripts/deployments/facets/*.s.sol
📄 CodeRabbit inference engine (packages/contracts/AGENTS.md)
Deploy facets using dedicated deployment scripts in
scripts/deployments/facets/Deploy[Feature].s.sol
Files:
packages/contracts/scripts/deployments/facets/DeployDMGatingFacet.s.sol
🧠 Learnings (33)
📚 Learning: 2025-12-17T01:18:07.265Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/contracts/.cursor/rules/contracts.mdc:0-0
Timestamp: 2025-12-17T01:18:07.265Z
Learning: Applies to packages/contracts/scripts/**/*.sol : Use modular facet deployment that can be customized by passing different facet lists
Applied to files:
packages/contracts/scripts/deployments/diamonds/DeployAccountModules.s.solpackages/contracts/scripts/deployments/facets/DeployDMGatingFacet.s.sol
📚 Learning: 2025-12-06T08:15:28.770Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/contracts/AGENTS.md:0-0
Timestamp: 2025-12-06T08:15:28.770Z
Learning: Applies to packages/contracts/scripts/deployments/facets/*.s.sol : Deploy facets using dedicated deployment scripts in `scripts/deployments/facets/Deploy[Feature].s.sol`
Applied to files:
packages/contracts/scripts/deployments/diamonds/DeployAccountModules.s.solpackages/contracts/scripts/deployments/facets/DeployDMGatingFacet.s.sol
📚 Learning: 2025-12-17T01:18:07.265Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/contracts/.cursor/rules/contracts.mdc:0-0
Timestamp: 2025-12-17T01:18:07.265Z
Learning: Applies to packages/contracts/scripts/**/*Deploy*.sol : Each facet deployment library must provide selectors and cut data
Applied to files:
packages/contracts/scripts/deployments/diamonds/DeployAccountModules.s.solpackages/contracts/scripts/deployments/facets/DeployDMGatingFacet.s.sol
📚 Learning: 2025-12-06T08:15:28.770Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/contracts/AGENTS.md:0-0
Timestamp: 2025-12-06T08:15:28.770Z
Learning: Applies to packages/contracts/scripts/deployments/**/*.s.sol : Add deployment scripts in `scripts/deployments/[type]/Deploy[Feature].s.sol` when adding new facets or core contracts
Applied to files:
packages/contracts/scripts/deployments/diamonds/DeployAccountModules.s.solpackages/contracts/scripts/deployments/facets/DeployDMGatingFacet.s.sol
📚 Learning: 2025-12-06T08:15:28.770Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/contracts/AGENTS.md:0-0
Timestamp: 2025-12-06T08:15:28.770Z
Learning: Applies to packages/contracts/test/**/*.t.sol : Test upgrade paths for diamond facets when modifying existing facet contracts
Applied to files:
packages/contracts/scripts/deployments/diamonds/DeployAccountModules.s.solpackages/contracts/src/account/facets/dm/DMGatingFacet.solpackages/contracts/test/account/DMGating.t.sol
📚 Learning: 2025-05-11T12:35:14.828Z
Learnt from: shuhuiluo
Repo: towns-protocol/towns PR: 3041
File: packages/contracts/test/base/registry/RewardsDistributionV2.t.sol:83-94
Timestamp: 2025-05-11T12:35:14.828Z
Learning: In the Towns Protocol codebase, the types `FacetCut` and `FacetCutAction` are available through the `IDiamond` interface, not just through `IDiamondCut`. This means contracts inheriting from `IDiamond` can use these types without qualification.
Applied to files:
packages/contracts/scripts/deployments/diamonds/DeployAccountModules.s.solpackages/contracts/src/account/facets/dm/DMGatingFacet.sol
📚 Learning: 2025-12-06T08:15:28.770Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/contracts/AGENTS.md:0-0
Timestamp: 2025-12-06T08:15:28.770Z
Learning: Applies to packages/contracts/src/**/facets/**/*Facet.sol : Create facet contracts with external functions in `[Feature]Facet.sol` that inherit from corresponding `[Feature]Base` contracts
Applied to files:
packages/contracts/scripts/deployments/diamonds/DeployAccountModules.s.solpackages/contracts/src/account/facets/dm/DMGatingFacet.solpackages/contracts/scripts/deployments/facets/DeployDMGatingFacet.s.sol
📚 Learning: 2025-05-11T12:37:26.014Z
Learnt from: shuhuiluo
Repo: towns-protocol/towns PR: 3041
File: packages/contracts/scripts/deployments/diamonds/DeployBaseRegistry.s.sol:92-106
Timestamp: 2025-05-11T12:37:26.014Z
Learning: The DeployFacet helper in the Towns Protocol contract deployment system uses CREATE2 for deterministic address calculation and maintains a mapping of deployed addresses to prevent redeploying the same facet even if it's queued multiple times. The facet queue isn't reset between deployments, but this doesn't cause issues since the helper checks if each facet is already deployed.
Applied to files:
packages/contracts/scripts/deployments/diamonds/DeployAccountModules.s.solpackages/contracts/scripts/deployments/facets/DeployDMGatingFacet.s.sol
📚 Learning: 2025-12-17T01:18:07.265Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/contracts/.cursor/rules/contracts.mdc:0-0
Timestamp: 2025-12-17T01:18:07.265Z
Learning: Applies to packages/contracts/src/**/facets/**/*.sol : Split facet implementation into Storage Library, Base Contract, Facet Contract, and Interfaces for upgrade safety
Applied to files:
packages/contracts/scripts/deployments/diamonds/DeployAccountModules.s.solpackages/contracts/src/account/facets/dm/DMGatingFacet.solpackages/contracts/src/account/facets/dm/IDMGating.solpackages/contracts/src/account/facets/dm/DMGatingMod.solpackages/contracts/scripts/deployments/facets/DeployDMGatingFacet.s.sol
📚 Learning: 2025-12-10T22:31:40.807Z
Learnt from: giuseppecrj
Repo: towns-protocol/towns PR: 4640
File: packages/contracts/src/account/facets/hub/AccountHubMod.sol:91-94
Timestamp: 2025-12-10T22:31:40.807Z
Learning: In packages/contracts/src/account/facets/hub/AccountHubMod.sol and similar module files, file-level functions are used as internal helpers and default to internal visibility in Solidity, but explicit visibility modifiers are still preferred per coding guidelines.
Applied to files:
packages/contracts/scripts/deployments/diamonds/DeployAccountModules.s.solpackages/contracts/src/account/facets/dm/DMGatingFacet.solpackages/contracts/src/account/facets/dm/IDMGating.solpackages/contracts/src/account/facets/dm/DMGatingMod.sol
📚 Learning: 2025-11-25T08:45:45.263Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/contracts/.cursor/rules/design-philosophy.mdc:0-0
Timestamp: 2025-11-25T08:45:45.263Z
Learning: Applies to packages/contracts/**/*.sol : Design facets to be somewhat general-purpose; separate specialized logic from general mechanisms to maximize code reusability
Applied to files:
packages/contracts/scripts/deployments/diamonds/DeployAccountModules.s.solpackages/contracts/src/account/facets/dm/DMGatingFacet.solpackages/contracts/scripts/deployments/facets/DeployDMGatingFacet.s.sol
📚 Learning: 2025-12-17T01:18:07.265Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/contracts/.cursor/rules/contracts.mdc:0-0
Timestamp: 2025-12-17T01:18:07.265Z
Learning: Applies to packages/contracts/src/**/facets/**/*.sol : Place business logic in a base contract and expose only protected/external calls in the facet contract
Applied to files:
packages/contracts/scripts/deployments/diamonds/DeployAccountModules.s.solpackages/contracts/src/account/facets/dm/DMGatingFacet.sol
📚 Learning: 2025-11-17T17:41:02.370Z
Learnt from: giuseppecrj
Repo: towns-protocol/towns PR: 4507
File: packages/contracts/src/apps/facets/reputation/ReputationRegistryFacet.sol:78-80
Timestamp: 2025-11-17T17:41:02.370Z
Learning: In the towns-protocol/towns repository, the IdentityRegistryFacet and ReputationRegistryFacet are both facets of the same diamond proxy (EIP-2535 pattern). Therefore, ReputationRegistryFacet.getIdentityRegistry() correctly returns address(this), which is the diamond's address where both registry functionalities are accessible.
Applied to files:
packages/contracts/scripts/deployments/diamonds/DeployAccountModules.s.sol
📚 Learning: 2025-12-19T20:33:59.100Z
Learnt from: shuhuiluo
Repo: towns-protocol/towns PR: 4717
File: packages/contracts/test/spaces/membership/unit/MembershipCurrencyMigration.t.sol:2-2
Timestamp: 2025-12-19T20:33:59.100Z
Learning: In Foundry projects, the compiler version is governed by foundry.toml; file-level pragmas only need to be compatible. Do not require exact version matches. Ensure pragma solidity in .sol files is compatible with the version configured in foundry.toml and avoid mismatches that would cause compilation issues.
Applied to files:
packages/contracts/scripts/deployments/diamonds/DeployAccountModules.s.solpackages/contracts/src/account/facets/dm/ICriteria.solpackages/contracts/src/account/facets/dm/DMGatingFacet.solpackages/contracts/src/account/criteria/AllowlistCriteria.solpackages/contracts/src/account/facets/dm/IDMGating.solpackages/contracts/test/account/DMGating.t.solpackages/contracts/src/account/facets/dm/DMGatingMod.solpackages/contracts/scripts/deployments/facets/DeployDMGatingFacet.s.sol
📚 Learning: 2026-01-06T21:19:34.734Z
Learnt from: giuseppecrj
Repo: towns-protocol/towns PR: 4720
File: packages/contracts/scripts/deployments/diamonds/DeployL1Resolver.s.sol:40-46
Timestamp: 2026-01-06T21:19:34.734Z
Learning: In Solidity deployment script files under packages/contracts/scripts/ (e.g., DeployL1Resolver.s.sol), treat them as local build-time tools that run during deployment and are not deployed on-chain. Do not add runtime access controls (like onlyOwner) or on-chain input validations that are only relevant for production contracts. Reviewers should ensure such script files focus on deployment logic and do not introduce on-chain security concerns meant for deployed contracts.
Applied to files:
packages/contracts/scripts/deployments/diamonds/DeployAccountModules.s.solpackages/contracts/scripts/deployments/facets/DeployDMGatingFacet.s.sol
📚 Learning: 2025-12-06T08:15:28.770Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/contracts/AGENTS.md:0-0
Timestamp: 2025-12-06T08:15:28.770Z
Learning: Applies to packages/contracts/src/**/*/{I[A-Z]*.sol,I*.sol} : Create interface contracts in `I[Feature].sol` for all facet contracts
Applied to files:
packages/contracts/src/account/facets/dm/ICriteria.solpackages/contracts/src/account/facets/dm/IDMGating.sol
📚 Learning: 2025-12-17T01:18:07.265Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/contracts/.cursor/rules/contracts.mdc:0-0
Timestamp: 2025-12-17T01:18:07.265Z
Learning: Applies to packages/contracts/src/**/*Interface.sol : Define interfaces for external APIs
Applied to files:
packages/contracts/src/account/facets/dm/ICriteria.solpackages/contracts/src/account/facets/dm/IDMGating.sol
📚 Learning: 2025-11-25T08:45:45.263Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/contracts/.cursor/rules/design-philosophy.mdc:0-0
Timestamp: 2025-11-25T08:45:45.263Z
Learning: Applies to packages/contracts/**/*.sol : Design facet interfaces to be minimal and clear, hiding internal complexity such as cross-chain calls, rule evaluation, and caching logic
Applied to files:
packages/contracts/src/account/facets/dm/ICriteria.solpackages/contracts/src/account/facets/dm/DMGatingFacet.solpackages/contracts/src/account/facets/dm/IDMGating.sol
📚 Learning: 2025-05-19T23:57:16.097Z
Learnt from: shuhuiluo
Repo: towns-protocol/towns PR: 3104
File: packages/contracts/src/airdrop/drop/DropFacet.sol:54-75
Timestamp: 2025-05-19T23:57:16.097Z
Learning: The DropFacet contract follows the Checks-Effects-Interactions pattern in its claim functions, with state modifications happening before external calls to prevent re-entrancy attacks. Additionally, the ERC-20 tokens used in the system are set by governance, providing an extra layer of security.
Applied to files:
packages/contracts/src/account/facets/dm/DMGatingFacet.sol
📚 Learning: 2025-12-06T08:15:28.770Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/contracts/AGENTS.md:0-0
Timestamp: 2025-12-06T08:15:28.770Z
Learning: Applies to packages/contracts/src/**/facets/**/*Base.sol : Create base contracts with internal logic in `[Feature]Base.sol` alongside facet contracts
Applied to files:
packages/contracts/src/account/facets/dm/DMGatingFacet.sol
📚 Learning: 2025-11-25T08:45:45.263Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/contracts/.cursor/rules/design-philosophy.mdc:0-0
Timestamp: 2025-11-25T08:45:45.263Z
Learning: Applies to packages/contracts/**/*.sol : Implement information hiding to ensure each facet has isolated storage slots and facets communicate through libraries, abstracts, or well-defined interfaces rather than shared knowledge
Applied to files:
packages/contracts/src/account/facets/dm/DMGatingFacet.solpackages/contracts/scripts/deployments/facets/DeployDMGatingFacet.s.sol
📚 Learning: 2025-05-20T00:00:31.574Z
Learnt from: shuhuiluo
Repo: towns-protocol/towns PR: 3104
File: packages/contracts/src/airdrop/drop/DropFacet.sol:133-139
Timestamp: 2025-05-20T00:00:31.574Z
Learning: The DropFacet contract uses an assembly memory optimization technique in getter functions that return structs, resetting the free memory pointer to deallocate the memory that Solidity automatically allocates for named return variables. This is marked as "memory-safe" and used to improve gas efficiency.
Applied to files:
packages/contracts/src/account/facets/dm/DMGatingFacet.solpackages/contracts/scripts/deployments/facets/DeployDMGatingFacet.s.sol
📚 Learning: 2025-11-25T08:45:45.263Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/contracts/.cursor/rules/design-philosophy.mdc:0-0
Timestamp: 2025-11-25T08:45:45.263Z
Learning: Applies to packages/contracts/**/*.sol : Do not expose storage layout details of one facet to another; each facet must have isolated storage and communicate through interfaces
Applied to files:
packages/contracts/src/account/facets/dm/DMGatingFacet.sol
📚 Learning: 2025-12-17T01:18:07.265Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/contracts/.cursor/rules/contracts.mdc:0-0
Timestamp: 2025-12-17T01:18:07.265Z
Learning: Applies to packages/contracts/**/*.t.sol : Test upgrade paths
Applied to files:
packages/contracts/test/account/DMGating.t.sol
📚 Learning: 2025-12-17T01:18:07.265Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/contracts/.cursor/rules/contracts.mdc:0-0
Timestamp: 2025-12-17T01:18:07.265Z
Learning: Applies to packages/contracts/**/*.t.sol : Test cross-chain functionality
Applied to files:
packages/contracts/test/account/DMGating.t.sol
📚 Learning: 2025-12-17T01:18:07.265Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/contracts/.cursor/rules/contracts.mdc:0-0
Timestamp: 2025-12-17T01:18:07.265Z
Learning: Applies to packages/contracts/**/*.t.sol : Write comprehensive unit tests
Applied to files:
packages/contracts/test/account/DMGating.t.sol
📚 Learning: 2025-12-17T01:18:07.265Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/contracts/.cursor/rules/contracts.mdc:0-0
Timestamp: 2025-12-17T01:18:07.265Z
Learning: Applies to packages/contracts/**/*.t.sol : Test all edge cases
Applied to files:
packages/contracts/test/account/DMGating.t.sol
📚 Learning: 2025-12-06T08:15:28.770Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/contracts/AGENTS.md:0-0
Timestamp: 2025-12-06T08:15:28.770Z
Learning: Applies to packages/contracts/test/**/*.t.sol : Test permission and access control logic thoroughly including edge cases and unauthorized access attempts
Applied to files:
packages/contracts/test/account/DMGating.t.sol
📚 Learning: 2025-12-17T01:18:07.265Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/contracts/.cursor/rules/contracts.mdc:0-0
Timestamp: 2025-12-17T01:18:07.265Z
Learning: Applies to packages/contracts/**/*.t.sol : Test permission/access control logic
Applied to files:
packages/contracts/test/account/DMGating.t.sol
📚 Learning: 2025-12-06T08:15:28.770Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/contracts/AGENTS.md:0-0
Timestamp: 2025-12-06T08:15:28.770Z
Learning: Applies to packages/contracts/test/**/*.t.sol : Write comprehensive unit tests for all functionality with fuzz testing for numeric inputs using 4096 test runs minimum
Applied to files:
packages/contracts/test/account/DMGating.t.sol
📚 Learning: 2025-11-25T08:45:45.263Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/contracts/.cursor/rules/design-philosophy.mdc:0-0
Timestamp: 2025-11-25T08:45:45.263Z
Learning: Applies to packages/contracts/**/*.sol : Reduce cognitive load by making facet interfaces self-documenting and isolating storage layouts so developers don't need extensive context to complete tasks
Applied to files:
packages/contracts/scripts/deployments/facets/DeployDMGatingFacet.s.sol
📚 Learning: 2025-12-06T08:15:28.770Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/contracts/AGENTS.md:0-0
Timestamp: 2025-12-06T08:15:28.770Z
Learning: Applies to packages/contracts/src/**/*.sol : Organize contract code with separate Storage library, Base contract with internal logic, and Facet contract with external interface
Applied to files:
packages/contracts/scripts/deployments/facets/DeployDMGatingFacet.s.sol
📚 Learning: 2025-10-23T02:55:15.291Z
Learnt from: giuseppecrj
Repo: towns-protocol/towns PR: 4339
File: packages/contracts/src/apps/facets/factory/AppFactoryBase.sol:73-86
Timestamp: 2025-10-23T02:55:15.291Z
Learning: In packages/contracts/src/apps/facets/factory/AppFactoryBase.sol, the separate deploy + initialize pattern (deployERC1967BeaconProxy followed by ITownsApp.initialize) is the correct approach for beacon proxies. LibClone overloads with additional arguments use immutable args (constructor parameters), not initialization calldata, so they cannot be used for initializable proxy patterns.
Applied to files:
packages/contracts/scripts/deployments/facets/DeployDMGatingFacet.s.sol
🔇 Additional comments (8)
packages/contracts/src/account/facets/dm/ICriteria.sol (1)
1-31: Clean, minimal interface.Well-designed interface following best practices. NatSpec is complete, functions are appropriately scoped, and the abstraction is clear.
packages/contracts/scripts/deployments/diamonds/DeployAccountModules.s.sol (1)
74-76: DMGatingFacet integration follows established patterns.Consistent with existing facet deployment conventions. Properly adds selectors, queues deployment, and provides init data.
Also applies to: 89-89, 122-127
packages/contracts/src/account/facets/dm/IDMGating.sol (1)
1-48: Solid interface design.Minimal surface area, complete NatSpec, and proper type reuse from DMGatingMod for CombinationMode.
packages/contracts/scripts/deployments/facets/DeployDMGatingFacet.s.sol (1)
1-38: Deployment helper follows established conventions.Selector count matches reserved capacity (7), init data encoding is correct, and deploy pattern is consistent with other facet deployers.
packages/contracts/src/account/facets/dm/DMGatingFacet.sol (1)
14-75: Clean facet implementation.Thin external layer properly delegates to DMGatingMod. Reentrancy guards on state-changing functions, interface registration in init. Follows the pattern.
packages/contracts/test/account/DMGating.t.sol (1)
1-368: Comprehensive test coverage.Good coverage of success paths, error conditions, AND/OR modes, and allowlist integration. Fuzz testing for addresses is appropriate given the feature's input types.
packages/contracts/src/account/facets/dm/DMGatingMod.sol (1)
59-78: Storage layout follows diamond storage best practices.ERC-7201 namespaced storage slot, proper assembly accessor, and clear Layout struct documentation.
packages/contracts/src/account/criteria/AllowlistCriteria.sol (1)
44-50: LGTM — remaining functions are correctly implemented.
canDMcorrectly checks recipient's allowlist for sender.addToAllowlist/removeFromAllowlistproperly usemsg.senderfor self-modification.- View functions are safe and well-documented.
_addAddressesvalidates againstaddress(0)and emits events appropriately.Also applies to: 83-99, 101-132, 138-151
12f1852 to
dede117
Compare
Implement DMGatingFacet that allows users to control who can DM them through installable criteria modules. Users can configure AND/OR evaluation modes with a hard limit of 8 criteria per account. Default behavior blocks all DMs until at least one criteria is installed. Includes AllowlistCriteria for explicit address allowlists. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Updated AllowlistCriteria to require an authorized DMGating module for onInstall and onUninstall functions, preventing unauthorized modifications. - Added a constructor to initialize the DMGating module address. - Introduced a modifier to restrict access to DMGating functions. - Updated tests to reflect the new constructor requirements for AllowlistCriteria.
… related logic - Renamed the function canReceiveDMFrom to isEntitled for clarity in the DM gating logic. - Updated the function signature to include the receiver address. - Adjusted internal logic to reflect the new naming and ensure correct criteria checks. - Modified tests to align with the new function name and behavior. This change enhances the readability and understanding of the DM gating functionality.
dede117 to
92219df
Compare

Summary
Test plan
🤖 Generated with Claude Code