The DepotFacet contract interacts with the Pipeline contract and attempts to refund any remaining Ether to the caller at the end of the function execution using the LibEth.refundEth() function.
However, if the callee does not have a payable fallback function, the refund will fail, causing the entire transaction to revert. This can lead to unexpected gas losses for users.
The vulnerability arises from the following code in the LibEth.refundEth() function:
Any transaction that involves a call to the LibEth.refundEth() function will revert if the caller’s contract does not have a payable fallback function. This means all state changes made before the refund attempt will be rolled back, which in turn, users will lose the gas fees spent on the transaction due to the reversion caused by the failed Ether transfer. They will have to call this function again and lose more funds on gas.
Consider the following scenario:
Alice creates a non-payable contract that interacts with the DepotFacet contract.
Alice’s contract makes a call to the advancedPipe function in the DepotFacet contract.
The LibEth.refundEth() function attempts to refund remaining Ether to Alice’s contract.
Since Alice’s contract does not have a payable fallback function, the refund fails, causing the entire transaction to revert and Alice loses the gas fees spent on the transaction.
Manual Review
Introduce a Secondary Refund Address with Conditional Statements.
Modify the LibEth.refundEth()
function to include a secondary refund address as an optional parameter. This allows specifying an alternative address for refunds if the original caller cannot accept Ether.
Also, update DepotFacet
functions to handle optional secondary refund address.
Pass an optional secondary address to the LibEth.refundEth function that can be used if the primary refund to msg.sender fails.
By implementing these changes, the contract ensures that if the primary caller cannot receive Ether, the refund will be sent to an alternative address specified within the function parameters that is able to receive the remaining balance afterwards.
Updated DepotFacet
functions:
Updated LibEth.refundEth()
function:
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.