TempleGold

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

Wrong fee calculated in `TempleTeleporter#quote()` function.

Summary

In TempleTeleporter#quote() function, fee is wrongly calculated due to wrong message sent

Vulnerability Details

In quote()function, fee is calculated with message is abi.encodePacked(_to, _amount):

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); // <--
}

But when sending, message is abi.encodePacked(to.addressToBytes32(), 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);
receipt = _lzSend(dstEid, _payload, options, MessagingFee(msg.value, 0), payable(msg.sender)); // <---
}

It will lead to message will be difference when claculating and actual fee that necessary. For example:

function encode1(address _address, uint256 amount) public pure returns (bytes memory){
return abi.encodePacked(_address, amount);
}
function encode2(address _address, uint256 amount) public pure returns (bytes memory){
return abi.encodePacked(addressToBytes32(_address), amount);
}

With input is 0x95222290dd7278aa3ddd389cc1e1d165cc4bafe5and 123:

  • encode1()will return 0x95222290dd7278aa3ddd389cc1e1d165cc4bafe5000000000000000000000000000000000000000000000000000000000000007b

  • encode2()will return 0x00000000000000000000000095222290dd7278aa3ddd389cc1e1d165cc4bafe5000000000000000000000000000000000000000000000000000000000000007b

And in LayerZero, fee is calculated based on message size (link: https://github.com/LayerZero-Labs/LayerZero-v2/blob/7aebbd7c79b2dc818f7bb054aed2405ca076b9d6/packages/layerzero-v2/evm/messagelib/contracts/SendLibBase.sol#L147

function _quote(
address _sender,
uint32 _dstEid,
uint256 _msgSize,
bool _payInLzToken,
bytes calldata _options
) internal view returns (uint256, uint256) {
(bytes memory executorOptions, WorkerOptions[] memory validationOptions) = _splitOptions(_options);
// quote the verifier used in the library. for ULN, it is a list of DVNs
uint256 nativeFee = _quoteVerifier(_sender, _dstEid, validationOptions);
// quote executor
ExecutorConfig memory config = getExecutorConfig(_sender, _dstEid);
// assert msg size
_assertMessageSize(_msgSize, config.maxMessageSize);
nativeFee += ILayerZeroExecutor(config.executor).getFee(_dstEid, _sender, _msgSize, executorOptions); // <---
// quote treasury
(uint256 treasuryNativeFee, uint256 lzTokenFee) = _quoteTreasury(_sender, _dstEid, nativeFee, _payInLzToken);
nativeFee += treasuryNativeFee;
return (nativeFee, lzTokenFee);
}

Which will lead to wrong fee returned. As actual fee bigger than calculated fee, it will lead to msg revert if user rely on it.

Impact

User are not able to send message if thet are rely on fee returned in TempleTeleporter#quote() function

Tools Used

Manual review.

Recommendations

Update quote()function to:

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);
+ return _quote(_dstEid, abi.encodePacked(_to.addressToBytes32(), _amount), _options, false);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 11 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.