Skip to content

Latest commit

 

History

History
63 lines (52 loc) · 2.21 KB

069.md

File metadata and controls

63 lines (52 loc) · 2.21 KB

Fierce Coral Turkey

High

User's remaining fees are lost whenever withdrawing

Description

withdraw function is invoked whenever a user wants to withdraw his staking, this function will invoke _msgRemoveStakers.

Inside _msgRemoveStakers sendMessage is called, note that there is no option to specify the refundAddress.

    function _msgRemoveStakers(address[] memory remove) internal {
=>        MESSENGER.sendMessage(
            address(OTHER_STAKING),
            0,
            abi.encodeCall(IL2Staking.removeStakers, (remove)),
            gasLimitRemoveStakers
        );
    }

This triggers the sendMessage function in the L1CrossDomainMessenger contract:

    function sendMessage(
        address _to,
        uint256 _value,
        bytes memory _message,
        uint256 _gasLimit
    ) external payable override whenNotPaused {
        _sendMessage(_to, _value, _message, _gasLimit, _msgSender());
    }

The sendMessage function invokes _sendMessage, assigning the refundAddress as the msg.sender. The msg.sender will always be the L1CrossDomainMessenger contract itself.

   function _sendMessage(
        address _to,
        uint256 _value,
        bytes memory _message,
        uint256 _gasLimit,
        address _refundAddress
    ) internal nonReentrant {
//...Omitted code
        // Refund any remaining fee to the `_refundAddress`
        unchecked {
            uint256 _refund = msg.value - _fee - _value;
            if (_refund > 0) {
                (bool _success, ) = _refundAddress.call{value: _refund}("");
                require(_success, "Failed to refund the fee");
            }
        }
    }

If a refund is required, any leftover fee is returned to the _refundAddress, which will always be the L1CrossDomainMessenger contract itself.

This means that users that might have any remaining fee will not get it back. Instead, the contract will receive it.

Ultimately users lose a part of their funds.

Recommendation

Use the other sendMessage function which allows to specify your own _refundAddress