From cdca88d89d6a8ef601ae8511f8d706f76605dc31 Mon Sep 17 00:00:00 2001 From: Serge <2901744+evercoinx@users.noreply.github.com> Date: Tue, 19 May 2026 09:29:48 +0200 Subject: [PATCH] fix: add event during token recovery on Swapper --- src/Swapper.sol | 2 ++ src/interfaces/ISwapper.sol | 8 ++++++++ test/unit/Swapper.t.sol | 23 +++++++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/src/Swapper.sol b/src/Swapper.sol index d45084ad..afa28e15 100644 --- a/src/Swapper.sol +++ b/src/Swapper.sol @@ -147,6 +147,8 @@ contract Swapper is UUPSUpgradeable, AccessControlUpgradeable, PausableUpgradeab } else { IERC20(token).safeTransfer(to, amount); } + + emit TokensRecovered(token, to, amount); } /** diff --git a/src/interfaces/ISwapper.sol b/src/interfaces/ISwapper.sol index 731d46d8..19c276bc 100644 --- a/src/interfaces/ISwapper.sol +++ b/src/interfaces/ISwapper.sol @@ -95,6 +95,14 @@ interface ISwapper is IAccessControl { */ event NativeWrapperSet(address indexed wrapper); + /** + * @notice Emitted when stranded tokens or native ETH are recovered by an admin. + * @param token Token address recovered, or the native ETH sentinel (0xEeee...eeEE). + * @param to Recipient of the recovered funds. + * @param amount Amount recovered. + */ + event TokensRecovered(address indexed token, address indexed to, uint256 amount); + /** * @notice Reverts when a required address argument is zero. */ diff --git a/test/unit/Swapper.t.sol b/test/unit/Swapper.t.sol index 58ad607c..14457d90 100644 --- a/test/unit/Swapper.t.sol +++ b/test/unit/Swapper.t.sol @@ -418,6 +418,17 @@ contract SwapperTest is Test { assertEq(tokenIn.balanceOf(address(swapper)), 0, "Swapper balance should be zero"); } + function test_recoverTokens_WhenValid_EmitsTokensRecovered() public { + uint256 rescueAmount = 50 ether; + tokenIn.mint(address(swapper), rescueAmount); + + vm.expectEmit(true, true, false, true, address(swapper)); + emit ISwapper.TokensRecovered(address(tokenIn), recipient, rescueAmount); + + vm.prank(admin); + swapper.recoverTokens(address(tokenIn), recipient, rescueAmount); + } + function test_recoverTokens_WhenNativeETH_TransfersNativeETH() public { uint256 rescueAmount = 5 ether; @@ -433,6 +444,18 @@ contract SwapperTest is Test { assertEq(address(swapper).balance, 0, "Swapper balance should be zero"); } + function test_recoverTokens_WhenNativeETH_EmitsTokensRecovered() public { + uint256 rescueAmount = 5 ether; + vm.deal(address(swapper), rescueAmount); + address nativeEth = swapper.NATIVE_ETH(); + + vm.expectEmit(true, true, false, true, address(swapper)); + emit ISwapper.TokensRecovered(nativeEth, recipient, rescueAmount); + + vm.prank(admin); + swapper.recoverTokens(nativeEth, recipient, rescueAmount); + } + function test_recoverTokens_WhenNativeETHTransferFails_Reverts() public { uint256 rescueAmount = 5 ether;