MorpheusAI

MorpheusAI
Foundry
22,500 USDC
View results
Submission Details
Severity: low
Valid

`sendMintMessage` should estimate fees to prevent failed transactions

Summary

sendMintMessage does not check the msg.value sent by the user that is used by layer zero endpoint to fullfill the gas fees, before calling the send function.

Vulnerability Details

When a user try to claim its token by calling the following function:

function claim(uint256 poolId_, address user_) external payable poolExists(poolId_) {
Pool storage pool = pools[poolId_];
PoolData storage poolData = poolsData[poolId_];
UserData storage userData = usersData[user_][poolId_];
require(block.timestamp > pool.payoutStart + pool.claimLockPeriod, "DS: pool claim is locked");
uint256 currentPoolRate_ = _getCurrentPoolRate(poolId_);
uint256 pendingRewards_ = _getCurrentUserReward(currentPoolRate_, userData);
require(pendingRewards_ > 0, "DS: nothing to claim");
// Update pool data
poolData.lastUpdate = uint128(block.timestamp);
poolData.rate = currentPoolRate_;
// Update user data
userData.rate = currentPoolRate_;
userData.pendingRewards = 0;
// Transfer rewards
L1Sender(l1Sender).sendMintMessage{value: msg.value}(user_, pendingRewards_, _msgSender());
emit UserClaimed(poolId_, user_, pendingRewards_);
}

The function perform an external call to L1Sender contract to pass a mint message using the following function:

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}(
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")
);
}

the msg.value sent by the caller is used by the layer zero endpoint to pay for the transaction fees. Therefore, if for any reason the user's msg.value is less than the required fees, the transaction will revert, leading to sender tokens burn.

Here is a quote from documentation of layer zero endpoint:

call send() with {value: msg.value} this is because send() requires a bit of native gas token so the relayer can complete the message delivery on the destination chain. If you don't set this value you might get this error when calling endpoint.send()

Layerzero Documentation

For more details about this vulnerability, please check the following Link

Impact

Users may lose their funds (execution gas fees) when trying to call this function if they send a value less than the required one for fees. as they will still pay for the execution of the transaction even if it revert.

Tools Used

Manual Auditing

Recommendations

Use the estimateFees() to check the msg.value sent by the user before performing the external call to layerzero .send().

Updates

Lead Judging Commences

inallhonesty Lead Judge over 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

LayerZero Integration: `sendMintMessage` doesn't verify the `msg.value` sent by the user facilitating failed transactions.

Support

FAQs

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