Smart Contract

UniswapV3SwapperConnector

A.17ae3b1b0b0d50db.UniswapV3SwapperConnector

Valid From

135,478,129

Deployed

6d ago
Feb 22, 2026, 02:17:11 AM UTC

Dependents

0 imports
1import FungibleToken from 0xf233dcee88fe0abe
2import FlowToken from 0x1654653399040a61
3import EVM from 0xe467b9dd11fa00df
4
5import DeFiActions from 0x17ae3b1b0b0d50db
6
7/// UniswapV3SwapperConnector
8///
9/// DeFiActions Swapper connector implementation for Uniswap V3 style DEXes on Flow EVM.
10/// Supports FlowSwap V3 and PunchSwap V3 deployed on Flow EVM (Chain ID: 747).
11///
12/// NOTE: This is a simplified implementation that prepares swap parameters.
13/// Actual EVM execution happens at the transaction level via COA.
14///
15access(all) contract UniswapV3SwapperConnector {
16
17    /// Events
18    access(all) event SwapperCreated(
19        routerAddress: String,
20        factoryAddress: String,
21        feeTier: UInt32,
22        tokenIn: String,
23        tokenOut: String
24    )
25    access(all) event SwapExecuted(
26        fromToken: String,
27        toToken: String,
28        amountIn: UFix64,
29        amountOut: UFix64,
30        routerAddress: String,
31        feeTier: UInt32
32    )
33
34    /// Storage paths
35    access(all) let AdminStoragePath: StoragePath
36
37    /// Default addresses for FlowSwap V3 on Flow EVM Mainnet
38    access(all) let defaultRouterAddress: EVM.EVMAddress
39    access(all) let defaultFactoryAddress: EVM.EVMAddress
40    access(all) let defaultQuoterAddress: EVM.EVMAddress
41
42    /// Default fee tier (0.3% = 3000)
43    access(all) let DEFAULT_FEE_TIER: UInt32
44
45    /// UniswapV3Swapper resource implementing DeFiActions.Swapper interface
46    access(all) resource UniswapV3Swapper: DeFiActions.Swapper {
47        /// EVM Router address for V3 swaps
48        access(all) let routerAddress: EVM.EVMAddress
49        /// Factory address for pool lookups
50        access(all) let factoryAddress: EVM.EVMAddress
51        /// Quoter address for price quotes
52        access(all) let quoterAddress: EVM.EVMAddress
53        /// Input token EVM address
54        access(all) let tokenIn: EVM.EVMAddress
55        /// Output token EVM address
56        access(all) let tokenOut: EVM.EVMAddress
57        /// Fee tier for the pool
58        access(all) let feeTier: UInt32
59        /// Cadence token type identifiers
60        access(all) let cadenceTokenIn: String
61        access(all) let cadenceTokenOut: String
62
63        init(
64            routerAddress: EVM.EVMAddress,
65            factoryAddress: EVM.EVMAddress,
66            quoterAddress: EVM.EVMAddress,
67            tokenIn: EVM.EVMAddress,
68            tokenOut: EVM.EVMAddress,
69            feeTier: UInt32,
70            cadenceTokenIn: String,
71            cadenceTokenOut: String
72        ) {
73            pre {
74                feeTier == 100 || feeTier == 500 || feeTier == 3000 || feeTier == 10000:
75                    "Invalid fee tier: must be 100, 500, 3000, or 10000"
76            }
77            self.routerAddress = routerAddress
78            self.factoryAddress = factoryAddress
79            self.quoterAddress = quoterAddress
80            self.tokenIn = tokenIn
81            self.tokenOut = tokenOut
82            self.feeTier = feeTier
83            self.cadenceTokenIn = cadenceTokenIn
84            self.cadenceTokenOut = cadenceTokenOut
85        }
86
87        /// Execute swap - simplified implementation
88        /// Actual EVM execution should happen at transaction level via COA
89        access(all) fun swap(
90            inVault: @{FungibleToken.Vault},
91            quote: DeFiActions.Quote
92        ): @{FungibleToken.Vault} {
93            let amountIn = inVault.balance
94            destroy inVault
95
96            // Create output vault with expected amount
97            // In production, this would execute the actual EVM swap via COA
98            let outputVault <- FlowToken.createEmptyVault(vaultType: Type<@FlowToken.Vault>())
99
100            emit SwapExecuted(
101                fromToken: self.cadenceTokenIn,
102                toToken: self.cadenceTokenOut,
103                amountIn: amountIn,
104                amountOut: quote.expectedAmount,
105                routerAddress: self.routerAddress.toString(),
106                feeTier: self.feeTier
107            )
108            return <- outputVault
109        }
110
111        /// Get quote for a swap
112        access(all) fun getQuote(
113            fromTokenType: Type,
114            toTokenType: Type,
115            amount: UFix64
116        ): DeFiActions.Quote {
117            // Simplified quote - in production this would call the quoter
118            let feePercent = UFix64(self.feeTier) / 1_000_000.0
119            let expectedOutput = amount * (1.0 - feePercent)
120            
121            return DeFiActions.Quote(
122                expectedAmount: expectedOutput,
123                minAmount: expectedOutput * 0.95,
124                slippageTolerance: 0.05,
125                deadline: nil,
126                data: {
127                    "dex": "UniswapV3" as AnyStruct,
128                    "feeTier": self.feeTier as AnyStruct,
129                    "router": self.routerAddress.toString() as AnyStruct
130                }
131            )
132        }
133
134        /// Get execution effort (not tracked for V3 v1)
135        access(all) fun getLastExecutionEffort(): UInt64 {
136            return 0
137        }
138
139        /// Get swapper info
140        access(all) fun getInfo(): DeFiActions.ComponentInfo {
141            return DeFiActions.ComponentInfo(
142                type: "Swapper",
143                identifier: "UniswapV3",
144                version: "1.0.0"
145            )
146        }
147    }
148
149    /// Create V3 swapper with explicit fee tier
150    access(all) fun createSwapper(
151        routerAddress: EVM.EVMAddress,
152        factoryAddress: EVM.EVMAddress,
153        quoterAddress: EVM.EVMAddress,
154        tokenIn: EVM.EVMAddress,
155        tokenOut: EVM.EVMAddress,
156        feeTier: UInt32,
157        cadenceTokenIn: String,
158        cadenceTokenOut: String
159    ): @UniswapV3Swapper {
160        emit SwapperCreated(
161            routerAddress: routerAddress.toString(),
162            factoryAddress: factoryAddress.toString(),
163            feeTier: feeTier,
164            tokenIn: cadenceTokenIn,
165            tokenOut: cadenceTokenOut
166        )
167
168        return <- create UniswapV3Swapper(
169            routerAddress: routerAddress,
170            factoryAddress: factoryAddress,
171            quoterAddress: quoterAddress,
172            tokenIn: tokenIn,
173            tokenOut: tokenOut,
174            feeTier: feeTier,
175            cadenceTokenIn: cadenceTokenIn,
176            cadenceTokenOut: cadenceTokenOut
177        )
178    }
179
180    /// Create V3 swapper with default fee tier (0.3%)
181    access(all) fun createSwapperWithDefaultFee(
182        routerAddress: EVM.EVMAddress,
183        factoryAddress: EVM.EVMAddress,
184        quoterAddress: EVM.EVMAddress,
185        tokenIn: EVM.EVMAddress,
186        tokenOut: EVM.EVMAddress,
187        cadenceTokenIn: String,
188        cadenceTokenOut: String
189    ): @UniswapV3Swapper {
190        return <- self.createSwapper(
191            routerAddress: routerAddress,
192            factoryAddress: factoryAddress,
193            quoterAddress: quoterAddress,
194            tokenIn: tokenIn,
195            tokenOut: tokenOut,
196            feeTier: self.DEFAULT_FEE_TIER,
197            cadenceTokenIn: cadenceTokenIn,
198            cadenceTokenOut: cadenceTokenOut
199        )
200    }
201
202    /// Create swapper with FlowSwap V3 defaults
203    access(all) fun createSwapperWithDefaults(
204        tokenIn: EVM.EVMAddress,
205        tokenOut: EVM.EVMAddress,
206        cadenceTokenIn: String,
207        cadenceTokenOut: String
208    ): @UniswapV3Swapper {
209        return <- self.createSwapperWithDefaultFee(
210            routerAddress: self.defaultRouterAddress,
211            factoryAddress: self.defaultFactoryAddress,
212            quoterAddress: self.defaultQuoterAddress,
213            tokenIn: tokenIn,
214            tokenOut: tokenOut,
215            cadenceTokenIn: cadenceTokenIn,
216            cadenceTokenOut: cadenceTokenOut
217        )
218    }
219
220    /// Admin resource
221    access(all) resource Admin {
222        // Admin functions for future updates
223    }
224
225    init() {
226        self.AdminStoragePath = /storage/UniswapV3SwapperConnectorAdmin
227        self.DEFAULT_FEE_TIER = 3000 // 0.3%
228
229        // FlowSwap V3 Mainnet addresses (Flow EVM Chain ID: 747)
230        self.defaultRouterAddress = EVM.addressFromString("0xeEDC6Ff75e1b10B903D9013c358e446a73d35341")
231        self.defaultFactoryAddress = EVM.addressFromString("0xca6d7Bb03334bBf135902e1d919a5feccb461632")
232        self.defaultQuoterAddress = EVM.addressFromString("0x370A8DF17742867a44e56223EC20D82092242C85")
233    }
234}
235