Use of Solidity's transfer()
function might render ETH impossible to withdraw
#134
Labels
bug
Something isn't working
duplicate
This issue or pull request already exists
QA (Quality Assurance)
Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax
Lines of code
https://github.com/code-423n4/2022-07-axelar/blob/9c4c44b94cddbd48b9baae30051a4e13cbe39539/contracts/deposit-service/ReceiverImplementation.sol#L23
https://github.com/code-423n4/2022-07-axelar/blob/9c4c44b94cddbd48b9baae30051a4e13cbe39539/contracts/deposit-service/ReceiverImplementation.sol#L51
https://github.com/code-423n4/2022-07-axelar/blob/9c4c44b94cddbd48b9baae30051a4e13cbe39539/contracts/deposit-service/ReceiverImplementation.sol#L71
https://github.com/code-423n4/2022-07-axelar/blob/9c4c44b94cddbd48b9baae30051a4e13cbe39539/contracts/deposit-service/ReceiverImplementation.sol#L86
https://github.com/code-423n4/2022-07-axelar/blob/9c4c44b94cddbd48b9baae30051a4e13cbe39539/contracts/gas-service/AxelarGasService.sol#L128
https://github.com/code-423n4/2022-07-axelar/blob/9c4c44b94cddbd48b9baae30051a4e13cbe39539/contracts/gas-service/AxelarGasService.sol#L144
Vulnerability details
Impact
Using Solidity's
transfer
function has some notable shortcomings when the caller is a smart contract, which can render registers viaETH
impossible. Specifically, the transfer will inevitably fail when:The
sendValue
function available in OpenZeppelin Contract’s Address library can be used to transfer the withdrawn Ether without being limited to 2300 gas units. Risks of reentrancy stemming from the use of this function can be mitigated by tightly following the "Check-effects-interactions" pattern and using OpenZeppelin Contract’s ReentrancyGuard contract. For further reference on why using Solidity’s transfer is no longer recommended, refer to these articles:Proof of Concept
deposit-service/ReceiverImplementation.sol:
L23 -
refundAddress.transfer(address(this).balance);
L51 -
refundAddress.transfer(address(this).balance);
L71 -
refundAddress.transfer(address(this).balance);
L86 -
recipient.transfer(amount);
gas-service/AxelarGasService.sol:
L128 -
receiver.transfer(amount);
L144 -
receiver.transfer(amount);
Tools Used
Manual review
Recommended mitigation steps
Use Solidity's low-level
call()
function or thesendValue
function available in OpenZeppelin Contract’s Address library to send Ether.The text was updated successfully, but these errors were encountered: