@@ -3,14 +3,19 @@ pragma solidity 0.8.24;
33
44import {IAny2EVMMessageReceiver} from "../../../interfaces/IAny2EVMMessageReceiver.sol " ;
55import {Client} from "../../../libraries/Client.sol " ;
6-
76import {IERC165 } from "../../../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/IERC165.sol " ;
7+ import {IERC20 } from "../../../../vendor/openzeppelin-solidity/v5.0.2/contracts/token/ERC20/IERC20.sol " ;
88
99contract MaybeRevertMessageReceiver is IAny2EVMMessageReceiver , IERC165 {
1010 error ReceiveRevert ();
1111 error CustomError (bytes err );
12+ error Unauthorized ();
13+ error InsufficientBalance (uint256 available , uint256 required );
14+ error TransferFailed ();
1215
1316 event ValueReceived (uint256 amount );
17+ event FundsWithdrawn (address indexed owner , uint256 amount );
18+ event TokensWithdrawn (address indexed token , address indexed owner , uint256 amount );
1419 event MessageReceived (
1520 bytes32 messageId ,
1621 uint64 sourceChainSelector ,
@@ -19,35 +24,34 @@ contract MaybeRevertMessageReceiver is IAny2EVMMessageReceiver, IERC165 {
1924 Client.EVMTokenAmount[] destTokenAmounts
2025 );
2126
22- address private s_manager;
27+ address private immutable s_manager;
2328 bool public s_toRevert;
2429 bytes private s_err;
2530
26- constructor (
27- bool toRevert
28- ) {
31+ constructor (bool toRevert ) {
2932 s_manager = msg .sender ;
3033 s_toRevert = toRevert;
3134 }
3235
33- function setRevert (
34- bool toRevert
35- ) external {
36+ modifier onlyManager () {
37+ if (msg .sender != s_manager) {
38+ revert Unauthorized ();
39+ }
40+ _;
41+ }
42+
43+ function setRevert (bool toRevert ) external onlyManager {
3644 s_toRevert = toRevert;
3745 }
3846
39- function setErr (
40- bytes memory err
41- ) external {
47+ function setErr (bytes memory err ) external onlyManager {
4248 s_err = err;
4349 }
4450
4551 /// @notice IERC165 supports an interfaceId
4652 /// @param interfaceId The interfaceId to check
4753 /// @return true if the interfaceId is supported
48- function supportsInterface (
49- bytes4 interfaceId
50- ) public pure override returns (bool ) {
54+ function supportsInterface (bytes4 interfaceId ) public pure override returns (bool ) {
5155 return interfaceId == type (IAny2EVMMessageReceiver).interfaceId || interfaceId == type (IERC165 ).interfaceId;
5256 }
5357
@@ -72,4 +76,37 @@ contract MaybeRevertMessageReceiver is IAny2EVMMessageReceiver, IERC165 {
7276
7377 emit ValueReceived (msg .value );
7478 }
79+
80+ /// @notice Allows the manager (deployer) to withdraw all Ether from the contract
81+ function withdrawFunds () external onlyManager {
82+ uint256 balance = address (this ).balance;
83+ if (balance == 0 ) {
84+ revert InsufficientBalance (0 , 1 );
85+ }
86+
87+ (bool success , ) = s_manager.call {value: balance}("" );
88+ if (! success) {
89+ revert TransferFailed ();
90+ }
91+
92+ emit FundsWithdrawn (s_manager, balance);
93+ }
94+
95+ /// @notice Allows the manager to withdraw ERC-20 tokens from the contract
96+ /// @param token The address of the ERC-20 token contract
97+ /// @param amount The amount of tokens to withdraw
98+ function withdrawTokens (address token , uint256 amount ) external onlyManager {
99+ IERC20 erc20 = IERC20 (token);
100+ uint256 balance = erc20.balanceOf (address (this ));
101+ if (balance < amount) {
102+ revert InsufficientBalance (balance, amount);
103+ }
104+
105+ bool success = erc20.transfer (s_manager, amount);
106+ if (! success) {
107+ revert TransferFailed ();
108+ }
109+
110+ emit TokensWithdrawn (token, s_manager, amount);
111+ }
75112}
0 commit comments