TempleGold

TempleDAO
Foundry
25,000 USDC
View results
Submission Details
Severity: low
Invalid

Not calculating cost when sending crosschain transaction with LZ could lead to user loses

Summary

Not calculating the cost when sending transaction crosschain wilth ZL could lead to user loses in the form of Temple tokens or overpaying transaction fees.

Vulnerability Details

The protocol uses LZ's OApp in TempleTeleporter to send cross chain messages that burns Temple tokens on the current chain and mints them on the destination chain. It uses OTF in templeGold to send TGLD crosschain.

In both cases tokens are burned on the current chain and minted on the destination chain. Both use _lzSend to send the message.

receipt = _lzSend(dstEid, _payload, options, MessagingFee(msg.value, 0), payable(msg.sender));

The first problem is than in both cases the user passes the fee amount. This could cause loses of Temple Tokens and TGLD if the fee amount is NOT enough to execute the transaction on the target chain (mint to tokens on the target chain), because tokens would be burned on the current chain.

) external payable override returns(MessagingReceipt memory receipt) {
if (amount == 0) { revert CommonEventsAndErrors.ExpectedNonZero(); }
if (to == address(0)) { revert CommonEventsAndErrors.InvalidAddress(); }
// Encodes the message before invoking _lzSend.
bytes memory _payload = abi.encodePacked(to.addressToBytes32(), amount);
// debit
=> temple.burnFrom(msg.sender, amount);
emit TempleTeleported(dstEid, msg.sender, to, amount);
=> receipt = _lzSend(dstEid, _payload, options, MessagingFee(msg.value, 0), payable(msg.sender));
}

Another issue here is that if a user sends more gas for the target chain transaction the excess would NOT be refunded. As stated in the LZ docs the refund address passed in _lzSend is only in case the transaction reverts.

"The refund address in case the send call reverts."

https://docs.layerzero.network/v2/developers/evm/oapp/overview#message-execution-options

Impact

Loss of user funds

Tools Used

Manual review, LZ Docs

Recommendations

For the TempleTeleporter check if msg.value is greater than quote amount

function teleport(
uint32 dstEid,
address to,
uint256 amount,
bytes calldata options
) external payable override returns(MessagingReceipt memory receipt) {
if (amount == 0) { revert CommonEventsAndErrors.ExpectedNonZero(); }
if (to == address(0)) { revert CommonEventsAndErrors.InvalidAddress(); }
// Encodes the message before invoking _lzSend.
bytes memory _payload = abi.encodePacked(to.addressToBytes32(), amount);
// debit
temple.burnFrom(msg.sender, amount);
emit TempleTeleported(dstEid, msg.sender, to, amount);
+ require(msg.value> quote(dstEid, _payload, options));
receipt = _lzSend(dstEid, _payload, options, MessagingFee(msg.value, 0), payable(msg.sender));
}
Updates

Lead Judging Commences

inallhonesty Lead Judge
about 1 year ago
inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

Fee validation issue in send

Support

FAQs

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