TOFT exerciseOption
fails due to not passing msg.value
properly
#1248
Labels
2 (Med Risk)
Assets not at direct risk, but function/availability of the protocol could be impacted or leak value
bug
Something isn't working
downgraded by judge
Judge downgraded the risk level of this issue
edited-by-warden
M-28
primary issue
Highest quality submission among a set of duplicates
selected for report
This submission will be included/highlighted in the audit report
sponsor confirmed
Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")
Lines of code
https://github.com/Tapioca-DAO/tapiocaz-audit/blob/master/contracts/tOFT/BaseTOFT.sol#L127-L146
https://github.com/Tapioca-DAO/tapiocaz-audit/blob/master/contracts/tOFT/BaseTOFT.sol#L536-L550
Vulnerability details
Impact
Packet type
PT_TAP_EXERCISE
always reverts due to not passing properly themsg.value
to the final destination contract.When first sent out it will revert and be stored inside
failedMessages
and the user is not able to retry the message.The user losses gas and
TOFT
tokens by using this function.Layer Zero message delivery
LayerZero is a messaging protocol that enables the delivery of payload from chainA to chainB.
The sender specifies and pays for the destination gas and has the option of airdropping native gas tokens into an address on the destination chain. This is done through relayer params.
The Relayer invokes the validateTransactionProofV2 function on the destination chain to deliver the payload.
The airdropped value is not part of the
msg.value
but is delivered asaddress(this).balance
on the destination contract. Also, thevalidateTransactionProofV2
function doesn't revert if airdropped tokens are not sent to the destination contract. It just emits an event, so the assumption always has to be that nothing is airdropped in the worst case.Proof of Concept
The flow of the issue is the following:
The only thing which is validated is does he have enough TOFT tokens, which are being burned and the packetType is
PT_TAP_EXERCISE
and he cannot airdrop any native tokens since adapterParamsV1 are enforced.tapSendData.withdrawOnAnotherChain
is true after exercising the option the tapOFT tokens are tried to be sent out to another chain. The problem is that thesendFrom
is missing{value: address(this.balance)
and the transaction reverts.sendFrom
function inside the BaseOFTV2 and the underlying _send function inOFTCoreV2
.We can see that the
_lzSend
relies on themsg.value
. However, in this casemsg.value
is always 0.failedMessages
mapping, the user can never retry it because it would always fail due to the same reason of not havingsendFrom{value: address(this).balance}
.Tools Used
Recommended Mitigation Steps
In my other issue, I have elaborated on the issues of airdropping users' tokens into TOFT's contract balance. It should be avoided. But the immediate fix for this issue is:
Add the option of airdropping tokens into the
exerciseOption
through adapterParamsV2 as it is done for many other packet types.Add the value to the
sendFrom
external call.Other occurrences
This exact same issue occurs while exercising option through BaseUSDO and when it is received on the other chain through the exercise function. This would also result in loss of USDO tokens and gas for the user.
initMultiHopBuy results in loss of airdropped tokens since no USDO is burned in this case.
This function offers the option of airdropping tokens through airdropAdapterParams but when it is received on the remote chain it invokes
multiHopBuyCollateral
on theSingularity
contract which expects msg.value.Thus, the whole thing would revert and be saved inside
failedMessages
mapping. And since the{value: address(this).balance}
is missing in the multiHop the user cannot retry the message.initMultiSell suffers from the same issue I just described above. The user would lose gas and airdropped tokens.
{value: address(this).balance}
is missing from multiHopSellCollateral function.Assessed type
Payable
The text was updated successfully, but these errors were encountered: