MorpheusAI

MorpheusAI
Foundry
22,500 USDC
View results
Submission Details
Severity: medium
Invalid

Use call instead of send in `L1Sender::sendMintMessage`

Summary

When transferring Ether in Solidity and needing complex code execution, please skip the limited 2300 gas .send() and .transfer(). And if the recipient is a contract, the transfer might fail unexpectedly. Instead, please use .call{value: _amount}("") for full gas and advanced functionality.

Vulnerability Details

In Solidity, when it comes to transferring Ether, developers often resort to using .send() and .transfer() methods. However, these methods come with a limitation: they only provide a stipend of 2300 gas. This limitation restricts the execution of any significant code within the recipient contract, allowing only simple event emissions. Consequently, if the recipient is a contract, the transfer might fail unexpectedly.

To address this limitation, Solidity introduced the .call{value: _amount}("") method. Unlike .send() and .transfer(), .call forwards all available gas and can execute more complex functionality within the recipient contract. Furthermore, .call does not revert on failure but instead returns a boolean value, indicating the success or failure of the transfer. Due to these advantages, it is generally considered a safer choice to use .call when transferring Ether to a payable address, while ensuring necessary safety checks are implemented to handle potential errors.

There are one instance(s) of this issue:
L1Sender::sendMintMessage

function sendMintMessage(address user_, uint256 amount_, address refundTo_) external payable onlyDistribution {
RewardTokenConfig storage config = rewardTokenConfig;
bytes memory receiverAndSenderAddresses_ = abi.encodePacked(config.receiver, address(this));
bytes memory payload_ = abi.encode(user_, amount_);
- ILayerZeroEndpoint(config.gateway).send{value: msg.value}(
+ (bool success, ) = ILayerZeroEndpoint(config.gateway).send{value: msg.value}(
config.receiverChainId, // communicator LayerZero chainId
receiverAndSenderAddresses_, // send to this address to the communicator
payload_, // bytes payload
payable(refundTo_), // refund address
address(0x0), // future parameter
bytes("") // adapterParams (see "Advanced Features")
);
+ if (!success) revert TransferFailed();
}

Impact

The traditional methods of transferring Ether in Solidity, namely .send() and .transfer(), due to their restricted gas stipend of 2300 have limitation in the execution of significant code within the recipient contract, potentially leading to unexpected failures, especially if the recipient is a contract.

Tools Used

Manual Review

Recommendations

Solidity provides a solution to this limitation through the .call{value: _amount}("") method. By forwarding all available gas, .call allows for the execution of more complex functionality within the recipient contract. Additionally, .call does not revert on failure but returns a boolean value, improving error handling.

Updates

Lead Judging Commences

inallhonesty Lead Judge
over 1 year ago
inallhonesty Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
eta Submitter
over 1 year ago
inallhonesty Lead Judge
over 1 year ago
inallhonesty Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.