Skip to content

Commit 8c726da

Browse files
committed
feat: make fee collector open and competitive
New fee collector implementation where anyone can make any calls from the collector in return for a specific amount of the fee token. Searchers can then compete to execute based on the current balance of tokens and the best route
1 parent 5084b16 commit 8c726da

File tree

1 file changed

+28
-36
lines changed

1 file changed

+28
-36
lines changed

src/FeeCollector.sol

+28-36
Original file line numberDiff line numberDiff line change
@@ -5,62 +5,54 @@ import {Owned} from "solmate/auth/Owned.sol";
55
import {ERC20} from "solmate/tokens/ERC20.sol";
66
import {SafeTransferLib} from "solmate/utils/SafeTransferLib.sol";
77
import {IFeeCollector} from "./interfaces/IFeeCollector.sol";
8-
import {IPermit2} from "./external/IPermit2.sol";
98

109
/// @notice The collector of protocol fees that will be used to swap and send to a fee recipient address.
1110
contract FeeCollector is Owned, IFeeCollector {
1211
using SafeTransferLib for ERC20;
1312

14-
error UniversalRouterCallFailed();
13+
error CallFailed();
1514

16-
address private immutable universalRouter;
15+
struct Call {
16+
address to;
17+
bytes data;
18+
}
1719

20+
address private immutable universalRouter;
21+
address public feeRecipient;
22+
uin256 public feeTokenAmount;
1823
ERC20 private immutable feeToken;
19-
IPermit2 private immutable permit2;
20-
21-
uint256 private constant MAX_APPROVAL_AMOUNT = type(uint256).max;
22-
uint160 private constant MAX_PERMIT2_APPROVAL_AMOUNT = type(uint160).max;
23-
uint48 private constant MAX_PERMIT2_DEADLINE = type(uint48).max;
2424

25-
constructor(address _owner, address _universalRouter, address _permit2, address _feeToken) Owned(_owner) {
25+
constructor(address _owner, address _universalRouter, address _feeToken, uint256 _feeTokenAmount) Owned(_owner) {
2626
universalRouter = _universalRouter;
2727
feeToken = ERC20(_feeToken);
28-
permit2 = IPermit2(_permit2);
28+
feeTokenAmount = _feeTokenAmount;
2929
}
3030

31-
/// @inheritdoc IFeeCollector
32-
function swapBalance(bytes calldata swapData, uint256 nativeValue) external onlyOwner {
33-
_execute(swapData, nativeValue);
34-
}
35-
36-
/// @inheritdoc IFeeCollector
37-
function swapBalance(bytes calldata swapData, uint256 nativeValue, ERC20[] calldata tokensToApprove)
38-
external
39-
onlyOwner
40-
{
41-
unchecked {
42-
for (uint256 i = 0; i < tokensToApprove.length; i++) {
43-
tokensToApprove[i].safeApprove(address(permit2), MAX_APPROVAL_AMOUNT);
44-
permit2.approve(
45-
address(tokensToApprove[i]), universalRouter, MAX_PERMIT2_APPROVAL_AMOUNT, MAX_PERMIT2_DEADLINE
46-
);
31+
/// @notice allow anyone to make any arbitrary calls from this address
32+
/// @dev as long as they pay `feeTokenAmount` to the `feeRecipient`
33+
/// this creates a competitive auction as the balances of this contract increase
34+
/// to find the optimal path for the swap
35+
function swapBalances(Call[] calldata calls) external {
36+
for (uint256 i = 0; i < calls.length; i++) {
37+
(bool success, ) = calls[i].to.call(calls[i].data);
38+
if (!success) {
39+
revert CallFailed();
4740
}
4841
}
4942

50-
_execute(swapData, nativeValue);
43+
feeToken.safeTransferFrom(msg.sender, feeRecipient, feeTokenAmount);
44+
}
45+
46+
function setFeeRecipient(address _feeRecipient) external onlyOwner {
47+
feeRecipient = _feeRecipient;
5148
}
5249

53-
/// @notice Helper function to call UniversalRouter.
54-
/// @param swapData The bytes call data to be forwarded to UniversalRouter.
55-
/// @param nativeValue The amount of native currency to send to UniversalRouter.
56-
function _execute(bytes calldata swapData, uint256 nativeValue) internal {
57-
(bool success,) = universalRouter.call{value: nativeValue}(swapData);
58-
if (!success) revert UniversalRouterCallFailed();
50+
function setFeeToken(uint256 _feeTokenAmount) external onlyOwner {
51+
feeTokenAmount = _feeTokenAmount;
5952
}
6053

61-
/// @inheritdoc IFeeCollector
62-
function withdrawFeeToken(address feeRecipient, uint256 amount) external onlyOwner {
63-
feeToken.safeTransfer(feeRecipient, amount);
54+
function setFeeTokenAmount(uint256 _feeTokenAmount) external onlyOwner {
55+
feeTokenAmount = _feeTokenAmount;
6456
}
6557

6658
receive() external payable {}

0 commit comments

Comments
 (0)