LUKSO LSP17 Contract Extension Standard
LSP·17 · Execution
Fallback router by function selector. Grow a deployed contract without an upgrade key.
// The base contract's fallback() looks up an extension per selector.
// Extensions are registered via ERC-725Y data keys:
//
// LSP17Extension:<selector> → address (the extension contract)
//
// Two flavors:
// Extendable → CALL into the extension (clean separation)
// Extension → DELEGATECALL (shared storage; advanced)
LSP17 is the “grow without an upgrade key” primitive. When a call lands on an unknown function selector, the base contract’s fallback looks up the registered extension address in ERC-725Y data and forwards the call. The base bytecode is immutable; new behavior is a separate, individually permissioned contract.
This is the design choice that lets Universal Profiles add features (signature verification, hook delegates, new asset receivers) without proxies and without the permanent upgrade authority a UUPS proxy carries.
What it solves.
What it does not solve.
Anti-overselling is a feature.
- LSP17 isn't an upgrade primitive for the base bytecode. It adds *new* functions; it doesn't change existing ones.
- DELEGATECALL extensions share storage — you still need storage-layout discipline if you use that flavor.
- Registering an extension is a permissioned action. Who can do it depends on LSP6.
Companions.
Standards this composes with.