TempleGold

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

The message length in `TempleTeleporter.quote` is different from `TempleTeleporter.teleport`.

Summary

The message length in TempleTeleporter.quote is different from TempleTeleporter.teleport.

Vulnerability Details

I will call the former quote1 and the latter quote2.

  1. function quote(uint32 _dstEid, bytes memory _message, bytes memory _options)

  2. function quote(uint32 _dstEid, address _to, uint256 _amount, bytes memory _options)

quote2 uses abi.encodePacked.

function quote(
uint32 _dstEid,
address _to,
uint256 _amount,
bytes memory _options
) external view returns (MessagingFee memory fee) {
return _quote(_dstEid, abi.encodePacked(_to, _amount), _options, false);
}

https://github.com/Cyfrin/2024-07-templegold/blob/6873abd52ddee3502fdefd95b83304687feb515b/protocol/contracts/templegold/TempleTeleporter.sol#L93

However, the test below uses abi.encode for quote1, which makes the length of the message 16 byte longer.

MessagingFee memory fee = aTT.quote(bEid, abi.encode(userB, tokensToSend), options);
// ...
MessagingFee memory feeRaw = aTT.quote(bEid, userB, tokensToSend, options);
// @audit Both are 0
assertEq(feeRaw.lzTokenFee, fee.lzTokenFee);
// @audit The former is 210504 but the latter is 210516
assertApproxEqAbs(feeRaw.nativeFee, fee.nativeFee, 20);

https://github.com/Cyfrin/2024-07-templegold/blob/6873abd52ddee3502fdefd95b83304687feb515b/protocol/test/forge/templegold/TempleTeleporter.t.sol#L66-L87

teleport function makes the address to bytes32.

bytes memory _payload = abi.encodePacked(to.addressToBytes32(), amount);

https://github.com/Cyfrin/2024-07-templegold/blob/6873abd52ddee3502fdefd95b83304687feb515b/protocol/contracts/templegold/TempleTeleporter.sol#L52

OFTMsgCodec.addressToBytes32 zero-pads to the left, so abi.encode(userB, tokensToSend) is the right way to
calculate the fee.

function addressToBytes32(address _addr) internal pure returns (bytes32) {
return bytes32(uint256(uint160(_addr)));
}

https://github.com/LayerZero-Labs/LayerZero-v2/blob/7aebbd7c79b2dc818f7bb054aed2405ca076b9d6/packages/layerzero-v2/evm/oapp/contracts/oft/libs/OFTMsgCodec.sol#L71-L73

$ chisel
-> address x = address(0x123);
-> bytes32(uint256(uint160(x)))
Type: bytes32
ā”” Data: 0x0000000000000000000000000000000000000000000000000000000000000123

Impact

Calculated fee is less by 16 than the necessary amount in TempleTeleporter.teleport, so teleport will fail if
a user sends its fee calculated from quote2.

Tools Used

Manual review, foundry.

Recommendations

Fix as below.

- return _quote(_dstEid, abi.encodePacked(_to, _amount), _options, false);
+ return _quote(_dstEid, abi.encode(_to, _amount), _options, false);

https://github.com/Cyfrin/2024-07-templegold/blob/6873abd52ddee3502fdefd95b83304687feb515b/protocol/contracts/templegold/TempleTeleporter.sol#L93

Updates

Lead Judging Commences

inallhonesty Lead Judge 12 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Incorrect payload bytes in `quote()` they use `abi.encodePacked(_to, _amount)` instead of `abi.encodePacked(_to.addressToBytes32(), _amount)`

Support

FAQs

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