@@ -3,6 +3,7 @@ pragma solidity 0.8.26;
33
44import { EIP712 } from "./abstracts/EIP712.sol " ;
55import { TokenCollector } from "./abstracts/TokenCollector.sol " ;
6+ import { Ownable } from "./abstracts/Ownable.sol " ;
67
78import { IGenericSwap } from "./interfaces/IGenericSwap.sol " ;
89import { IStrategy } from "./interfaces/IStrategy.sol " ;
@@ -14,42 +15,84 @@ import { SignatureValidator } from "./libraries/SignatureValidator.sol";
1415/// @title GenericSwap Contract
1516/// @author imToken Labs
1617/// @notice This contract facilitates token swaps using SmartOrderStrategy strategies.
17- contract GenericSwap is IGenericSwap , TokenCollector , EIP712 {
18+ contract GenericSwap is IGenericSwap , TokenCollector , EIP712 , Ownable {
1819 using Asset for address ;
1920
21+ /// @notice Mapping to track addresses authorized as solvers.
22+ /// @dev Maps each address to a boolean indicating whether it is an authorized solver.
23+ mapping (address solver = > bool isSolver ) public solvers;
24+
2025 /// @notice Mapping to keep track of filled swaps.
2126 /// @dev Stores the status of swaps to ensure they are not filled more than once.
2227 mapping (bytes32 swapHash = > bool isFilled ) public filledSwap;
2328
29+ modifier onlySolver () {
30+ if (! solvers[msg .sender ]) revert InvalidSolver ();
31+ _;
32+ }
33+
2434 /// @notice Constructor to initialize the contract with the permit2 and allowance target.
2535 /// @param _uniswapPermit2 The address for Uniswap permit2.
2636 /// @param _allowanceTarget The address for the allowance target.
27- constructor (address _uniswapPermit2 , address _allowanceTarget ) TokenCollector (_uniswapPermit2, _allowanceTarget) {}
37+ constructor (
38+ address _uniswapPermit2 ,
39+ address _allowanceTarget ,
40+ address _owner ,
41+ address [] memory _trustedSolvers
42+ ) TokenCollector (_uniswapPermit2, _allowanceTarget) Ownable (_owner) {
43+ uint256 length = _trustedSolvers.length ;
44+ for (uint256 i; i < length; ++ i) {
45+ solvers[_trustedSolvers[i]] = true ;
46+ }
47+ }
2848
2949 /// @notice Receive function to receive ETH.
3050 receive () external payable {}
3151
52+ function addSolver (address solver ) external onlyOwner {
53+ if (solver == address (0 )) revert ZeroAddress ();
54+
55+ if (! solvers[solver]) {
56+ solvers[solver] = true ;
57+
58+ emit AddSolver (solver);
59+ }
60+ }
61+
62+ function removeSolver (address solver ) external onlyOwner {
63+ if (solvers[solver]) {
64+ solvers[solver] = false ;
65+
66+ emit RemoveSolver (solver);
67+ }
68+ }
69+
3270 /// @inheritdoc IGenericSwap
33- function executeSwap (GenericSwapData calldata swapData , bytes calldata takerTokenPermit ) external payable returns (uint256 returnAmount ) {
34- returnAmount = _executeSwap (swapData, msg .sender , takerTokenPermit);
71+ function executeSwap (
72+ GenericSwapData calldata swapData ,
73+ bytes calldata strategyData ,
74+ bytes calldata takerTokenPermit
75+ ) external payable returns (uint256 returnAmount ) {
76+ returnAmount = _executeSwap (swapData, strategyData, msg .sender , takerTokenPermit);
3577
3678 _emitGSExecuted (getGSDataHash (swapData), swapData, msg .sender , returnAmount);
3779 }
3880
3981 /// @inheritdoc IGenericSwap
4082 function executeSwapWithSig (
4183 GenericSwapData calldata swapData ,
84+ bytes calldata strategyData ,
4285 bytes calldata takerTokenPermit ,
4386 address taker ,
4487 bytes calldata takerSig
45- ) external payable returns (uint256 returnAmount ) {
88+ ) external payable onlySolver returns (uint256 returnAmount ) {
4689 bytes32 swapHash = getGSDataHash (swapData);
4790 bytes32 gs712Hash = getEIP712Hash (swapHash);
4891 if (filledSwap[swapHash]) revert AlreadyFilled ();
4992 filledSwap[swapHash] = true ;
5093 if (! SignatureValidator.validateSignature (taker, gs712Hash, takerSig)) revert InvalidSignature ();
5194
52- returnAmount = _executeSwap (swapData, taker, takerTokenPermit);
95+ returnAmount = _executeSwap (swapData, strategyData, taker, takerTokenPermit);
5396
5497 _emitGSExecuted (swapHash, swapData, taker, returnAmount);
5598 }
@@ -61,6 +104,7 @@ contract GenericSwap is IGenericSwap, TokenCollector, EIP712 {
61104 /// @return returnAmount The output amount of the swap.
62105 function _executeSwap (
63106 GenericSwapData calldata _swapData ,
107+ bytes calldata strategyData ,
64108 address _authorizedUser ,
65109 bytes calldata _takerTokenPermit
66110 ) private returns (uint256 returnAmount ) {
@@ -78,7 +122,7 @@ contract GenericSwap is IGenericSwap, TokenCollector, EIP712 {
78122 _collect (_inputToken, _authorizedUser, _swapData.maker, _swapData.takerTokenAmount, _takerTokenPermit);
79123 }
80124
81- IStrategy (_swapData.maker).executeStrategy { value: msg .value }(_outputToken, _swapData. strategyData);
125+ IStrategy (_swapData.maker).executeStrategy { value: msg .value }(_outputToken, strategyData);
82126
83127 returnAmount = _outputToken.getBalance (address (this ));
84128 if (returnAmount > 1 ) {
0 commit comments