@@ -15,7 +15,7 @@ import {Enum} from "safe/common/Enum.sol";
1515// Composable CoW
1616import {IConditionalOrder, ComposableCoW} from "composable-cow/src/ComposableCoW.sol " ;
1717import {IValueFactory} from "composable-cow/src/interfaces/IValueFactory.sol " ;
18- import {ExtensibleFallbackHandler} from "safe/handler/ExtensibleFallbackHandler.sol " ;
18+ import {ExtensibleFallbackHandler, ERC1271 } from "safe/handler/ExtensibleFallbackHandler.sol " ;
1919import {SignatureVerifierMuxer} from "safe/handler/extensible/SignatureVerifierMuxer.sol " ;
2020import {ISafeSignatureVerifier} from "safe/handler/extensible/SignatureVerifierMuxer.sol " ;
2121
@@ -50,8 +50,8 @@ contract PolyswapTest is Test {
5050 address public constant POLYGON_TIMESTAMP_VALUE_FACTORY = 0x52eD56Da04309Aca4c3FECC595298d80C2f16BAc ; // TimestampValueFactory on Polygon
5151
5252 // BLINDSPOT: Need real Polymarket contract address on Polygon
53- // Polymarket CTF Exchange contract address - needs to be updated with real address
54- address public constant POLYGON_POLYMARKET_EXCHANGE = address (0 ); // UPDATE REQUIRED
53+ // Polymarket CTF Exchange contract address
54+ address public constant POLYGON_POLYMARKET_EXCHANGE = address (0x4bFb41d5B3570DeFd03C39a9A4D8dE6Bd8B8982E );
5555
5656 // Test tokens on Polygon
5757 address public constant USDC_POLYGON = 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174 ;
@@ -145,10 +145,10 @@ contract PolyswapTest is Test {
145145 PolyswapOrder.Data memory order = _createTestOrder ();
146146
147147 // Should not revert on validation
148- PolyswapOrder.validate (order, Trading ( address (mockPolymarket)) );
148+ PolyswapOrder.validate (order);
149149
150150 // Should generate valid GPv2Order
151- GPv2Order.Data memory gpv2Order = PolyswapOrder.orderFor (order, Trading ( address (mockPolymarket)) );
151+ GPv2Order.Data memory gpv2Order = PolyswapOrder.orderFor (order);
152152
153153 assertEq (address (gpv2Order.sellToken), address (order.sellToken));
154154 assertEq (address (gpv2Order.buyToken), address (order.buyToken));
@@ -206,28 +206,28 @@ contract PolyswapTest is Test {
206206 invalidOrder.buyToken = invalidOrder.sellToken;
207207
208208 vm.expectRevert (abi.encodeWithSelector (IConditionalOrder.OrderNotValid.selector , "same token " ));
209- PolyswapOrder.validate (invalidOrder, Trading ( address (mockPolymarket)) );
209+ PolyswapOrder.validate (invalidOrder);
210210
211211 // Test zero sell amount
212212 invalidOrder = _createTestOrder ();
213213 invalidOrder.sellAmount = 0 ;
214214
215215 vm.expectRevert (abi.encodeWithSelector (IConditionalOrder.OrderNotValid.selector , "invalid sell amount " ));
216- PolyswapOrder.validate (invalidOrder, Trading ( address (mockPolymarket)) );
216+ PolyswapOrder.validate (invalidOrder);
217217
218218 // Test zero buy amount
219219 invalidOrder = _createTestOrder ();
220220 invalidOrder.minBuyAmount = 0 ;
221221
222222 vm.expectRevert (abi.encodeWithSelector (IConditionalOrder.OrderNotValid.selector , "invalid min buy amount " ));
223- PolyswapOrder.validate (invalidOrder, Trading ( address (mockPolymarket)) );
223+ PolyswapOrder.validate (invalidOrder);
224224
225225 // Test invalid time range
226226 invalidOrder = _createTestOrder ();
227227 invalidOrder.t = invalidOrder.t0 - 1 ;
228228
229229 vm.expectRevert (abi.encodeWithSelector (IConditionalOrder.OrderNotValid.selector , "invalid end date " ));
230- PolyswapOrder.validate (invalidOrder, Trading ( address (mockPolymarket)) );
230+ PolyswapOrder.validate (invalidOrder);
231231 }
232232
233233 // ===== INTEGRATION TESTS WITH REAL CONTRACTS =====
@@ -325,7 +325,7 @@ contract PolyswapTest is Test {
325325 order.t = uint256 (block .timestamp - 1 ); // Expired
326326
327327 vm.expectRevert (abi.encodeWithSelector (IConditionalOrder.OrderNotValid.selector , INVALID_END_DATE));
328- PolyswapOrder.validate (order, Trading ( address (mockPolymarket)) );
328+ PolyswapOrder.validate (order);
329329 }
330330
331331 /**
@@ -337,7 +337,7 @@ contract PolyswapTest is Test {
337337 order.polymarketOrderHash = bytes32 (0 );
338338
339339 vm.expectRevert (abi.encodeWithSelector (IConditionalOrder.OrderNotValid.selector , INVALID_POLYMARKET_ORDER_HASH));
340- PolyswapOrder.validate (order, Trading ( address (mockPolymarket)) );
340+ PolyswapOrder.validate (order);
341341 }
342342
343343 // TODO more negative tests
@@ -352,13 +352,13 @@ contract PolyswapTest is Test {
352352
353353 // Measure validation gas
354354 uint256 gasStart = gasleft ();
355- PolyswapOrder.validate (order, Trading ( address (mockPolymarket)) );
355+ PolyswapOrder.validate (order);
356356 uint256 validationGas = gasStart - gasleft ();
357357 console.log ("Validation gas: " , validationGas);
358358
359359 // Measure order generation gas
360360 gasStart = gasleft ();
361- PolyswapOrder.orderFor (order, Trading ( address (mockPolymarket)) );
361+ PolyswapOrder.orderFor (order);
362362 uint256 orderGenGas = gasStart - gasleft ();
363363 console.log ("Order generation gas: " , orderGenGas);
364364
@@ -367,6 +367,59 @@ contract PolyswapTest is Test {
367367 assertTrue (orderGenGas < 30000 , "Order generation gas too high " );
368368 }
369369
370+ /**
371+ * @dev Test isValidSafeSignature function from ComposableCoW in real context
372+ */
373+ function test_integration_isValidSafeSignature () public {
374+ // Setup: Polymarket order fulfilled so condition is met
375+ mockPolymarket.setOrderStatus (TEST_ORDER_HASH, true , 0 );
376+
377+ PolyswapOrder.Data memory order = _createTestOrder ();
378+
379+ // Create conditional order params
380+ IConditionalOrder.ConditionalOrderParams memory params = IConditionalOrder.ConditionalOrderParams ({
381+ handler: IConditionalOrder (address (polyswap)),
382+ salt: keccak256 (abi.encodePacked ("signature-test " , block .timestamp )),
383+ staticInput: abi.encode (order)
384+ });
385+
386+ // Create the conditional order first
387+ vm.prank (owner);
388+ testSafe.executeSingleOwner (
389+ address (composableCow), 0 , abi.encodeCall (composableCow.create, (params, false )), Enum.Operation.Call, owner
390+ );
391+
392+ // Get the tradeable order that would be generated
393+ GPv2Order.Data memory gpv2Order =
394+ polyswap.getTradeableOrder (address (testSafe), address (this ), bytes32 (0 ), abi.encode (order), bytes ("" ));
395+
396+ // Create the payload for isValidSafeSignature
397+ ComposableCoW.PayloadStruct memory payload = ComposableCoW.PayloadStruct ({
398+ proof: new bytes32 [](0 ), // Empty proof for single order
399+ params: params,
400+ offchainInput: bytes ("" )
401+ });
402+
403+ // Hash the order for signature validation
404+ bytes32 orderHash = GPv2Order.hash (gpv2Order, composableCow.domainSeparator ());
405+
406+ bytes32 domainSeparator = composableCow.domainSeparator ();
407+
408+ // Call isValidSafeSignature - this should succeed
409+ bytes4 result = composableCow.isValidSafeSignature (
410+ testSafe,
411+ address (this ),
412+ orderHash,
413+ domainSeparator,
414+ GPv2Order.TYPE_HASH,
415+ abi.encode (gpv2Order),
416+ abi.encode (payload)
417+ );
418+
419+ // Should return the ERC1271 magic value
420+ assertEq (result, ERC1271 .isValidSignature.selector );
421+ }
422+
370423 // /**
371424 // * @dev Test with maximum uint256 values to check for overflows
372425 // */
@@ -409,7 +462,7 @@ contract PolyswapTest is Test {
409462 PolyswapOrder.Data memory order = PolyswapOrder.Data ({
410463 sellToken: IERC20 (USDC_POLYGON),
411464 buyToken: IERC20 (USDT_POLYGON),
412- receiver: address (0 ),
465+ receiver: address (1 ),
413466 sellAmount: sellAmount,
414467 minBuyAmount: minBuyAmount,
415468 t0: block .timestamp ,
@@ -419,8 +472,8 @@ contract PolyswapTest is Test {
419472 });
420473
421474 // Should not revert with valid parameters
422- PolyswapOrder.validate (order, Trading ( address (mockPolymarket)) );
423- GPv2Order.Data memory gpv2Order = PolyswapOrder.orderFor (order, Trading ( address (mockPolymarket)) );
475+ PolyswapOrder.validate (order);
476+ GPv2Order.Data memory gpv2Order = PolyswapOrder.orderFor (order);
424477
425478 assertEq (gpv2Order.sellAmount, sellAmount);
426479 assertEq (gpv2Order.buyAmount, minBuyAmount);
@@ -469,19 +522,19 @@ contract PolyswapTest is Test {
469522 safeOwner
470523 );
471524
472- // // Set domain verifier for CoW Protocol through the fallback handler
473- // bytes32 domainSeparator = composableCow.domainSeparator();
474- // safe.executeSingleOwner(
475- // address(safe),
476- // 0,
477- // abi.encodeWithSelector(
478- // SignatureVerifierMuxer.setDomainVerifier.selector,
479- // domainSeparator,
480- // ISafeSignatureVerifier(composableCow)
481- // ),
482- // Enum.Operation.Call,
483- // safeOwner
484- // );
525+ // Set domain verifier for CoW Protocol through the fallback handler
526+ bytes32 domainSeparator = composableCow.domainSeparator ();
527+ safe.executeSingleOwner (
528+ address (safe),
529+ 0 ,
530+ abi.encodeWithSelector (
531+ SignatureVerifierMuxer.setDomainVerifier.selector ,
532+ domainSeparator,
533+ ISafeSignatureVerifier (composableCow)
534+ ),
535+ Enum.Operation.Call,
536+ safeOwner
537+ );
485538
486539 vm.stopPrank ();
487540 }
@@ -507,7 +560,7 @@ contract PolyswapTest is Test {
507560 return PolyswapOrder.Data ({
508561 sellToken: IERC20 (USDC_POLYGON),
509562 buyToken: IERC20 (USDT_POLYGON),
510- receiver: address (0 ),
563+ receiver: address (1 ),
511564 sellAmount: 100000 , // 0.1 USDC (6 decimals)
512565 minBuyAmount: 80000 , // 0.08 USDT (6 decimals)
513566 t0: block .timestamp ,
0 commit comments