TempleGold

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

Unchecked destination chain ID in `TempleTeleporter::teleport`

Summary

The function lacks validation for the destination chain ID (dstEid), potentially allowing users to send tokens to non-existent or unsupported chains. This could lead to permanent loss of user funds and reduction in the total token supply, as tokens are burned without being minted elsewhere.

Vulnerability Details

The teleport function fails to implement a crucial security check for the destination chain ID (dstEid):

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(); }
// No dstEid check
bytes memory _payload = abi.encodePacked(to.addressToBytes32(), amount);
temple.burnFrom(msg.sender, amount);
emit TempleTeleported(dstEid, msg.sender, to, amount);
receipt = _lzSend(dstEid, _payload, options, MessagingFee(msg.value, 0), payable(msg.sender));
}

The function accepts any uint32 value for dstEid without verifying its validity. This allows transactions to be initiated to any chain ID, regardless of whether it's supported or even exists within the LayerZero network.

Impact

The impact of this vulnerability are:

  1. Token Loss: When a user initiates a transfer to an invalid or unsupported destination chain:

    • Tokens are burned on the source chain.

    • The message fails to be delivered on the destination chain.

  2. Potential for Malicious Exploitation: Each failed transfer to an invalid chain ID results in tokens being burned without being minted elsewhere. Thus, bad actors could intentionally reduce the token supply by repeatedly sending tokens to invalid chains.

Tools Used

  • Manual review

Recommendations

Implement a destination chain whitelist, so the user is sure to never loose value unfortunatly:

mapping(uint32 => bool) public whitelistedChains;
function teleport(
uint32 dstEid,
address to,
uint256 amount,
bytes calldata options
) external payable override returns(MessagingReceipt memory receipt) {
require(whitelistedChains[dstEid], "Unsupported chain");
// ...
}
Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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