Extending deployed contracts.
Adding new function selectors to a deployed contract on LUKSO uses LSP17 Contract Extension. The base contract's fallback resolves the incoming function selector against an ERC-725Y-keyed registry of extension addresses and calls the matching extension. New capabilities ship as new extension contracts plus a permission-gated `setData` call — no admin upgrade key, no shared storage, no diamond-cut ceremony. LSP6 permissions control who can register or replace extensions. Different constraint model from ERC-2535 Diamonds and OpenZeppelin transparent proxies.
A Universal Profile is the canonical use case, but LSP17 is a general primitive. The base bytecode stays immutable; new selectors hit the fallback; the fallback looks up an extension contract registered in ERC-725Y data; the call is forwarded.
When this vertical fits
You’re shipping a contract that will need to grow — new asset receivers, new signature verifiers, new app-specific entry points — without surrendering a permanent upgrade key over the base bytecode. Or you’re extending a Universal Profile with custom behavior that should be registered per profile, not coded into the account.
The minimum stack
- LSP17 on the base contract (the fallback router)
- Extension contracts — one per selector you want to add
- LSP14 for safer ownership rotation of whoever can register extensions
- LSP6 when the registrant is a controller of a Universal Profile (the permission to write the registration key)
Reading list.
A curated path — problem → standard → migration.