Smart Contract

FlunksGraduation

A.807c3d470888cc48.FlunksGraduation

Deployed

1w ago
Feb 19, 2026, 10:24:09 AM UTC

Dependents

2 imports
1// SPDX-License-Identifier: MIT
2
3import Flunks from 0x807c3d470888cc48
4import NonFungibleToken from 0x1d7e57aa55817448
5import HybridCustodyHelper from 0x807c3d470888cc48
6import MetadataViews from 0x1d7e57aa55817448
7
8pub contract FlunksGraduation {
9  pub event ContractInitialized()
10  pub event Graduate(address: Address, tokenID: UInt64, templateID: UInt64)
11  pub event GraduateTimeUpdate(tokenID: UInt64, time: UInt64)
12
13  pub let AdminStoragePath: StoragePath
14
15  access(self) var GraduatedFlunks: {UInt64: Bool}
16  access(self) var GraduationTime: {UInt64: UInt64}
17  access(self) var tokenIDToUri: {UInt64: String}
18
19  pub fun graduateFlunk(owner: AuthAccount, tokenID: UInt64) {
20    pre {
21      !FlunksGraduation.GraduatedFlunks.containsKey(tokenID):
22        "Flunk has already graduated"
23      FlunksGraduation.GraduationTime[tokenID] ?? 1682049600 <= UInt64(getCurrentBlock().timestamp):
24        "Not time yet"
25    }
26
27    // Force re-link collections
28    HybridCustodyHelper.forceRelinkCollections(signer: owner)
29
30    // Check if owner is the true owner of the NFT
31    let ownerCollectionTokenIds = HybridCustodyHelper.getFlunksTokenIDsFromAllLinkedAccounts(ownerAddress: owner.address)
32    if !ownerCollectionTokenIds.contains(tokenID) {
33      panic("Not owner")
34    }
35
36    let trueOwnerAddress = HybridCustodyHelper.getChildAccountAddressHoldingFlunksTokenId(ownerAddress: owner.address, tokenID: tokenID)
37      ?? panic("Could not find true owner for specified tokenID")
38
39    let trueOwnercollection = getAccount(trueOwnerAddress).getCapability<&Flunks.Collection{NonFungibleToken.CollectionPublic}>(Flunks.CollectionPublicPath).borrow()
40      ?? panic("Could not borrow a reference to the account's NFT collection")
41    let item = trueOwnercollection.borrowNFT(id: tokenID)
42
43    let serialView = item.resolveView(Type<MetadataViews.Serial>())
44        ?? panic("Could not get the item's serial view")
45    let serial = serialView as! MetadataViews.Serial
46    let itemTemplateId = serial.number
47    let itemTemplate = Flunks.getFlunksTemplateByID(templateID: itemTemplateId)
48
49    // Update the NFT metadata and traits on-chain
50    let admin = self.account.borrow<&Flunks.Admin>(from: Flunks.AdminStoragePath)
51      ?? panic("Could not borrow a reference to the Flunks Admin")
52    let adminSet = admin.borrowSet(setID: itemTemplate.addedToSet)
53    
54    let newMetadata = Flunks.getFlunksTemplateByID(templateID: itemTemplateId).getMetadata()
55    newMetadata["Type"] = "Graduated"
56    newMetadata["pixelUri"] = newMetadata["uri"]
57    newMetadata["uri"] = FlunksGraduation.tokenIDToUri[tokenID]!
58    adminSet.updateTemplateMetadata(templateID: itemTemplateId, newMetadata: newMetadata)
59    // Graduate Flunks
60    FlunksGraduation.GraduatedFlunks[tokenID] = true
61    FlunksGraduation.GraduationTime.remove(key: tokenID)
62    emit Graduate(address: owner.address, tokenID: tokenID, templateID: itemTemplateId)
63  }
64
65  pub fun isFlunkGraduated(tokenID: UInt64): Bool {
66    return FlunksGraduation.GraduatedFlunks[tokenID] ?? false
67  }
68
69  pub fun getFlunksGraduationTimeTable(): {UInt64: UInt64} {
70    return FlunksGraduation.GraduationTime
71  }
72
73  pub resource Admin {
74    pub fun updateGraduationTime(tokenID: UInt64, _timeInSeconds: UInt64) {
75      pre {
76        !FlunksGraduation.GraduatedFlunks.containsKey(tokenID):
77          "Flunk has already graduated"
78      }
79      FlunksGraduation.GraduationTime[tokenID] = _timeInSeconds
80
81      // emit GraduateTimeUpdate(tokenID: tokenID, time: _timeInSeconds)
82    }
83
84    pub fun setGraduatedUri(tokenID: UInt64, uri: String) {
85        if FlunksGraduation.GraduatedFlunks.containsKey(tokenID) {
86          return
87        }
88      FlunksGraduation.tokenIDToUri[tokenID] = uri
89    }
90
91    pub fun alfredGraduatesForYa(ownerAddress: Address, templateID: UInt64, tokenID: UInt64) {
92      // Check if owner is the true owner of the NFT
93      let ownerCollectionTokenIds = HybridCustodyHelper.getFlunksTokenIDsFromAllLinkedAccounts(ownerAddress: ownerAddress)
94      if !ownerCollectionTokenIds.contains(tokenID) {
95        panic("Not owner")
96      }
97
98      let trueOwnerAddress = HybridCustodyHelper.getChildAccountAddressHoldingFlunksTokenId(ownerAddress: ownerAddress, tokenID: tokenID)
99        ?? panic("Could not find true owner for specified tokenID")
100
101      let trueOwnercollection = getAccount(trueOwnerAddress).getCapability<&Flunks.Collection{NonFungibleToken.CollectionPublic}>(Flunks.CollectionPublicPath).borrow()
102        ?? panic("Could not borrow a reference to the account's NFT collection")
103      let item = trueOwnercollection.borrowNFT(id: tokenID)
104
105      let serialView = item.resolveView(Type<MetadataViews.Serial>())
106          ?? panic("Could not get the item's serial view")
107      let serial = serialView as! MetadataViews.Serial
108      let itemTemplateId = serial.number
109      let itemTemplate = Flunks.getFlunksTemplateByID(templateID: itemTemplateId)
110
111      // Update the NFT metadata and traits on-chain
112      let admin = FlunksGraduation.account.borrow<&Flunks.Admin>(from: Flunks.AdminStoragePath)
113        ?? panic("Could not borrow a reference to the Flunks Admin")
114      let adminSet = admin.borrowSet(setID: itemTemplate.addedToSet)
115      
116      let newMetadata = Flunks.getFlunksTemplateByID(templateID: itemTemplateId).getMetadata()
117      newMetadata["Type"] = "Graduated"
118      newMetadata["pixelUri"] = newMetadata["uri"]
119      newMetadata["uri"] = FlunksGraduation.tokenIDToUri[tokenID]!
120      adminSet.updateTemplateMetadata(templateID: templateID, newMetadata: newMetadata)
121      // Graduate Flunks
122      FlunksGraduation.GraduatedFlunks[tokenID] = true
123      FlunksGraduation.GraduationTime.remove(key: tokenID)
124      emit Graduate(address: ownerAddress, tokenID: tokenID, templateID: templateID)
125    }
126
127    pub fun refreshGraduatedMetadata(ownerAddress: Address, templateID: UInt64, tokenID: UInt64) {
128      emit Graduate(address: ownerAddress, tokenID: tokenID, templateID: templateID)
129    }
130  }
131
132  init() {
133    self.AdminStoragePath = /storage/FlunksGraduationAdmin
134    let admin <- create Admin()
135    self.account.save(<-admin, to: self.AdminStoragePath)
136
137    self.GraduatedFlunks = {}
138    self.GraduationTime = {}
139    self.tokenIDToUri = {}
140
141    emit ContractInitialized()
142  }
143}
144