@@ -8,78 +8,76 @@ import "FlowEVMBridgeConfig"
88transaction () {
99
1010 prepare (acct : auth (Storage , Capabilities ) &Account ) {
11- // 1) COA capability your test published earlier
11+ // COA capability: either issue from storage (owner) or use a published public cap.
1212 let coaCap : Capability <auth (EVM.Owner ) &EVM.CadenceOwnedAccount > =
1313 acct .capabilities .storage .issue <auth (EVM.Owner ) &EVM.CadenceOwnedAccount >(/storage/evm )
1414
15- // 2) Router + Quoter + tokens from your forge deployment
15+ // Router + Quoter + tokens (FLOW → USDC)
1616 let router = EVM .addressFromString (" 0xB685ab04Dfef74c135A2ed4003441fF124AFF9a0" )
1717 let quoter = EVM .addressFromString (" 0xA1e0E4CCACA34a738f03cFB1EAbAb16331FA3E2c" )
1818
1919 let usdc = EVM .addressFromString (" 0x5e65b6B04fbA51D95409712978Cb91E99d93aE73" )
20- let wflow = EVM .addressFromString (" 0xd3bF53DAC106A0290B0483EcBC89d40FcC961f3e" )
20+ let wflow = EVM .addressFromString (" 0xd3bF53DAC106A0290B0483EcBC89d40FcC961f3e" ) // WFLOW on EVM side
2121
22- // Types associated with ERC20s on Flow
23- let inType : Type = FlowEVMBridgeConfig .getTypeAssociated (with : usdc ) ?? panic (" invalid in type" )
24- let outType = Type <@FlowToken.Vault >()
25- // If WFLOW maps to FlowToken.Vault, outType should equal Type<@FlowToken.Vault>()
22+ // Vault types for in/out
23+ let inType : Type = Type <@FlowToken.Vault >() // FLOW in
24+ let outType : Type = FlowEVMBridgeConfig .getTypeAssociated (with : usdc ) ?? panic (" invalid USDC out type" )
2625
27- // 3) Instantiate the V3 Swapper (single hop USDC -> WFLOW @ 0.3%)
26+ // Swapper: tokenPath must be [WFLOW, USDC] for FLOW → USDC
2827 let swapper = UniswapV3SwapConnectors .Swapper (
2928 routerAddress : router ,
3029 quoterAddress : quoter ,
31- tokenPath : [usdc , wflow ],
30+ tokenPath : [wflow , usdc ],
3231 feePath : [3000 ], // 0.3%
3332 inVault : inType ,
3433 outVault : outType ,
3534 coaCapability : coaCap ,
3635 uniqueID : nil
3736 )
3837
39- // 4) Bring in USDC from storage for testing (use FT interfaces for dynamic types)
40- let usdcStoragePath = /storage/EVMVMBridgedToken_5e65b6b04fba51d95409712978cb91e99d93ae73Vault
41- let usdcWithdrawRef = acct .storage
42- .borrow <auth (FungibleToken.Withdraw ) &{FungibleToken .Vault }>(from : usdcStoragePath )
43- ?? panic (" Missing USDC vault at \( usdcStoragePath ) " )
44-
45- let amountIn : UFix64 = 100.0
46- let vaultIn <- usdcWithdrawRef .withdraw (amount : amountIn )
38+ // ---- Swap FLOW → USDC (quoteOut + swap) ----
39+ // Withdraw FLOW
40+ let flowStoragePath = /storage/flowTokenVault
41+ let flowWithdrawRef = acct .storage
42+ .borrow <auth (FungibleToken.Withdraw ) &FlowToken.Vault >(from : flowStoragePath )
43+ ?? panic (" Missing FLOW vault at /storage/flowTokenVault" )
4744
48- // 5) Quote output for provided input
49- let q = swapper .quoteOut (forProvided : amountIn , reverse : false )
50- log (" Quote out for provided " .concat (amountIn .toString ()).concat (" : " ).concat (q .outAmount .toString ()))
45+ let flowIn : UFix64 = 100.0
46+ let flowVaultIn <- flowWithdrawRef .withdraw (amount : flowIn )
5147
52- // 6) Perform the swap with min-out from the quote
53- let outVault <- swapper .swap ( quote : q , inVault : <- vaultIn )
54- log (" Swap out received : " .concat (outVault . balance .toString ()))
48+ // Quote how much USDC we’ll get
49+ let q = swapper .quoteOut ( forProvided : flowIn , reverse : false )
50+ log (" Quote out for provided " . concat ( flowIn . toString ()). concat ( " FLOW → USDC : " ) .concat (q . outAmount .toString ()))
5551
56- // Deposit result (WFLOW) — if WFLOW maps to FlowToken.Vault, deposit to that path
57- let wflowStoragePath = /storage/wflowVault
58- let wflowDepositRef = acct .storage
59- .borrow <&{FungibleToken .Vault }>(from : wflowStoragePath )
60- ?? panic (" Missing WFLOW vault at /storage/wflowVault" )
61- wflowDepositRef .deposit (from : <- outVault )
52+ // Perform the swap
53+ let usdcOut <- swapper .swap (quote : q , inVault : <- flowVaultIn )
54+ log (" USDC received: " .concat (usdcOut .balance .toString ()))
6255
63- // 7) “Exact-out” pattern:
64- // Pre-quote the required input for desired WFLOW, withdraw exactly that, then swap.
65- let desiredWFLOW : UFix64 = 0.01
66- let qi = swapper . quoteIn ( forDesired : desiredWFLOW , reverse : false )
67- let needIn : UFix64 = qi . inAmount
68- log ( " ExactOut desired " . concat ( desiredWFLOW . toString ()). concat ( " WFLOW; need USDC: " ). concat ( needIn . toString ()) )
56+ // Deposit USDC
57+ let usdcStoragePath = / storage/EVMVMBridgedToken_5e65b6b04fba51d95409712978cb91e99d93ae73Vault
58+ let usdcReceiver = acct . storage
59+ . borrow <&{ FungibleToken . Receiver }>( from : usdcStoragePath )
60+ ?? panic ( " Missing USDC vault at " . concat ( usdcStoragePath . toString ()))
61+ usdcReceiver . deposit ( from : <- usdcOut )
6962
70- let usdcWithdrawRef2 = acct . storage
71- . borrow < auth ( FungibleToken.Withdraw ) &{ FungibleToken . Vault }>( from : usdcStoragePath )
72- ?? panic ( " Missing USDC vault at \( usdcStoragePath ) (for exactOut) " )
73- let maxSpend : UFix64 = 100.0
74- assert ( needIn < = maxSpend , message : " Required USDC exceeds test max spend " )
63+ // ---- Exact-out USDC: pre-quote input FLOW, then swap ----
64+ let desiredUSDC : UFix64 = 10.0
65+ let qi = swapper . quoteIn ( forDesired : desiredUSDC , reverse : false )
66+ let needFlow : UFix64 = qi . inAmount
67+ log ( " ExactOut want " . concat ( desiredUSDC . toString ()). concat ( " USDC; need FLOW: " ). concat ( needFlow . toString ()) )
7568
76- let needVault <- usdcWithdrawRef2 .withdraw (amount : needIn )
77- let outVault2 <- swapper .swap (quote : qi , inVault : <- needVault )
78- log (" ExactOut swap received WFLOW: " .concat (outVault2 .balance .toString ()))
69+ // Withdraw required FLOW
70+ let flowWithdrawRef2 = acct .storage
71+ .borrow <auth (FungibleToken.Withdraw ) &FlowToken.Vault >(from : flowStoragePath )
72+ ?? panic (" Missing FLOW vault for exact-out" )
73+ let flowNeedVault <- flowWithdrawRef2 .withdraw (amount : needFlow )
7974
80- let wflowDepositRef2 = acct .storage
81- .borrow <&{FungibleToken .Vault }>(from : wflowStoragePath )
82- ?? panic (" Missing WFLOW vault for exactOut deposit" )
83- wflowDepositRef2 .deposit (from : <- outVault2 )
75+ // Swap and deposit USDC
76+ let usdcOut2 <- swapper .swap (quote : qi , inVault : <- flowNeedVault )
77+ log (" ExactOut USDC received: " .concat (usdcOut2 .balance .toString ()))
78+ let usdcReceiver2 = acct .storage
79+ .borrow <&{FungibleToken .Receiver }>(from : usdcStoragePath )
80+ ?? panic (" Missing USDC vault for exact-out deposit" )
81+ usdcReceiver2 .deposit (from : <- usdcOut2 )
8482 }
8583}
0 commit comments