Smart Contract

TeamAssignment

A.8d75e1dff5f8af66.TeamAssignment

Valid From

136,156,145

Deployed

5d ago
Feb 23, 2026, 12:58:00 AM UTC

Dependents

2 imports
1// TeamAssignment.cdc
2// Smart contract for randomly assigning NBA Top Shot usernames to NBA teams
3// Uses Flow's on-chain randomness (revertibleRandom)
4
5access(all) contract TeamAssignment {
6    
7    // Event emitted when an assignment is made
8    access(all) event AssignmentMade(username: String, team: String, assignmentIndex: UInt64)
9    
10    // Event emitted when all assignments are complete
11    access(all) event AllAssignmentsComplete(assignments: {UInt64: Assignment})
12    
13    // Assignment structure
14    access(all) struct Assignment {
15        access(all) let username: String
16        access(all) let team: String
17        access(all) let assignmentIndex: UInt64
18        access(all) let timestamp: UFix64
19        
20        init(username: String, team: String, assignmentIndex: UInt64, timestamp: UFix64) {
21            self.username = username
22            self.team = team
23            self.assignmentIndex = assignmentIndex
24            self.timestamp = timestamp
25        }
26    }
27    
28    // Storage for all assignments
29    access(all) var assignments: {UInt64: Assignment}
30    
31    init() {
32        self.assignments = {}
33    }
34    
35    // Main function: Randomly assign all usernames to teams in one transaction
36    // This function uses Flow's revertibleRandom() for on-chain randomness
37    // Combos are passed as arrays of two-team strings like ["Team1, Team2", "Team3, Team4"]
38    access(all) fun assignAllRandomly(usernames: [String], teams: [String], combos: [String]): {UInt64: Assignment} {
39        pre {
40            usernames.length > 0: "Must provide at least one username"
41            (teams.length + combos.length) == usernames.length: "Number of single teams plus combos must equal number of usernames"
42        }
43        
44        var remainingUsernames = usernames
45        var remainingSingleTeams = teams
46        var remainingCombos = combos
47        var result: {UInt64: Assignment} = {}
48        var index: UInt64 = 0
49        let currentTime = getCurrentBlock().timestamp
50        
51        // Combine single teams and combos into one pool for random assignment
52        var allAssignments: [String] = []
53        var i = 0
54        while i < remainingSingleTeams.length {
55            allAssignments.append(remainingSingleTeams[i])
56            i = i + 1
57        }
58        i = 0
59        while i < remainingCombos.length {
60            allAssignments.append(remainingCombos[i])
61            i = i + 1
62        }
63        
64        // Loop through and assign each username to a random team or combo
65        while remainingUsernames.length > 0 {
66            // Get random index for username selection
67            let usernameRandomValue = revertibleRandom<UInt64>()
68            let usernameIndex = usernameRandomValue % UInt64(remainingUsernames.length)
69            
70            // Get random index for assignment selection (team or combo)
71            let assignmentRandomValue = revertibleRandom<UInt64>()
72            let assignmentIndex = assignmentRandomValue % UInt64(allAssignments.length)
73            
74            // Get the selected username and assignment (team or combo)
75            let selectedUsername = remainingUsernames[Int(usernameIndex)]
76            let selectedAssignment = allAssignments[Int(assignmentIndex)]
77            
78            // Create assignment
79            let assignment = Assignment(
80                username: selectedUsername,
81                team: selectedAssignment,
82                assignmentIndex: index,
83                timestamp: currentTime
84            )
85            
86            // Store assignment
87            result[index] = assignment
88            self.assignments[index] = assignment
89            
90            // Emit event for this assignment
91            emit AssignmentMade(
92                username: selectedUsername,
93                team: selectedAssignment,
94                assignmentIndex: index
95            )
96            
97            // Remove assigned username and assignment from remaining pools
98            remainingUsernames = self.removeElement(arr: remainingUsernames, index: Int(usernameIndex))
99            allAssignments = self.removeElement(arr: allAssignments, index: Int(assignmentIndex))
100            
101            index = index + 1
102        }
103        
104        // Emit completion event
105        emit AllAssignmentsComplete(assignments: result)
106        
107        return result
108    }
109    
110    // Helper function to remove element from array
111    access(all) fun removeElement(arr: [String], index: Int): [String] {
112        var result: [String] = []
113        var i = 0
114        while i < arr.length {
115            if i != index {
116                result.append(arr[i])
117            }
118            i = i + 1
119        }
120        return result
121    }
122    
123    // Get all assignments
124    access(all) fun getAllAssignments(): {UInt64: Assignment} {
125        return self.assignments
126    }
127    
128    // Get assignment by index
129    access(all) fun getAssignment(index: UInt64): Assignment? {
130        return self.assignments[index]
131    }
132}
133
134