Facet
Modular logic contracts in the Diamond Standard that contain specific functionality accessed through the diamond proxy.
Facets are the modular implementation contracts in the Diamond Standard (EIP-2535) that contain actual business logic and functionality. Each facet represents a distinct domain or feature set within the larger protocol, accessed through the diamond proxy contract via delegatecall. This architectural pattern enables protocols to organize complex functionality into manageable, independently upgradeable modules while presenting a single interface to users and external contracts.
The term "facet" metaphorically references how a diamond's many cut surfaces work together to form a complete gem. Similarly, in the Diamond Standard, multiple facet contracts combine to provide the full functionality of the protocol, all accessible through the single diamond proxy address. This design allows protocols to exceed Ethereum's 24KB contract size limit while maintaining clean separation of concerns.
Structure and Implementation
Facets are standard Solidity contracts that implement specific protocol functions, but they're designed to operate within the diamond's storage context. Unlike standalone contracts that manage their own storage, facets must use diamond storage patterns to ensure their state variables don't collide with other facets' storage when executed via delegatecall from the diamond proxy.
The diamond storage pattern typically involves defining a struct that contains all storage variables for a facet, then storing that struct at a specific storage position calculated by hashing a unique string or constant. This ensures each facet's storage occupies a distinct region of the diamond's storage space. For example:
1library LibVaultStorage {2 bytes32 constant VAULT_STORAGE_POSITION =3 keccak256("diamond.storage.vault");45 struct VaultStorage {6 uint256 totalAssets;7 mapping(address => uint256) userShares;8 // ... other vault-specific state9 }1011 function vaultStorage()12 internal13 pure14 returns (VaultStorage storage vs)15 {16 bytes32 position = VAULT_STORAGE_POSITION;17 assembly {18 vs.slot := position19 }20 }21}
Facets typically focus on specific functional domains. A vault facet might implement deposit, withdrawal, and accounting functions for tokenized vaults. A swap facet handles token exchange logic. A governance facet manages voting and proposal execution. This domain-driven organization makes codebases easier to understand, audit, and upgrade incrementally.
Facet Management and Upgrades
The diamond proxy manages facets through a process called diamond cutting, which adds, replaces, or removes facets and their associated function selectors. The cut operation modifies the diamond's internal mapping that routes function calls to their implementing facets. This enables surgical upgrades—changing a single function's implementation without touching other functionality.
When adding a new facet, the diamond cut operation registers the facet's contract address and maps each of its function selectors to that address. When replacing a facet, the operation updates the selector mappings to point to the new facet address. When removing a facet, the operation deletes selector mappings, making those functions unavailable on the diamond. All facet management operations should be strictly access-controlled to prevent unauthorized modifications.
Facet introspection through the loupe facet allows external parties to query the diamond's current configuration. The loupe provides functions to list all facets, retrieve all function selectors for a specific facet, and identify which facet implements a particular function. This transparency is essential for users and auditors to verify a diamond's current state and understand what code is actually being executed.
Security Considerations in Facet Design
Facets introduce security challenges distinct from traditional smart contracts. Storage isolation is paramount—facets must never use raw storage slots through standard Solidity variable declarations. Even a single incorrectly placed variable can collide with another facet's storage, leading to state corruption that's extremely difficult to diagnose. Auditing facets requires careful verification that all storage access goes through properly structured diamond storage patterns.
Inter-facet dependencies create complex security relationships. If Facet A's function calls a function in Facet B, auditors must analyze what happens if Facet B is upgraded or removed. Can Facet A handle a revert from Facet B gracefully? Does Facet A make security assumptions about Facet B's behavior that a malicious upgrade could violate? The article's discussion of auditing the Burve Protocol emphasizes treating each facet as an independent unit while carefully tracking these cross-facet interactions.
Function selector conflicts can occur if two facets attempt to register the same 4-byte function selector. While accidental collisions between properly named functions are extremely rare (birthday paradox makes this unlikely with 4-byte selectors), malicious facets could intentionally create collisions to hijack calls. Diamond implementations must validate during diamond cuts that new function selectors don't conflict with existing mappings.
Initialization vulnerabilities affect facets just like regular upgradeable contracts. Facets typically need initialization functions to set up their storage state when first added to a diamond. These initializers must be protected against replay—if an initializer can be called multiple times, attackers might reset critical state variables or grant themselves unauthorized permissions. Some patterns use initialization flags in diamond storage to prevent re-initialization.
Auditing Facets Effectively
The competitive audit experience described in the article provides valuable methodology for auditing facet-based protocols. The recommended approach involves first understanding the diamond's overall architecture—how many facets exist, what each facet's responsibility is, and how they interact. This holistic view prevents missing vulnerabilities that span multiple facets.
Next, audit each facet as an isolated contract while maintaining awareness of the broader system. The article describes this as treating each facet like a familiar "~500 nSLOC audit," which is psychologically more manageable than confronting a 4,000+ line monolith. For each facet, verify storage pattern correctness, analyze function logic for standard vulnerabilities, and document all external calls and dependencies.
Testing facets with tools like Foundry requires special consideration for the diamond context. Tests should cover both isolated facet behavior and integrated diamond behavior. Foundry's vm.etch and vm.prank cheatcodes enable sophisticated testing scenarios that verify facets behave correctly when called through the diamond proxy with various storage states.
Common Facet Patterns and Examples
Real-world diamond implementations typically include several standard facet types. Core protocol facets implement the main business logic—in a DEX this might be swap and liquidity facets, in a lending protocol it might be borrow and liquidation facets. The Burve Protocol mentioned in the article used a VaultE4626 facet to implement ERC-4626 vault functionality.
Administrative facets handle protocol configuration, parameter updates, and emergency controls. These facets should have the strictest access controls since they can modify critical protocol settings. Audits should verify that administrative functions can't be abused to extract value or permanently damage the protocol.
Diamond management facets (diamond cut and loupe) are meta-facets that manage the diamond itself. The diamond cut facet must be audited extremely carefully as it controls all future upgrades. The loupe facet, while primarily informational, should be verified to return accurate data about the diamond's current configuration.
Understanding facets requires recognizing them as both independent contracts and interdependent components of a larger system. The modularity they provide enables cleaner code organization and flexible upgrades, but this flexibility introduces security complexity that demands systematic auditing. The success story in the article demonstrates that mastering facet-based architecture—through mentorship, research, and hands-on analysis—transforms seemingly insurmountable codebases into manageable, auditable systems.
Articles Using This Term
Learn more about Facet in these articles:
Related Terms
Need expert guidance on Facet?
Our team at Zealynx has deep expertise in blockchain security and DeFi protocols. Whether you need an audit or consultation, we're here to help.
Get a Quote

