@@ -469,24 +469,19 @@ access(all) contract UniswapV3SwapConnectors {
469469 : self .feePath [hopIndex ]
470470
471471 let res = self ._dryCall (
472- self .factoryAddress ,
473- " getPool(address,address,uint24)" ,
474- [ tokenA , tokenB , UInt256 (fee ) ],
475- 120_000
472+ to : self .factoryAddress ,
473+ signature : " getPool(address,address,uint24)" ,
474+ args : [tokenA , tokenB , UInt256 (fee )],
475+ gasLimit : 120_000 ,
476+ resultTypes : [Type <EVM .EVMAddress >()]
476477 )!
477478 assert (
478479 res .status == EVM .Status .successful ,
479480 message : " unable to get pool: tokenA \( tokenA .toString ()) , tokenB \( tokenB .toString ()) , fee: \( fee ) "
480481 )
481482
482- // ABI return is one 32-byte word; the last 20 bytes are the address
483- let word = res .data
484- if word .length < 32 { panic (" getPool: invalid ABI word length" ) }
485-
486- let addrSlice = word .slice (from : 12 , upTo : 32 ) // 20 bytes
487- let addrBytes = addrSlice .toConstantSized <[UInt8 ; 20]>()!
488-
489- return EVM .EVMAddress (bytes : addrBytes )
483+ assert (res .results .length == 1 , message : " getPool: invalid ABI-encoded return data" )
484+ return res .results [0 ] as ! EVM .EVMAddress
490485 }
491486
492487 /// Get max input amount for a specific hop
@@ -506,50 +501,29 @@ access(all) contract UniswapV3SwapConnectors {
506501 access (self ) fun getMaxInAmount (hopIndex : Int , zeroForOne : Bool , reverse : Bool ): UInt256 {
507502 let poolEVMAddress = self .getPoolAddress (hopIndex : hopIndex , reverse : reverse )
508503
509- // Helper functions
510- fun wordToUInt (_ w : [UInt8 ]): UInt {
511- var acc : UInt = 0
512- var i = 0
513- while i < 32 { acc = (acc << 8 ) | UInt (w [i ]); i = i + 1 }
514- return acc
515- }
516- fun wordToUIntN (_ w : [UInt8 ], _ nBits : UInt ): UInt {
517- let full = wordToUInt (w )
518- if nBits > = 256 { return full }
519- let mask : UInt = (1 << nBits ) - 1
520- return full & mask
521- }
522- fun words (_ data : [UInt8 ]): [[UInt8 ]] {
523- let n = data .length / 32
524- var out : [[UInt8 ]] = []
525- var i = 0
526- while i < n {
527- out .append (data .slice (from : i * 32 , upTo : (i + 1 )* 32 ))
528- i = i + 1
529- }
530- return out
531- }
532-
533- // Selectors
534- let SEL_SLOT0 : [UInt8 ] = [0x38 , 0x50 , 0xc7 , 0xbd ]
535- let SEL_LIQUIDITY : [UInt8 ] = [0x1a , 0x68 , 0x65 , 0x02 ]
536-
537504 // Get slot0 (sqrtPriceX96, tick, etc.)
538- let s0Res = self ._dryCallRaw (
505+ // slot0 (uint160 sqrtPriceX96, int24, uint16, uint16, uint16, uint8, bool)
506+ let s0Res = self ._dryCall (
539507 to : poolEVMAddress ,
540- calldata : EVMAbiHelpers .buildCalldata (selector : SEL_SLOT0 , args : []),
508+ signature : " slot0()" ,
509+ args : [],
541510 gasLimit : 1_000_000 ,
511+ resultTypes : [Type <UInt >(), Type <Int32 >(), Type <UInt16 >(), Type <UInt16 >(), Type <UInt16 >(), Type <UInt8 >(), Type <Bool >()]
542512 )
543- let s0w = words (s0Res ! . data )
544- let sqrtPriceX96 = wordToUIntN ( s0w [0 ], 160 )
513+ assert (s0Res . results . length == 7 , message : " slot0: invalid ABI-encoded return data" )
514+ let sqrtPriceX96 = s0Res . results [0 ] as ! UInt
545515
546516 // Get current active liquidity
547- let liqRes = self ._dryCallRaw (
517+ // liquidity() (uint128 liquidity)
518+ let liqRes = self ._dryCall (
548519 to : poolEVMAddress ,
549- calldata : EVMAbiHelpers .buildCalldata (selector : SEL_LIQUIDITY , args : []),
520+ signature : " liquidity()" ,
521+ args : [],
550522 gasLimit : 300_000 ,
523+ resultTypes : [Type <UInt >()]
551524 )
552- let L = wordToUIntN (words (liqRes ! .data )[0 ], 128 )
525+ assert (liqRes .results .length == 1 , message : " liquidity: invalid ABI-encoded return data" )
526+ let L = liqRes .results [0 ] as ! UInt
553527
554528 // Calculate price multiplier based on 6% price impact (600 bps)
555529 // Use UInt256 throughout to prevent overflow in multiplication operations
@@ -626,13 +600,18 @@ access(all) contract UniswapV3SwapConnectors {
626600
627601 let args = [pathBytes , amount ]
628602
629- let res = self ._dryCall (self .quoterAddress , callSig , args , 10_000_000 )
603+ let res = self ._dryCall (
604+ to : self .quoterAddress ,
605+ signature : callSig ,
606+ args : args ,
607+ gasLimit : 10_000_000 ,
608+ resultTypes : [Type <UInt256 >()]
609+ )
630610 if res == nil || res ! .status ! = EVM .Status .successful { return nil }
631611
632- let decoded = EVM .decodeABI (types : [Type <UInt256 >()], data : res ! .data )
633- if decoded .length == 0 { return nil }
612+ if res ! .results .length == 0 { return nil }
634613
635- return decoded [0 ] as ! UInt256
614+ return res ! . results [0 ] as ! UInt256
636615 }
637616
638617 /// Executes exact input swap via router
@@ -701,7 +680,7 @@ access(all) contract UniswapV3SwapConnectors {
701680 args : [exactInputParams ],
702681 gasLimit : 10_000_000 ,
703682 value : 0 ,
704- resultTypes : nil
683+ resultTypes : [ Type < UInt256 >()]
705684 )!
706685 if swapRes .status ! = EVM .Status .successful {
707686 UniswapV3SwapConnectors ._callError (
@@ -717,13 +696,14 @@ access(all) contract UniswapV3SwapConnectors {
717696 args : [self .routerAddress , 0 as UInt256 ],
718697 gasLimit : 60_000 ,
719698 value : 0 ,
720- resultTypes : [ Type < UInt256 >()]
699+ resultTypes : nil
721700 )!
722701 if resetAllowanceRes .status ! = EVM .Status .successful {
723702 UniswapV3SwapConnectors ._callError (" approve(address,uint256)" , resetAllowanceRes , inToken , idType , id , self .getType ())
724703 }
725- assert (resetAllowanceRes .results .length == 1 , message : " invalid swap return data" )
726- let amountOut = resetAllowanceRes .results [0 ] as ! UInt256
704+
705+ assert (swapRes .results .length == 1 , message : " invalid swap return data" )
706+ let amountOut = swapRes .results [0 ] as ! UInt256
727707
728708 let outVaultType = reverse ? self .inType () : self .outType ()
729709 let outTokenEVMAddress =
@@ -759,19 +739,23 @@ access(all) contract UniswapV3SwapConnectors {
759739
760740 access (self ) view fun borrowCOA (): auth (EVM.Owner ) &EVM.CadenceOwnedAccount ? { return self .coaCapability .borrow () }
761741
762- access (self ) fun _dryCall (_ to : EVM .EVMAddress , _ signature : String , _ args : [AnyStruct ], _ gas : UInt64 ): EVM .Result ? {
763- let calldata = EVM .encodeABIWithSignature (signature , args )
764- let valueBalance = EVM .Balance (attoflow : 0 )
765- if let coa = self .borrowCOA () {
766- return coa .dryCall (to : to , data : calldata , gasLimit : gas , value : valueBalance )
767- }
768- return nil
769- }
770-
771- access (self ) fun _dryCallRaw (to : EVM .EVMAddress , calldata : [UInt8 ], gasLimit : UInt64 ): EVM .Result ? {
772- let valueBalance = EVM .Balance (attoflow : 0 )
742+ access (self )
743+ fun _dryCall (
744+ to : EVM .EVMAddress ,
745+ signature : String ,
746+ args : [AnyStruct ],
747+ gasLimit : UInt64 ,
748+ resultTypes : [Type ]?
749+ ): EVM .ResultDecoded ? {
773750 if let coa = self .borrowCOA () {
774- return coa .dryCall (to : to , data : calldata , gasLimit : gasLimit , value : valueBalance )
751+ return coa .dryCallWithSigAndArgs (
752+ to : to ,
753+ signature : signature ,
754+ args : args ,
755+ gasLimit : gasLimit ,
756+ value : EVM .Balance (attoflow : 0 ),
757+ resultTypes : resultTypes
758+ )
775759 }
776760 return nil
777761 }
@@ -818,21 +802,17 @@ access(all) contract UniswapV3SwapConnectors {
818802 }
819803
820804 access (self ) fun getPoolToken0 (_ pool : EVM .EVMAddress ): EVM .EVMAddress {
821- // token0() selector = 0x0dfe1681
822- let SEL_TOKEN0 : [UInt8 ] = [0x0d , 0xfe , 0x16 , 0x81 ]
823- let res = self ._dryCallRaw (
805+ let res = self ._dryCall (
824806 to : pool ,
825- calldata : EVMAbiHelpers .buildCalldata (selector : SEL_TOKEN0 , args : []),
807+ signature : " token0()" ,
808+ args : [],
826809 gasLimit : 150_000 ,
810+ resultTypes : [Type <EVM .EVMAddress >()]
827811 )!
828812 assert (res .status == EVM .Status .successful , message : " token0() call failed" )
829813
830- let word = res .data
831- if word .length < 32 { panic (" getPoolToken0: invalid ABI word length" ) }
832-
833- let addrSlice = word .slice (from : 12 , upTo : 32 )
834- let addrBytes = addrSlice .toConstantSized <[UInt8 ; 20]>()!
835- return EVM .EVMAddress (bytes : addrBytes )
814+ assert (res .results .length == 1 , message : " token0: invalid ABI-encoded return data" )
815+ return res .results [0 ] as ! EVM .EVMAddress
836816 }
837817
838818 access (self ) fun isZeroForOne (hopIndex : Int , reverse : Bool ): Bool {
0 commit comments