For the complete documentation index, see llms.txt. This page is also available as Markdown.

Transferability & Update Rules

Lock collection permissions to make properties permanently immutable or permanently permitted

Category: Advanced

Summary

Controls whether collection properties can be changed after creation.

  • Two states: FROZEN (permanentlyForbiddenTimes: FOREVER) or NEUTRAL (empty [])

  • NEUTRAL [] = manager can update now AND can freeze it later. Use this for editable fields.

  • FROZEN = permanent and irreversible. Use for fields that should never change.

  • AVOID permanentlyPermittedTimes β€” it permanently prevents locking. Almost never needed.

  • canUpdateCollectionApprovals: controls transfer rule mutability

    • SECURITY: If manager can update Mint approvals, they can mint unlimited tokens

    • Default to frozen unless user requests updatable

  • List IDs in permissions: ONLY use reserved IDs ("All", "Mint", "!Mint", direct "bb1..." addresses)

  • permanentlyForbiddenTimes: [{ "start": "1", "end": "18446744073709551615" }] = frozen forever

Instructions

Transferability & Update Rules Configuration

When configuring collection permissions for transferability and update rules, you MUST follow these critical requirements:

Critical Permission Rules

canUpdateCollectionApprovals:

  • CRITICAL: Controls whether transfer rules (approvals) can be changed after creation

  • SECURITY RISK: If the manager can update approvals from the "Mint" address, they can mint any amount

  • DEFAULT: Should be forbidden (frozen) for collections where transfer rules should be locked

  • Format: Uses CollectionApprovalPermission format (see below)

CollectionApprovalPermission Format

Key Fields:

  • List IDs (fromListId, toListId, initiatedByListId): Use ONLY reserved list IDs:

    • "All" β€” Any address

    • "Mint" β€” Mint address

    • "!Mint" β€” Everything except Mint

    • "bb1..." β€” Direct address

    • "!bb1..." β€” Everything except the specific address

    • "bb1abc:bb1xyz" β€” Colon-separated addresses

    • DO NOT USE: Custom list IDs β€” only reserved IDs or direct addresses

  • approvalId: "All" to restrict all approvals, or a specific approvalId string

Example: Immutable Transfer Rules (All Frozen)

Example: Restricting Only Mint Approvals

Example: Restricting Specific Approval ID

Empty Permission Arrays β€” CRITICAL

IMPORTANT: If a permission entry has both permanentlyPermittedTimes and permanentlyForbiddenTimes as empty arrays, the entire permission entry is redundant and should be replaced with an empty array.

For ActionPermission (canDeleteCollection, canArchiveCollection, etc.):

  • Wrong: "canArchiveCollection": [{ "permanentlyPermittedTimes": [], "permanentlyForbiddenTimes": [] }]

  • Correct: "canArchiveCollection": []

For TokenIdsActionPermission (canUpdateTokenMetadata, canUpdateValidTokenIds):

  • Wrong: "canUpdateTokenMetadata": [{ "tokenIds": [...], "permanentlyPermittedTimes": [], "permanentlyForbiddenTimes": [] }]

  • Correct: "canUpdateTokenMetadata": []

For CollectionApprovalPermission (canUpdateCollectionApprovals):

  • If both time arrays are empty, use empty array: "canUpdateCollectionApprovals": []

Permission Presets

Three common permission configurations:

1. Fully Immutable β€” Everything frozen. Nothing can change after creation.

  • ALL permissions set to permanentlyForbiddenTimes: FOREVER

  • Use when: the collection should never change

2. Manager Controlled β€” Manager can change everything except delete.

  • canDeleteCollection: frozen

  • Everything else: NEUTRAL [] (editable now, can be frozen later)

  • Use when: the manager needs full control (issuer-controlled tokens, evolving collections)

3. Locked Approvals (recommended default) β€” Approvals and supply frozen, metadata editable.

  • canDeleteCollection: frozen

  • canUpdateStandards: frozen

  • canUpdateManager: frozen

  • canUpdateValidTokenIds: frozen

  • canUpdateCollectionApprovals: frozen

  • canUpdateCollectionMetadata: NEUTRAL []

  • canUpdateTokenMetadata: NEUTRAL []

  • canArchiveCollection: NEUTRAL []

  • canUpdateCustomData: NEUTRAL []

  • Use when: supply and rules should be immutable but metadata needs updates

Understanding permission states:

  • Empty array [] = NEUTRAL (manager can update now AND can lock it later β€” preserves maximum flexibility)

  • permanentlyForbiddenTimes: FOREVER = FROZEN (can never be changed β€” permanent and irreversible)

  • permanentlyPermittedTimes: FOREVER = PERMANENTLY ALLOWED (can never be frozen β€” almost never needed)

IMPORTANT: For editable fields, ALWAYS use NEUTRAL (empty []) instead of permanentlyPermittedTimes. Neutral gives the same current behavior (manager can update) but preserves the option to freeze it later. Only use permanentlyPermittedTimes if the user explicitly requests a guarantee that a field can never be locked.

Security Considerations

  • Mint Transfer Rules: If canUpdateCollectionApprovals is allowed for Mint, the manager could mint unlimited tokens

  • Post-Mint Transfer Rules: If post-mint transfer rules can be updated, the manager could change transferability

  • Best Practice: Default to locked (frozen) transfer rules unless user explicitly requests updatable rules

  • Only allow updates for dynamic collections where the user explicitly requests flexibility

Common Mistakes

  • DON'T use custom list IDs in permissions β€” only reserved IDs: "All", "Mint", "!Mint", or direct bb1... addresses.

  • DON'T leave both permanentlyPermittedTimes and permanentlyForbiddenTimes as empty arrays in a permission entry β€” this is redundant. Replace the entire entry with an empty array [].

  • DON'T forget that unfrozen Mint approval permissions means the manager can mint unlimited tokens β€” freeze canUpdateCollectionApprovals for Mint if supply should be fixed.

  • DON'T confuse empty permission array [] (neutral/unset) with a frozen permission β€” empty means the field is still updatable.

Last updated