Smart Contract

aiSportsSwapper

A.254b32edc33e5bc3.aiSportsSwapper

Valid From

135,490,920

Deployed

1w ago
Feb 21, 2026, 02:48:38 PM UTC

Dependents

1 imports
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}