Smart Contract

ToucansActions

A.577a3c409c5dcb5e.ToucansActions

Deployed

36m ago
Feb 26, 2026, 10:26:44 PM UTC

Dependents

0 imports
1import FungibleToken from 0xf233dcee88fe0abe
2import NonFungibleToken from 0x1d7e57aa55817448
3import ToucansUtils from 0x577a3c409c5dcb5e
4import NFTCatalog from 0x49a7cda3a1eecc29
5
6access(all) contract ToucansActions {
7
8  access(all) struct interface Action {
9    access(all) fun getIntent(): String
10    access(all) fun getTitle(): String
11  }
12
13
14  //                _   _                 
15  //      /\       | | (_)                
16  //     /  \   ___| |_ _  ___  _ __  ___ 
17  //    / /\ \ / __| __| |/ _ \| '_ \/ __|
18  //   / ____ \ (__| |_| | (_) | | | \__ \
19  //  /_/    \_\___|\__|_|\___/|_| |_|___/   
20
21
22  // Transfers `amount` tokens from the treasury to `recipientVault`
23  access(all) struct WithdrawToken: Action {
24    access(all) let vaultType: Type
25    access(all) let recipientVault: Capability<&{FungibleToken.Receiver}>
26    access(all) let amount: UFix64
27    access(all) let tokenSymbol: String
28    access(all) let readableAmount: String
29
30    access(all) fun getIntent(): String {
31      return "Withdraw ".concat(self.readableAmount).concat(" ").concat(self.tokenSymbol).concat(" tokens from the treasury to ").concat(ToucansUtils.getFind(self.recipientVault.borrow()!.owner!.address))
32    }
33
34    access(all) fun getTitle(): String {
35      return "Withdraw"
36    }
37
38    init(_ vaultType: Type, _ recipientVault: Capability<&{FungibleToken.Receiver}>, _ amount: UFix64, _ tokenSymbol: String) {
39      pre {
40        recipientVault.check(): "Invalid recipient capability."
41      }
42      self.vaultType = vaultType
43      self.recipientVault = recipientVault
44      self.amount = amount
45      self.tokenSymbol = tokenSymbol
46      self.readableAmount = ToucansUtils.fixToReadableString(num: amount)
47    }
48  }
49
50  access(all) struct BatchWithdrawToken: Action {
51    access(all) let vaultType: Type
52    access(all) let recipientVaults: {Address: Capability<&{FungibleToken.Receiver}>}
53    access(all) let amounts: {Address: UFix64}
54    access(all) let tokenSymbol: String
55    access(all) let totalReadableAmount: String
56
57    access(all) fun getIntent(): String {
58      return "Withdraw a total of ".concat(self.totalReadableAmount).concat(" ").concat(self.tokenSymbol).concat(" tokens from the treasury to ").concat(self.amounts.keys.length.toString()).concat(" total wallets")
59    }
60
61    access(all) fun getTitle(): String {
62      return "BatchWithdraw"
63    }
64
65    init(_ vaultType: Type, _ recipientVaults: {Address: Capability<&{FungibleToken.Receiver}>}, _ amounts: {Address: UFix64}, _ tokenSymbol: String) {
66      self.vaultType = vaultType
67      self.recipientVaults = recipientVaults
68      self.amounts = amounts
69      self.tokenSymbol = tokenSymbol
70
71      var totalAmount: UFix64 = 0.0
72      for amount in amounts.values {
73        totalAmount = totalAmount + amount
74      }
75      self.totalReadableAmount = ToucansUtils.fixToReadableString(num: totalAmount)
76    }
77  }
78
79  // Withdraws NFTs from the treasury to 1 address
80  access(all) struct WithdrawNFTs: Action {
81    access(all) let collectionType: Type
82    access(all) let recipientCollection: Capability<&{NonFungibleToken.Receiver}>
83    access(all) let nftIDs: [UInt64]
84    access(all) let collectionIdentifier: String
85    access(all) let collectionName: String
86    access(all) let collectionExternalURL: String
87    access(all) let extra: {String: AnyStruct}
88
89    access(all) fun getIntent(): String {
90      return "Withdraw ".concat(self.nftIDs.length.toString()).concat(" ").concat(self.collectionName).concat(" NFT(s) from the treasury to ").concat(ToucansUtils.getFind(self.recipientCollection.address))
91    }
92
93    access(all) fun getTitle(): String {
94      return "WithdrawNFTs"
95    }
96
97    init(_ collectionType: Type, _ nftIDs: [UInt64], _ recipientCollection: Capability<&{NonFungibleToken.Receiver}>, _ recipientCollectionBackup: Capability<&{NonFungibleToken.CollectionPublic}>, _ message: String) {
98      pre {
99        recipientCollection.check() || recipientCollectionBackup.check(): "Invalid recipient capability."
100      }
101      self.collectionType = collectionType
102      self.recipientCollection = recipientCollection
103      self.nftIDs = nftIDs
104      let nftCatalogCollectionIdentifier = ToucansUtils.getNFTCatalogCollectionIdentifierFromCollectionIdentifier(collectionIdentifier: collectionType.identifier)
105      let nftCatalogEntry = NFTCatalog.getCatalogEntry(collectionIdentifier: nftCatalogCollectionIdentifier)!
106      self.collectionIdentifier = nftCatalogCollectionIdentifier
107      self.collectionName = nftCatalogEntry.collectionDisplay.name
108      self.collectionExternalURL = nftCatalogEntry.collectionDisplay.externalURL.url
109      self.extra = {
110        "backupReceiver": recipientCollectionBackup,
111        "message": message
112      }
113    }
114  }
115
116  // Mint `amount` tokens to `recipientVault`
117  access(all) struct MintTokens: Action {
118    access(all) let recipientVault: Capability<&{FungibleToken.Receiver}>
119    access(all) let amount: UFix64
120    access(all) let tokenSymbol: String
121    access(all) let readableAmount: String
122
123    access(all) fun getIntent(): String {
124      return "Mint ".concat(self.readableAmount).concat(" ").concat(self.tokenSymbol).concat(" tokens to ").concat(ToucansUtils.getFind(self.recipientVault.borrow()!.owner!.address))
125    }
126
127    access(all) fun getTitle(): String {
128      return "Mint"
129    }
130
131    init(_ recipientVault: Capability<&{FungibleToken.Receiver}>, _ amount: UFix64, _ tokenSymbol: String) {
132      self.recipientVault = recipientVault
133      assert(self.recipientVault.check(), message: "Invalid recipient capability.")
134      self.amount = amount
135      self.tokenSymbol = tokenSymbol
136      self.readableAmount = ToucansUtils.fixToReadableString(num: amount)
137    }
138  }
139
140  access(all) struct BatchMintTokens: Action {
141    access(all) let recipientVaults: {Address: Capability<&{FungibleToken.Receiver}>}
142    access(all) let amounts: {Address: UFix64}
143    access(all) let tokenSymbol: String
144    access(all) let totalReadableAmount: String
145
146    access(all) fun getIntent(): String {
147      return "Mint a total of ".concat(self.totalReadableAmount).concat(" ").concat(self.tokenSymbol).concat(" tokens to ").concat(self.amounts.keys.length.toString()).concat(" total wallets")
148    }
149
150    access(all) fun getTitle(): String {
151      return "BatchMint"
152    }
153
154    init(_ recipientVaults: {Address: Capability<&{FungibleToken.Receiver}>}, _ amounts: {Address: UFix64}, _ tokenSymbol: String) {
155      self.recipientVaults = recipientVaults
156      self.amounts = amounts
157      self.tokenSymbol = tokenSymbol
158
159      var totalAmount: UFix64 = 0.0
160      for amount in amounts.values {
161        totalAmount = totalAmount + amount
162      }
163      self.totalReadableAmount = ToucansUtils.fixToReadableString(num: totalAmount)
164    }
165  }
166
167  // Mint `amount` tokens to the treasury directly
168  access(all) struct MintTokensToTreasury: Action {
169    access(all) let amount: UFix64
170    access(all) let tokenSymbol: String
171    access(all) let readableAmount: String
172
173    access(all) fun getIntent(): String {
174      return "Mint ".concat(self.readableAmount).concat(" ").concat(self.tokenSymbol).concat(" tokens to the Treasury")
175    }
176
177    access(all) fun getTitle(): String {
178      return "MintToTreasury"
179    }
180
181    init(_ amount: UFix64, _ tokenSymbol: String) {
182      self.amount = amount
183      self.tokenSymbol = tokenSymbol
184      self.readableAmount = ToucansUtils.fixToReadableString(num: amount)
185    }
186  }
187
188  // Add a new signer to the treasury
189  access(all) struct AddOneSigner: Action {
190    access(all) let signer: Address
191
192    access(all) fun getIntent(): String {
193      return "Add ".concat(ToucansUtils.getFind(self.signer)).concat(" as a signer to the Treasury")
194    }
195
196    access(all) fun getTitle(): String {
197      return "AddSigner"
198    }
199
200    init(_ signer: Address) {
201      self.signer = signer
202    }
203  }
204
205  // Remove a signer from the treasury
206  // NOTE: If this reduces the # of signers to 
207  // below the threshold, this will automatically
208  // reduce the threshold to the # of signers
209  access(all) struct RemoveOneSigner: Action {
210    access(all) let signer: Address
211
212    access(all) fun getIntent(): String {
213      return "Remove ".concat(ToucansUtils.getFind(self.signer)).concat(" as a signer from the Treasury")
214    }
215
216    access(all) fun getTitle(): String {
217      return "RemoveSigner"
218    }
219
220    init(_ signer: Address) {
221      self.signer = signer
222    }
223  }
224
225  // Update the threshold of signers
226  access(all) struct UpdateTreasuryThreshold: Action {
227    access(all) let threshold: UInt64
228
229    access(all) fun getIntent(): String {
230      return "Update the threshold of signers needed to execute an action in the Treasury to ".concat(self.threshold.toString())
231    }
232
233    access(all) fun getTitle(): String {
234      return "UpdateThreshold"
235    }
236
237    init(_ threshold: UInt64) {
238      self.threshold = threshold
239    }
240  }
241
242  // burn your DAOs token from the treasury
243  access(all) struct BurnTokens: Action {
244    access(all) let amount: UFix64
245    access(all) let tokenSymbol: String
246    access(all) let readableAmount: String
247
248    access(all) fun getIntent(): String {
249      return "Burn ".concat(self.readableAmount).concat(" ").concat(self.tokenSymbol).concat(" tokens from the Treasury")
250    }
251
252    access(all) fun getTitle(): String {
253      return "Burn"
254    }
255
256    init(_ amount: UFix64, _ tokenSymbol: String) {
257      self.amount = amount
258      self.tokenSymbol = tokenSymbol
259      self.readableAmount = ToucansUtils.fixToReadableString(num: amount)
260    }
261  }
262
263  // lock a token to a user
264  access(all) struct LockTokens: Action {
265    access(all) let recipient: Address
266    access(all) let amount: UFix64
267    access(all) let tokenSymbol: String
268    access(all) let readableAmount: String
269    access(all) let unlockTime: UFix64
270
271    access(all) fun getIntent(): String {
272      return "Lock ".concat(self.readableAmount).concat(" ").concat(self.tokenSymbol).concat(" tokens for ").concat(ToucansUtils.getFind(self.recipient)).concat(" until ").concat(self.unlockTime.toString())
273    }
274
275    access(all) fun getTitle(): String {
276      return "LockTokens"
277    }
278
279    init(_ recipient: Address, _ amount: UFix64, _ tokenSymbol: String, _ unlockTime: UFix64) {
280      self.amount = amount
281      self.tokenSymbol = tokenSymbol
282      self.readableAmount = ToucansUtils.fixToReadableString(num: amount)
283      self.unlockTime = unlockTime
284      self.recipient = recipient
285    }
286  }
287
288  // stake flow by swapping it to stFlow on increment fi
289  access(all) struct StakeFlow: Action {
290    access(all) let flowAmount: UFix64
291    access(all) let readableAmount: String
292    access(all) let stFlowAmountOutMin: UFix64
293    access(all) let readableMin: String
294
295    access(all) fun getIntent(): String {
296      return "Stake ".concat(self.readableAmount).concat(" FLOW ").concat(" tokens by swapping them for a minimum of ").concat(self.readableMin).concat(" stFlow.")
297    }
298
299    access(all) fun getTitle(): String {
300      return "StakeFlow"
301    }
302
303    init(_ flowAmount: UFix64, _ stFlowAmountOutMin: UFix64) {
304      self.flowAmount = flowAmount
305      self.readableAmount = ToucansUtils.fixToReadableString(num: flowAmount)
306      self.stFlowAmountOutMin = stFlowAmountOutMin
307      self.readableMin = ToucansUtils.fixToReadableString(num: stFlowAmountOutMin)
308    }
309  }
310
311  // unstake flow by swapping stFlow for flow on increment fi
312  access(all) struct UnstakeFlow: Action {
313    access(all) let stFlowAmount: UFix64
314    access(all) let readableAmount: String
315    access(all) let flowAmountOutMin: UFix64
316    access(all) let readableMin: String
317
318    access(all) fun getIntent(): String {
319      return "Unstake FLOW".concat(" tokens by swapping ").concat(self.readableAmount).concat(" stFlow for a minimum of ").concat(self.readableMin).concat(" FLOW.")
320    }
321
322    access(all) fun getTitle(): String {
323      return "UnstakeFlow"
324    }
325
326    init(_ stFlowAmount: UFix64, _ flowAmountOutMin: UFix64) {
327      self.stFlowAmount = stFlowAmount
328      self.readableAmount = ToucansUtils.fixToReadableString(num: stFlowAmount)
329      self.flowAmountOutMin = flowAmountOutMin
330      self.readableMin = ToucansUtils.fixToReadableString(num: flowAmountOutMin)
331    }
332  }
333}
334