Smart Contract
aiSportsSwapper
A.254b32edc33e5bc3.aiSportsSwapper
1import FungibleToken from 0xf233dcee88fe0abe
2import FlowToken from 0x1654653399040a61
3import FungibleTokenMetadataViews from 0xf233dcee88fe0abe
4import aiSportsJuice from 0x9db94c9564243ba7
5import IncrementFiSwapConnectors from 0xefa9bd7d1b17f1ed
6
7access(all) contract aiSportsSwapper {
8
9 access(all) let SwapManagerStoragePath: StoragePath
10
11 //add an array of token types that we should scan and swap
12 access(all) let tokenStorageVaultPaths: [StoragePath]
13 access(all) let swappers: [IncrementFiSwapConnectors.Swapper]
14
15 access(all) fun swapToJuice() {
16
17 var vaultPathIndex = 0
18
19 // Deposit JUICE into the token holder's JUICE receiver
20 let juiceReceiver = self.account.capabilities.get<&{FungibleToken.Receiver}>(/public/aiSportsJuiceReceiver).borrow()
21 ?? panic("Missing /public/aiSportsJuiceReceiver capability on signer")
22
23 //loop through the array of token public vault paths and check the balance of each token
24 for tokenStorageVaultPath in self.tokenStorageVaultPaths {
25 let vaultRef = self.account.storage.borrow<auth(FungibleToken.Withdraw) &{FungibleToken.Vault}>(from:tokenStorageVaultPath) ?? panic("Vault not found")
26
27 //check the type of the vault - if it is a Flow Token Vault, we need to keep some Flow tokens in the contract account for fees
28 if vaultRef.getType() == Type<@FlowToken.Vault>() {
29 let balance = vaultRef.balance
30
31 if balance > 5.0 {
32 let balanceToSwap = balance - 5.0
33 let flowToWithdraw <- vaultRef.withdraw(amount: balanceToSwap)
34
35 // Perform the swap; the swapper internally quotes amountOutMin
36 let juiceVault <- self.swappers[0].swap(quote: nil, inVault: <-flowToWithdraw)
37
38 juiceReceiver.deposit(from: <-juiceVault)
39 }
40 } else { //once we add more tokens, will need to add else logic here to swap
41 let balance = vaultRef.balance
42 if balance > 0.01 {
43 let balanceToSwap = balance
44 let tokenToWithdraw <- vaultRef.withdraw(amount: balanceToSwap)
45 let juiceVault <- self.swappers[vaultPathIndex].swap(quote: nil, inVault: <-tokenToWithdraw)
46 juiceReceiver.deposit(from: <-juiceVault)
47
48 }
49 }
50 vaultPathIndex = vaultPathIndex + 1
51 }
52 }
53
54 access(all) resource SwapManager{
55 //this function is called by the contract admin to add a token type to the array of tokens to add/swap
56 access(all) fun addTokenType(vaultStoragePath: StoragePath, swapper: IncrementFiSwapConnectors.Swapper) {
57 aiSportsSwapper.tokenStorageVaultPaths.append(vaultStoragePath)
58 aiSportsSwapper.swappers.append(swapper)
59 }
60 }
61
62 init() {
63 let vaultData = FlowToken.resolveContractView(
64 resourceType: nil,
65 viewType: Type<FungibleTokenMetadataViews.FTVaultData>()
66 ) as! FungibleTokenMetadataViews.FTVaultData
67 self.tokenStorageVaultPaths = [ vaultData.storagePath ]
68
69 // Initialize with IncrementFi FLOW -> JUICE (via stFLOW) swapper
70 // Provide concrete token vault types for validation against the path
71 self.swappers = [IncrementFiSwapConnectors.Swapper(
72 path: [
73 "A.1654653399040a61.FlowToken",
74 "A.d6f80565193ad727.stFlowToken",
75 "A.9db94c9564243ba7.aiSportsJuice"
76 ],
77 inVault: Type<@FlowToken.Vault>(),
78 outVault: Type<@aiSportsJuice.Vault>(),
79 uniqueID: nil
80 )]
81
82 //create the swap manager resource
83 self.SwapManagerStoragePath = /storage/aiSportsSwapperSwapManager
84 self.account.storage.save(<-create SwapManager(), to: self.SwapManagerStoragePath)
85 }
86}