Closed c4-bot-5 closed 7 months ago
cryptotechmaker (sponsor) confirmed
dmvt marked the issue as primary issue
0xRektora (sponsor) disputed
I agree that the naming should be different and documentation more explicit.
Used in a sandboxed environment, you'd instantly know that there's a problem. However the encoding/decoding aren't done straightforward. Using a fuzzer might trigger a false positive. I'm not sure how this was setup but there should be a condition for the parameter passing.
The _tapComposedMsg
in encodeToeComposeMsg
should always be empty if _msgIndex
is 0, this is because it's the first message.
If we take this into account, decodeToeComposeMsg
will receive the right data structure, and index > 0 will not break too because we'd be passing a slice of the data to the next decodeToeComposeMsg
call
nextMsg_ = BytesLib.slice(_msg, tapComposeOffset_, _msg.length - (tapComposeOffset_));
Which always make _tapComposedMsg
of encodeToeComposeMsg
empty, and match the decodeToeComposeMsg
structure.
encodeToeComposeMsg
passes previous messages to concatenate every compose message. Better wording could've been used between function/variable names.
dmvt marked the issue as unsatisfactory: Invalid
Lines of code
https://github.com/Tapioca-DAO/tapioca-periph/blob/2ddbcb1cde03b548e13421b2dba66435d2ac8eb5/contracts/tapiocaOmnichainEngine/TapiocaOmnichainEngineCodec.sol#L85-L92 https://github.com/Tapioca-DAO/tapioca-periph/blob/2ddbcb1cde03b548e13421b2dba66435d2ac8eb5/contracts/tapiocaOmnichainEngine/TapiocaOmnichainEngineCodec.sol#L96-L109
Vulnerability details
The function
encodeToeComposeMsg
is written as followshttps://github.com/Tapioca-DAO/tapioca-periph/blob/2ddbcb1cde03b548e13421b2dba66435d2ac8eb5/contracts/tapiocaOmnichainEngine/TapiocaOmnichainEngineCodec.sol#L85-L92
Decoding is written as follows:
https://github.com/Tapioca-DAO/tapioca-periph/blob/2ddbcb1cde03b548e13421b2dba66435d2ac8eb5/contracts/tapiocaOmnichainEngine/TapiocaOmnichainEngineCodec.sol#L96-L109
Which means that the encoding is being done incorrectly
_msgType should be the first parameter
We can verify this (this is how I found it) via fuzz testing a random inputs and verifying that the decoded data matches
POC
The POC uses a custom foundry repo, I simply copied the files and fixed imports
The library
TapiocaOmnichainEngineCodec
is changed to always use internal functionsThe source code is here: https://gist.github.com/GalloDaSballo/418d7c394de8bba4961332ce305d52aa
And the full repo is available here (invite only): https://github.com/GalloDaSballo/omnichain-lib-fuzz
The test is as follows:
Which simply encodes random values, and then decodes them, to verify that the decoding function returns the original values
Due to the incorrect order demonstrated above, the test will fail
Medusa logs will look like these:
Indicating that the
_msgType
is being decoded incorrectlyThis will make it so that messages built with
encodeToeComposeMsg
will always fail at decoding as they will result in gibberish bytes being decodedMitigation
Change the encoding function to:
Please note that I am unsure if
msg
and_tapComposedMsg
are supposed to be in this or the reversed order, as the documentation is ambigous!And consider adding extensive fuzz and invariant testing for these libraries as they may have more edge cases that were missed
Assessed type
en/de-code