Smart Contract

FlowTokenHelper

A.6c1b12e35dca8863.FlowTokenHelper

Valid From

118,667,553

Deployed

6d ago
Feb 22, 2026, 03:31:08 PM UTC

Dependents

0 imports
1// FlowTokenHelper.cdc - Fixed for Cadence 1.0 (Standalone Version)
2access(all) contract FlowTokenHelper {
3    
4    // =====================================
5    // EVENTS
6    // =====================================
7    
8    access(all) event SafeTransferCompleted(from: Address, to: Address, amount: UFix64)
9    access(all) event BatchTransferCompleted(from: Address, recipients: UInt64, totalAmount: UFix64)
10    access(all) event TransferValidationFailed(from: Address, to: Address, amount: UFix64, reason: String)
11    
12    // =====================================
13    // STRUCTS
14    // =====================================
15    
16    access(all) struct TransferResult {
17        access(all) let success: Bool
18        access(all) let amount: UFix64
19        access(all) let recipient: Address
20        access(all) let error: String?
21        
22        init(success: Bool, amount: UFix64, recipient: Address, error: String?) {
23            self.success = success
24            self.amount = amount
25            self.recipient = recipient
26            self.error = error
27        }
28    }
29    
30    access(all) struct TokenBalance {
31        access(all) let address: Address
32        access(all) let balance: UFix64
33        access(all) let hasVault: Bool
34        access(all) let hasReceiver: Bool
35        
36        init(address: Address, balance: UFix64, hasVault: Bool, hasReceiver: Bool) {
37            self.address = address
38            self.balance = balance
39            self.hasVault = hasVault
40            self.hasReceiver = hasReceiver
41        }
42    }
43    
44    access(all) struct PayoutDistribution {
45        access(all) let recipient: Address
46        access(all) let amount: UFix64
47        access(all) let shares: UFix64
48        
49        init(recipient: Address, amount: UFix64, shares: UFix64) {
50            self.recipient = recipient
51            self.amount = amount
52            self.shares = shares
53        }
54    }
55    
56    // =====================================
57    // VALIDATION FUNCTIONS
58    // =====================================
59    
60    access(all) fun validateTransfer(from: Address, to: Address, amount: UFix64): {String: Bool} {
61        let result: {String: Bool} = {}
62        
63        // Check if addresses are valid
64        result["validFromAddress"] = FlowTokenHelper.isValidAddress(address: from)
65        result["validToAddress"] = FlowTokenHelper.isValidAddress(address: to)
66        
67        // Check if amount is valid
68        result["validAmount"] = FlowTokenHelper.validateTransferAmount(amount: amount)
69        
70        // Check if recipient has receiver capability
71        result["hasReceiver"] = FlowTokenHelper.hasFlowTokenReceiver(address: to)
72        
73        // Check if sender has vault
74        result["hasVault"] = FlowTokenHelper.hasFlowTokenVault(address: from)
75        
76        return result
77    }
78    
79    access(all) fun validateTransferAmount(amount: UFix64): Bool {
80        return amount > 0.0 && amount <= 999999999.99999999 // Max reasonable amount
81    }
82    
83    access(all) fun isValidAddress(address: Address): Bool {
84        // Basic address validation - check if account exists
85        let account = getAccount(address)
86        return true // Account exists if we can get it
87    }
88    
89    // =====================================
90    // BALANCE CHECKING FUNCTIONS (Simplified)
91    // =====================================
92    
93    access(all) fun getBalance(address: Address): TokenBalance? {
94        let account = getAccount(address)
95        
96        // Simplified balance check without FungibleToken imports
97        // In a real implementation, you'd check the actual FlowToken vault
98        return TokenBalance(
99            address: address,
100            balance: account.balance, // Account's native FLOW balance
101            hasVault: true,          // Assume true for simplicity
102            hasReceiver: true        // Assume true for simplicity
103        )
104    }
105    
106    access(all) fun getBatchBalances(addresses: [Address]): [TokenBalance] {
107        let balances: [TokenBalance] = []
108        
109        for address in addresses {
110            if let balance = FlowTokenHelper.getBalance(address: address) {
111                balances.append(balance)
112            }
113        }
114        
115        return balances
116    }
117    
118    access(all) fun hasFlowTokenVault(address: Address): Bool {
119        // Simplified check - in production, check actual FlowToken vault capability
120        let account = getAccount(address)
121        return true // Assume all accounts have vaults
122    }
123    
124    access(all) fun hasFlowTokenReceiver(address: Address): Bool {
125        // Simplified check - in production, check actual FlowToken receiver capability
126        let account = getAccount(address)
127        return true // Assume all accounts can receive tokens
128    }
129    
130    // =====================================
131    // FORMATTING FUNCTIONS
132    // =====================================
133    
134    access(all) fun formatTokenAmount(amount: UFix64): String {
135        if amount >= 1000000.0 {
136            let millions = amount / 1000000.0
137            return millions.toString().concat("M")
138        } else if amount >= 1000.0 {
139            let thousands = amount / 1000.0
140            return thousands.toString().concat("K")
141        } else {
142            return amount.toString()
143        }
144    }
145    
146    access(all) fun formatForDisplay(amount: UFix64, decimals: UInt8): String {
147        // Format amount with specified decimal places
148        let integerPart = UInt64(amount)
149        let fractionalPart = amount - UFix64(integerPart)
150        
151        if decimals == 0 {
152            return integerPart.toString()
153        }
154        
155        // Simple decimal formatting
156        let multiplier = UFix64(decimals == 1 ? 10 : decimals == 2 ? 100 : 1000)
157        let fractionalInt = UInt64(fractionalPart * multiplier)
158        
159        return integerPart.toString().concat(".").concat(fractionalInt.toString())
160    }
161    
162    access(all) fun calculateTransactionFee(amount: UFix64): UFix64 {
163        // Simple fee calculation - can be customized
164        let baseFee: UFix64 = 0.001 // 0.001 FLOW base fee
165        let percentageFee = amount * 0.001 // 0.1% of amount
166        
167        return baseFee + percentageFee
168    }
169    
170    // =====================================
171    // PAYOUT DISTRIBUTION
172    // =====================================
173    
174    access(all) fun distributePayout(
175        totalPayout: UFix64,
176        winners: [Address],
177        shares: [UFix64]
178    ): {Address: UFix64} {
179        pre {
180            winners.length == shares.length: "Winners and shares arrays must have the same length"
181            totalPayout > 0.0: "Total payout must be greater than 0"
182        }
183        
184        let payouts: {Address: UFix64} = {}
185        var totalShares: UFix64 = 0.0
186        
187        // Calculate total shares
188        for share in shares {
189            totalShares = totalShares + share
190        }
191        
192        if totalShares == 0.0 {
193            return payouts
194        }
195        
196        // Calculate individual payouts
197        var i = 0
198        while i < winners.length {
199            let winner = winners[i]
200            let share = shares[i]
201            let payout = (share / totalShares) * totalPayout
202            
203            payouts[winner] = payout
204            i = i + 1
205        }
206        
207        return payouts
208    }
209    
210    access(all) fun calculatePayoutDistribution(
211        totalPayout: UFix64,
212        winners: [Address],
213        shares: [UFix64]
214    ): [PayoutDistribution] {
215        pre {
216            winners.length == shares.length: "Winners and shares arrays must have the same length"
217        }
218        
219        let distributions: [PayoutDistribution] = []
220        var totalShares: UFix64 = 0.0
221        
222        // Calculate total shares
223        for share in shares {
224            totalShares = totalShares + share
225        }
226        
227        if totalShares == 0.0 {
228            return distributions
229        }
230        
231        // Create distribution objects
232        var i = 0
233        while i < winners.length {
234            let winner = winners[i]
235            let share = shares[i]
236            let amount = (share / totalShares) * totalPayout
237            
238            let distribution = PayoutDistribution(
239                recipient: winner,
240                amount: amount,
241                shares: share
242            )
243            distributions.append(distribution)
244            i = i + 1
245        }
246        
247        return distributions
248    }
249    
250    // =====================================
251    // UTILITY FUNCTIONS
252    // =====================================
253    
254    access(all) fun convertToDisplayUnits(amount: UFix64): UFix64 {
255        // Convert from base units to display units if needed
256        return amount
257    }
258    
259    access(all) fun convertFromDisplayUnits(amount: UFix64): UFix64 {
260        // Convert from display units to base units if needed
261        return amount
262    }
263    
264    access(all) fun getMinimumBalance(): UFix64 {
265        return 0.001 // Minimum balance to maintain for transaction fees
266    }
267    
268    access(all) fun getMaximumTransferAmount(): UFix64 {
269        return 999999999.99999999 // Maximum allowed transfer amount
270    }
271    
272    // =====================================
273    // SECURITY FUNCTIONS
274    // =====================================
275    
276    access(all) fun isTransferAmountSafe(amount: UFix64, senderBalance: UFix64): Bool {
277        let minimumBalance = FlowTokenHelper.getMinimumBalance()
278        return senderBalance >= (amount + minimumBalance)
279    }
280    
281    access(all) fun validateBatchTransfer(recipients: [Address], amounts: [UFix64]): Bool {
282        pre {
283            recipients.length == amounts.length: "Recipients and amounts must have same length"
284            recipients.length > 0: "Must have at least one recipient"
285        }
286        
287        // Validate each recipient and amount
288        var i = 0
289        while i < recipients.length {
290            let recipient = recipients[i]
291            let amount = amounts[i]
292            
293            if !FlowTokenHelper.isValidAddress(address: recipient) {
294                return false
295            }
296            
297            if !FlowTokenHelper.validateTransferAmount(amount: amount) {
298                return false
299            }
300            
301            if !FlowTokenHelper.hasFlowTokenReceiver(address: recipient) {
302                return false
303            }
304            
305            i = i + 1
306        }
307        
308        return true
309    }
310    
311    // =====================================
312    // CONTRACT INITIALIZATION
313    // =====================================
314    
315    init() {
316        // Contract initialization
317    }
318}