standard · execution

LUKSO LSP17 Contract Extension Standard

LSP·17 · Execution

Fallback router by function selector. Grow a deployed contract without an upgrade key.

LSP·17 interface solidity
// 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.

Read the source.