in TapiocaOmnichainReceiver
when the user executes MSG_REMOTE_TRANSFER
If the srcChain amount request is bigger than the debited one, overwrite the amount to credit with the amount debited and send the difference back to the user.
function _internalRemoteTransferSendPacket(
address _srcChainSender,
LZSendParam memory _lzSendParam,
bytes memory _composeMsg
) internal returns (MessagingReceipt memory msgReceipt, OFTReceipt memory oftReceipt) {
...
// If the srcChain amount request is bigger than the debited one, overwrite the amount to credit with the amount debited and send the difference back to the user.
if (_lzSendParam.sendParam.amountLD > amountDebitedLD_) {
// Overwrite the amount to credit with the amount debited
@> _lzSendParam.sendParam.amountLD = amountDebitedLD_;
_lzSendParam.sendParam.minAmountLD = amountDebitedLD_;
// Send the difference back to the user
@> _transfer(address(this), _srcChainSender, _lzSendParam.sendParam.amountLD - amountDebitedLD_);
}
The above code, first modify _lzSendParam.sendParam.amountLD = amountDebitedLD_
Then call _transfer(address(this), _srcChainSender, _lzSendParam.sendParam.amountLD - amountDebitedLD_);
This way the difference is always `0
Correctly transfer() the difference first, and then modify _lzSendParam.sendParam.amountLD
Impact
the difference token be left in the contract
Recommended Mitigation
function _internalRemoteTransferSendPacket(
address _srcChainSender,
LZSendParam memory _lzSendParam,
bytes memory _composeMsg
) internal returns (MessagingReceipt memory msgReceipt, OFTReceipt memory oftReceipt) {
...
// If the srcChain amount request is bigger than the debited one, overwrite the amount to credit with the amount debited and send the difference back to the user.
if (_lzSendParam.sendParam.amountLD > amountDebitedLD_) {
+ _transfer(address(this), _srcChainSender, _lzSendParam.sendParam.amountLD - amountDebitedLD_);
// Overwrite the amount to credit with the amount debited
_lzSendParam.sendParam.amountLD = amountDebitedLD_;
_lzSendParam.sendParam.minAmountLD = amountDebitedLD_;
// Send the difference back to the user
- _transfer(address(this), _srcChainSender, _lzSendParam.sendParam.amountLD - amountDebitedLD_);
}
Lines of code
https://github.com/Tapioca-DAO/tapioca-periph/blob/032396f701be935b04a7e5cf3cb40a0136259dbc/contracts/tapiocaOmnichainEngine/TapiocaOmnichainReceiver.sol#L261
Vulnerability details
Vulnerability details
in
TapiocaOmnichainReceiver
when the user executes MSG_REMOTE_TRANSFER If the srcChain amount request is bigger than the debited one, overwrite the amount to credit with the amount debited and send the difference back to the user.lzCompose()
->_remoteTransferReceiver()
->_internalRemoteTransferSendPacket()
The above code, first modify
_lzSendParam.sendParam.amountLD = amountDebitedLD_
Then call_transfer(address(this), _srcChainSender, _lzSendParam.sendParam.amountLD - amountDebitedLD_);
This way the difference is always `0Correctly
transfer()
the difference first, and then modify_lzSendParam.sendParam.amountLD
Impact
the difference token be left in the contract
Recommended Mitigation
Assessed type
Context