Skip to content

Add LSP-33 (Music NFT Metadata), LSP-34 (Minting Delegation), and LSP-35 (Identifiable Digital Asset Entanglement)#319

Open
emmet-bot wants to merge 14 commits into
lukso-network:mainfrom
emmet-bot:lsp-33-34-music-nft-external-ownership
Open

Add LSP-33 (Music NFT Metadata), LSP-34 (Minting Delegation), and LSP-35 (Identifiable Digital Asset Entanglement)#319
emmet-bot wants to merge 14 commits into
lukso-network:mainfrom
emmet-bot:lsp-33-34-music-nft-external-ownership

Conversation

@emmet-bot
Copy link
Copy Markdown

@emmet-bot emmet-bot commented Apr 1, 2026

Summary

This PR introduces three LUKSO Standard Proposals that work together for music NFTs while remaining independently useful:

LSP-33: Music NFT Metadata (Pure Metadata Standard)

Defines the metadata schema for representing music releases and tracks:

  • LSP33Metadata data key: Structured music metadata (contributors, industry identifiers, copyright, lyrics, preview, stems, DDEX references)
  • LSP4 extensions: Required attributes for music (category: Music, artist, release type, genre, etc.)
  • AI classification (DDEX ERN 4.3.2): audio_ai_usage, composition_ai_usage, commercial_samples, and per-contributor ai_contribution fields
  • Industry compatibility: Maps to DDEX ERN, ISRC, ISWC, GRid, UPC for DSP interoperability
  • Standalone or combined: Can be used on any LSP7/LSP8 token, or combined with LSP-35 for advanced entanglement

LSP-34: Minting Delegation

A mechanism for delegating minting rights only to an external address:

  • Single data key LSP34MintingSource(address, bytes32)
  • If tokenId ≠ 0: minting rights go to tokenOwnerOf(tokenId) on the source LSP8
  • If tokenId = 0: minting rights go to owner() on the source contract
  • Does NOT transfer ownership — the contract owner() stays unchanged
  • Does NOT grant setData rights — metadata control stays with the original artist/owner
  • Solves the "token owner vs artist" problem: collectors can mint editions, artists keep metadata control

LSP-35: Identifiable Digital Asset Entanglement

Defines how an LSP8 collection can structurally link to LSP7 tokens:

  • LSP35OwnableToken data key: Points from an LSP8 tokenId to a linked LSP7 contract
  • Transparent data routing: getDataForTokenId/setDataForTokenId proxy to the linked LSP7
  • Bidirectional verification: LSP7 has LSP8ReferenceContract pointing back
  • Uses LSP-34 for minting delegation (not ownership transfer)

Authorization Model (Critical Fix)

This architecture cleanly separates concerns:

Role Can Do Cannot Do
Artist (contract owner) Set metadata, configure the release
Track owner (via LSP8 tokenOwnerOf + LSP-34) Mint LSP7 editions Modify metadata
Collectors (LSP7 unit holders) Transfer their units Mint, modify metadata

Reference Implementation

See lukso-network/lsp-smart-contracts#1088 for LSP7MusicNFT and LSP8MusicNFT extension contracts.


Status: Draft
Authors: Fabian Vogelsteller fabian@universaleverything.io, Thomas Beard thomas@universaleverything.io
Discussion: https://t.me/+PjX_Awnpjh8xYWE0

…ations

LSP-33 defines a composable standard for music releases and tracks using
LSP8 collections (releases) with LSP7 contracts (ownable track editions).
Features transparent data routing between LSP8 and linked LSP7, structured
music metadata (LSP33Metadata), industry standard integration (DDEX, ISRC),
and contributor roles with Universal Profile linking.

LSP-34 defines a generic mechanism for any ERC725Y contract to derive its
owner from an external contract (LSP8 tokenOwnerOf or ERC173 owner),
enabling ownership delegation without manual synchronization.
@emmet-bot
Copy link
Copy Markdown
Author

Reference implementation for both LSP-33 and LSP-34 is available at lukso-network/lsp-smart-contracts#1088.

Includes:

  • LSP8MusicNFT extension — transparent metadata routing (read proxy + write forwarding), bidirectional link verification
  • LSP7MusicNFT extension — LSP34 external ownership, parent collection authorization for setData
  • 27 Foundry tests (13 LSP8 + 14 LSP7), all passing

Discussion: https://t.me/+PjX_Awnpjh8xYWE0

@emmet-bot
Copy link
Copy Markdown
Author

🔒 Security Audit — LSP-33 & LSP-34 Specifications

Scope

  • LSP-33 Music NFT specification
  • LSP-34 External Ownership specification

🟡 MEDIUM — LSP34 Ownership Clearing: Spec Says "SHOULD set local owner" But No Mechanism Defined

File: LSP-34, LSP34OwnershipSource requirements

The spec states: "When removed (set to empty bytes), the contract SHOULD fall back to the local owner variable. The local owner SHOULD be set to the last resolved external owner before clearing, to prevent ownership loss."

However, there is no specified function or procedure for clearing LSP34OwnershipSource safely. Since setData is restricted to owner() (which resolves via LSP34), and transferOwnership is blocked while LSP34 is active, there's a chicken-and-egg problem:

  1. The current owner (resolved via LSP34) calls setData to clear LSP34OwnershipSource
  2. But setData cannot atomically update _owner and clear LSP34 in one step — they're different operations
  3. After clearing, owner() falls back to whatever _owner was set to at construction time

Recommendation: Specify a clearExternalOwnership() function that atomically: (1) resolves current owner(), (2) sets local _owner to that address, (3) clears LSP34OwnershipSource. Alternatively, state that LSP34 is intended to be permanent (set-once).


🟡 MEDIUM — Write Forwarding Event Ambiguity

File: LSP-33, Data Routing Behavior, setDataForTokenId

The spec says writes to LSP4Metadata/LSP33Metadata are forwarded to the LSP7 via setData(). It does not specify whether TokenIdDataChanged should be emitted on the LSP8 for forwarded writes. This creates ambiguity:

  • Indexers watching the LSP8 for TokenIdDataChanged events won't see forwarded metadata updates
  • But the LSP7 will emit its own DataChanged event
  • Frontends need to know: listen to LSP8 events? LSP7 events? Both?

Recommendation: Add a note specifying event behavior. Either: (a) the LSP8 SHOULD emit TokenIdDataChanged even for forwarded writes (for discoverability), or (b) explicitly state that consumers should listen to the linked LSP7's DataChanged events for metadata updates.


🟡 MEDIUM — Circular Ownership Resolution Depth Not Enforced in LSP-33 Context

File: LSP-34, Security Considerations

The spec says: "Implementations SHOULD set a maximum resolution depth of 1 hop." However, in the LSP-33 context, the resolution chain is: LSP7 → LSP8 → artist's UP. If the artist's UP itself uses LSP34 (e.g., a DAO-controlled profile), you get 2 hops: LSP7 → LSP8 → UP → DAO. The spec should clarify:

  • Is 1 hop from the LSP7's perspective (LSP7 → LSP8), or 1 hop total including the chain?
  • What happens if tokenOwnerOf on the LSP8 itself involves resolution?

Recommendation: Clarify that 1 hop means the LSP34 contract makes exactly 1 external call. The resolved tokenOwnerOf result is the final answer regardless of whether that address itself uses LSP34 internally.


🟢 LOW — LSP33OwnableTrackToken Link Immutability Not Enforced

File: LSP-33, LSP33OwnableTrackToken requirements

The spec says: "Once set, it is RECOMMENDED not to change this value." But RECOMMENDED (SHOULD) is weaker than MUST. In practice, replacing a linked LSP7 would orphan existing token holders — they'd hold tokens in an LSP7 that no longer receives routing from the LSP8.

Recommendation: Consider upgrading to MUST NOT change once set (if LSP7 has non-zero totalSupply). Alternatively, specify that implementations SHOULD verify totalSupply() == 0 on the existing LSP7 before allowing a relink.


🟢 LOW — No Specification for LSP7 Token Transfer Restrictions

File: LSP-33, LSP7 Contract

The spec says the LSP7 is for "ownable units" of a track but does not specify any transfer restrictions. All LSP7 tokens are freely transferable by default. Consider whether:

  • Transfer of LSP7 tokens should be restricted until the artist explicitly enables it (like a "sale" start)
  • There should be a way to freeze transfers (e.g., for compliance)

Recommendation: Mention that implementations MAY combine LSP7MusicNFT with existing LSP7 extensions (LSP7NonTransferable, LSP7CappedSupply, etc.) for additional restrictions. This composability is a feature, not a gap — but worth noting.


🟢 LOW — Metadata File Integrity: Single JSON File Referenced by Two Data Keys

File: LSP-33, Metadata

Both LSP4Metadata and LSP33Metadata SHOULD point to the same JSON file. But there's no on-chain enforcement. A malicious or buggy implementation could set them to different files, causing metadata inconsistency.

Recommendation: This is by design (flexibility), but add a note that validators/indexers SHOULD warn when the two VerifiableURIs resolve to different files.


🟢 LOW — bytes32(0) TokenId Ambiguity in LSP34

File: LSP-34, Owner Resolution

The spec uses bytes32(0) as a sentinel value meaning "call owner() instead of tokenOwnerOf()". But in LSP8, bytes32(0) could be a valid tokenId (uint256 encoded as bytes32 = 0). If someone creates an LSP8 where tokenId 0 exists, setting LSP34OwnershipSource to (lsp8Address, bytes32(0)) would incorrectly call owner() instead of tokenOwnerOf(bytes32(0)).

Recommendation: Add a note that bytes32(0) is reserved as the "no tokenId" sentinel. Implementations using sequential uint256 tokenIds SHOULD start from 1, not 0.


ℹ️ INFORMATIONAL — Contributor Role Extensibility vs Indexer Compatibility

The contributor roles array is extensible ("any role MAY be used"). While flexible, this means indexers cannot reliably categorize contributors without maintaining a growing role vocabulary. Standard DDEX roles are well-defined; non-standard roles will be displayed as-is.

Not a security issue — just a DX consideration for ecosystem tooling.


Summary

Severity Count Key Issues
🟡 MEDIUM 3 LSP34 clearing mechanism, event ambiguity, circular resolution depth
🟢 LOW 4 Link immutability, transfer restrictions, metadata integrity, bytes32(0) ambiguity
ℹ️ INFO 1 Role extensibility vs indexer compatibility

Both specifications are well-designed and compose existing LSP primitives effectively. The issues found are primarily around under-specified edge cases that should be clarified before moving from Draft to Review status.

LSP-33:
- Add Event Behavior section (LSP8 does not emit TokenIdDataChanged for forwarded writes)
- Require immutable parent collection cache in LSP7 requirements
- Document parent collection auth uses cached immutable, not LSP8ReferenceContract
- Add Address Encoding section (20-byte and 32-byte formats)

LSP-34:
- Clarify transferOwnership/renounceOwnership MUST (not SHOULD) fallback to ERC173
- Define 1-hop resolution depth precisely
- Add bytes32(0) tokenId reservation note
- Recommend immutable cache for source contract address
- Improve source contract availability guidance (catch revert + fallback)
…wner

- Access control: caller must be tokenOwnerOf(tokenId), consistent with LSP7/LSP34
- Updated flow diagram to show token-owner auth
- LSP33OwnableTrackToken settable by tokenId owner
- When track transfers, new owner controls metadata automatically
Comment thread LSPs/LSP-33-MusicNFT.md Outdated

_Requirements:_

- MUST only be callable by the current owner of the specific `tokenId` (as returned by `tokenOwnerOf(tokenId)`), **not** the contract-level `owner()`. This is consistent with LSP7's access model, where `owner()` resolves to the same `tokenOwnerOf` result via LSP34. When a track is transferred, the new token owner automatically gains control over that track's metadata.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Design issue: Token Owners Can Overwrite Artist Metadata

The current design gives setDataForTokenId access to tokenOwnerOf(tokenId), meaning whoever owns a track NFT can overwrite all metadata — title, artists, ISRC, lyrics, copyright, contributors, etc.

When a track is transferred, the new token owner automatically gains control over that track's metadata.

This conflates two separate concerns:

  • Edition control (minting, transferring LSP7 tokens) → should belong to token owner
  • Creative metadata (song info, credits, identifiers) → should belong to the artist

Concrete scenario: Artist X releases Album Y with 12 tracks. Collector Z buys tokenId 1. Collector Z can now rename the track, change credited artists, overwrite the ISRC, and replace the lyrics. This breaks the trust model for music NFTs.

Proposed fix: Split authorization so that:

  1. setDataForTokenId requires the contract-level owner (artist), not the token owner
  2. LSP7 owner() still resolves via LSP34 for minting control only
  3. LSP7 setData is callable only by the parent LSP8 (artist-controlled), not by the resolved token owner

This preserves the elegant LSP34 ownership delegation for edition minting while keeping creative metadata under artist control.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the idea is that owning the track is actually only done by the artist. If you want to own a track, the track should have an LSP7.

But I like the idea about using the owner only for minting.
Yeah, your two fixes are actually very good.

- Add Ownership Model section in Abstract with table and ASCII diagram
- Clarify: LSP8 tokenId = artist ownership (authorship, metadata control)
- Clarify: LSP7 units = collector ownership (tradeable copies, no metadata control)
- Add complete Release metadata JSON example with all fields
- Add complete Track metadata JSON example with all LSP33 fields (contributors, identifiers, copyright, lyrics, preview, stems, ddex)
- Update Overview diagrams with ownership labels
- Add 'Artist vs Collector Ownership' rationale section
- Improve readability throughout

Addresses feedback from PR review about artist/user ownership confusion.
- Default framing: separate files with separate data keys
- Note that combining into one JSON is optional optimization
- Split examples into 4 separate files (release LSP4, release LSP33, track LSP4, track LSP33)
- Update all references from 'same JSON file' to 'separate data key'
Split conflated concerns and fix the authorization model:

- LSP-33 becomes pure music metadata (LSP33Metadata schema, LSP4 attributes,
  AI classification fields, contributors, identifiers, etc.). No linking
  or routing logic.
- LSP-34 grants only mint() rights to the resolved external address. The
  contract owner() stays as standard ERC173 — setData and ownership
  transfer remain restricted to the artist. Title renamed to
  "External Minting Rights".
- LSP-35 (new) is "Identifiable Digital Asset Entanglement": a generic
  LSP8 <-> LSP7 linking standard with transparent metadata routing and
  bidirectional link verification. Data key renamed from
  LSP35OwnableTrackToken (music-specific) to LSP35OwnableToken (generic).
  setDataForTokenId is gated by the LSP8 contract owner() — NOT by
  tokenOwnerOf — so collectors who acquire a tokenId cannot rewrite
  the artist's metadata.

The previous model let token owners overwrite artist metadata, which
broke the artist-vs-collector separation. The new three-role model
makes authorship (artist / contract owner), minting (LSP8 tokenId
holder, via LSP34), and collectibility (LSP7 unit holders) cleanly
independent.
@emmet-bot emmet-bot changed the title Add LSP-33 (Music NFT) and LSP-34 (External Ownership) draft specifications Add LSP-33 (Music NFT Metadata), LSP-34 (Minting Delegation), and LSP-35 (Identifiable Digital Asset Entanglement) Apr 9, 2026
@rand0m-us3r
Copy link
Copy Markdown

Sick

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants