@@ -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,21 +15,58 @@ 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
3371 function executeSwap (
3472 GenericSwapData calldata swapData ,
@@ -47,7 +85,7 @@ contract GenericSwap is IGenericSwap, TokenCollector, EIP712 {
4785 bytes calldata takerTokenPermit ,
4886 address taker ,
4987 bytes calldata takerSig
50- ) external payable returns (uint256 returnAmount ) {
88+ ) external payable onlySolver returns (uint256 returnAmount ) {
5189 bytes32 swapHash = getGSDataHash (swapData);
5290 bytes32 gs712Hash = getEIP712Hash (swapHash);
5391 if (filledSwap[swapHash]) revert AlreadyFilled ();
@@ -84,7 +122,7 @@ contract GenericSwap is IGenericSwap, TokenCollector, EIP712 {
84122 _collect (_inputToken, _authorizedUser, _swapData.maker, _swapData.takerTokenAmount, _takerTokenPermit);
85123 }
86124
87- IStrategy (_swapData.maker).executeStrategy { value: msg .value }(_outputToken, _swapData. strategyData);
125+ IStrategy (_swapData.maker).executeStrategy { value: msg .value }(_outputToken, strategyData);
88126
89127 returnAmount = _outputToken.getBalance (address (this ));
90128 if (returnAmount > 1 ) {
0 commit comments