@@ -3,14 +3,17 @@ pragma solidity 0.8.25;
33
44import { IWBNB } from "../Interfaces.sol " ;
55import { ISwapHelper } from "./ISwapHelper.sol " ;
6- import { IERC20Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol " ;
6+ import { SafeERC20Upgradeable, IERC20Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol " ;
7+ import { Ownable2Step } from "@openzeppelin/contracts/access/Ownable2Step.sol " ;
78
89/**
910 * @title WBNBSwapHelper
1011 * @notice Swap helper that wraps or unwraps native BNB into WBNB for PositionSwapper.
1112 * @dev Only supports native token (BNB) wrapping into WBNB and unwrapping WBNB into BNB. Meant to be used only by the PositionSwapper.
1213 */
13- contract WBNBSwapHelper is ISwapHelper {
14+ contract WBNBSwapHelper is Ownable2Step , ISwapHelper {
15+ using SafeERC20Upgradeable for IERC20Upgradeable ;
16+
1417 /// @notice Address of the authorized PositionSwapper contract
1518 address public immutable POSITION_SWAPPER;
1619
@@ -29,6 +32,21 @@ contract WBNBSwapHelper is ISwapHelper {
2932 */
3033 event SwappedToBNB (uint256 amount );
3134
35+ /**
36+ * @notice Emitted after the owner sweeps leftover ERC-20 tokens from the contract
37+ * @param token The token that was swept.
38+ * @param receiver The address that received the swept tokens.
39+ * @param amount The amount of tokens that were swept.
40+ */
41+ event SweepToken (address indexed token , address indexed receiver , uint256 amount );
42+
43+ /**
44+ * @notice Emitted after the owner sweeps leftover native tokens (e.g., BNB) from the contract
45+ * @param receiver The address that received the swept native tokens.
46+ * @param amount The amount of native tokens that were swept.
47+ */
48+ event SweepNative (address indexed receiver , uint256 amount );
49+
3250 /// @notice Error thrown when caller is not the authorized PositionSwapper
3351 error Unauthorized ();
3452
@@ -50,13 +68,39 @@ contract WBNBSwapHelper is ISwapHelper {
5068 _;
5169 }
5270
53- constructor (address _wbnb , address _swapper ) {
71+ constructor (address _wbnb , address _swapper ) Ownable2Step () {
5472 if (_wbnb == address (0 ) || _swapper == address (0 )) revert ZeroAddress ();
5573
5674 WBNB = IWBNB (_wbnb);
5775 POSITION_SWAPPER = _swapper;
5876 }
5977
78+ /**
79+ * @notice Allows the owner to sweep leftover ERC-20 tokens from the contract.
80+ * @param token The token to sweep.
81+ * @custom:event Emits SweepToken event.
82+ */
83+ function sweepToken (IERC20Upgradeable token ) external onlyOwner {
84+ uint256 balance = token.balanceOf (address (this ));
85+ if (balance > 0 ) {
86+ token.safeTransfer (owner (), balance);
87+ emit SweepToken (address (token), owner (), balance);
88+ }
89+ }
90+
91+ /**
92+ * @notice Allows the owner to sweep leftover native tokens (e.g., BNB) from the contract.
93+ * @custom:event Emits SweepToken event.
94+ */
95+ function sweepNative () external onlyOwner {
96+ uint256 balance = address (this ).balance;
97+ if (balance > 0 ) {
98+ (bool success , ) = payable (owner ()).call { value: balance }("" );
99+ if (! success) revert TransferFailed ();
100+ emit SweepNative (owner (), balance);
101+ }
102+ }
103+
60104 /// @notice Allows this contract to receive native BNB
61105 receive () external payable {}
62106
@@ -80,7 +124,7 @@ contract WBNBSwapHelper is ISwapHelper {
80124 WBNB.transfer (msg .sender , amount);
81125 emit SwappedToWBNB (amount);
82126 } else {
83- IERC20Upgradeable ( WBNB) .transferFrom (msg .sender , address (this ), amount);
127+ WBNB.transferFrom (msg .sender , address (this ), amount);
84128 WBNB.withdraw (amount);
85129
86130 (bool success , ) = payable (msg .sender ).call { value: amount }("" );
0 commit comments