diff --git a/pkg/vault/contracts/MevRouter.sol b/pkg/vault/contracts/MevRouter.sol index 23fe8ef9d..e874f9692 100644 --- a/pkg/vault/contracts/MevRouter.sol +++ b/pkg/vault/contracts/MevRouter.sol @@ -2,12 +2,15 @@ pragma solidity ^0.8.24; +import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { IPermit2 } from "permit2/src/interfaces/IPermit2.sol"; import { IWETH } from "@balancer-labs/v3-interfaces/contracts/solidity-utils/misc/IWETH.sol"; import { IMevRouter } from "@balancer-labs/v3-interfaces/contracts/vault/IMevRouter.sol"; import { IMevTaxCollector } from "@balancer-labs/v3-interfaces/contracts/vault/IMevTaxCollector.sol"; +import { IRouterSwap } from "@balancer-labs/v3-interfaces/contracts/vault/IMevRouter.sol"; import { IVault } from "@balancer-labs/v3-interfaces/contracts/vault/IVault.sol"; +import { SwapKind } from "@balancer-labs/v3-interfaces/contracts/vault/VaultTypes.sol"; import { SingletonAuthentication } from "./SingletonAuthentication.sol"; import { RouterSwap } from "./RouterSwap.sol"; @@ -78,6 +81,78 @@ contract MevRouter is IMevRouter, SingletonAuthentication, RouterSwap { priorityGasThreshold = newPriorityGasThreshold; } + /// @inheritdoc IRouterSwap + function swapSingleTokenExactIn( + address pool, + IERC20 tokenIn, + IERC20 tokenOut, + uint256 exactAmountIn, + uint256 minAmountOut, + uint256 deadline, + bool wethIsEth, + bytes calldata userData + ) external payable override(RouterSwap, IRouterSwap) saveSender(msg.sender) returns (uint256) { + chargeMevTax(pool); + + return + abi.decode( + _vault.unlock( + abi.encodeCall( + RouterSwap.swapSingleTokenHook, + SwapSingleTokenHookParams({ + sender: msg.sender, + kind: SwapKind.EXACT_IN, + pool: pool, + tokenIn: tokenIn, + tokenOut: tokenOut, + amountGiven: exactAmountIn, + limit: minAmountOut, + deadline: deadline, + wethIsEth: wethIsEth, + userData: userData + }) + ) + ), + (uint256) + ); + } + + /// @inheritdoc IRouterSwap + function swapSingleTokenExactOut( + address pool, + IERC20 tokenIn, + IERC20 tokenOut, + uint256 exactAmountOut, + uint256 maxAmountIn, + uint256 deadline, + bool wethIsEth, + bytes calldata userData + ) external payable override(RouterSwap, IRouterSwap) saveSender(msg.sender) returns (uint256) { + chargeMevTax(pool); + + return + abi.decode( + _vault.unlock( + abi.encodeCall( + RouterSwap.swapSingleTokenHook, + SwapSingleTokenHookParams({ + sender: msg.sender, + kind: SwapKind.EXACT_OUT, + pool: pool, + tokenIn: tokenIn, + tokenOut: tokenOut, + amountGiven: exactAmountOut, + limit: maxAmountIn, + deadline: deadline, + wethIsEth: wethIsEth, + userData: userData + }) + ) + ), + (uint256) + ); + } + function chargeMevTax(address pool) internal { if (_isMevTaxEnabled == false) { return; diff --git a/pkg/vault/contracts/RouterSwap.sol b/pkg/vault/contracts/RouterSwap.sol index fef189fe7..8beaee797 100644 --- a/pkg/vault/contracts/RouterSwap.sol +++ b/pkg/vault/contracts/RouterSwap.sol @@ -36,7 +36,7 @@ contract RouterSwap is IRouterSwap, RouterCommon { uint256 deadline, bool wethIsEth, bytes calldata userData - ) external payable saveSender(msg.sender) returns (uint256) { + ) external payable virtual saveSender(msg.sender) returns (uint256) { return abi.decode( _vault.unlock( @@ -70,7 +70,7 @@ contract RouterSwap is IRouterSwap, RouterCommon { uint256 deadline, bool wethIsEth, bytes calldata userData - ) external payable saveSender(msg.sender) returns (uint256) { + ) external payable virtual saveSender(msg.sender) returns (uint256) { return abi.decode( _vault.unlock( diff --git a/pkg/vault/test/gas/.hardhat-snapshots/[PoolMock - WithNestedPool - BatchRouter] swap exact in - reverse - tokenD-tokenA b/pkg/vault/test/gas/.hardhat-snapshots/[PoolMock - WithNestedPool - BatchRouter] swap exact in - reverse - tokenD-tokenA index d43e23baf..655a05125 100644 --- a/pkg/vault/test/gas/.hardhat-snapshots/[PoolMock - WithNestedPool - BatchRouter] swap exact in - reverse - tokenD-tokenA +++ b/pkg/vault/test/gas/.hardhat-snapshots/[PoolMock - WithNestedPool - BatchRouter] swap exact in - reverse - tokenD-tokenA @@ -1 +1 @@ -508.5k \ No newline at end of file +508.4k \ No newline at end of file diff --git a/pkg/vault/test/gas/.hardhat-snapshots/[PoolMock - WithNestedPool - BatchRouter] swap exact in - tokenA-tokenD b/pkg/vault/test/gas/.hardhat-snapshots/[PoolMock - WithNestedPool - BatchRouter] swap exact in - tokenA-tokenD index 107780d07..32bdf3000 100644 --- a/pkg/vault/test/gas/.hardhat-snapshots/[PoolMock - WithNestedPool - BatchRouter] swap exact in - tokenA-tokenD +++ b/pkg/vault/test/gas/.hardhat-snapshots/[PoolMock - WithNestedPool - BatchRouter] swap exact in - tokenA-tokenD @@ -1 +1 @@ -514.1k \ No newline at end of file +514.0k \ No newline at end of file diff --git a/pkg/vault/test/gas/.hardhat-snapshots/[PoolMockWithHooks - WithNestedPool - BatchRouter] swap exact in - reverse - tokenD-tokenA b/pkg/vault/test/gas/.hardhat-snapshots/[PoolMockWithHooks - WithNestedPool - BatchRouter] swap exact in - reverse - tokenD-tokenA index 83ca925e3..05592e4a8 100644 --- a/pkg/vault/test/gas/.hardhat-snapshots/[PoolMockWithHooks - WithNestedPool - BatchRouter] swap exact in - reverse - tokenD-tokenA +++ b/pkg/vault/test/gas/.hardhat-snapshots/[PoolMockWithHooks - WithNestedPool - BatchRouter] swap exact in - reverse - tokenD-tokenA @@ -1 +1 @@ -559.0k \ No newline at end of file +558.9k \ No newline at end of file