Smart Contract
UniswapV3SwapperConnector
A.17ae3b1b0b0d50db.UniswapV3SwapperConnector
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