The important value here is the marketMsg_ parameter. The removeAssetReceiver function forwards the call to exitPositionAndRemoveCollateral function via magnetar contract.
The exitPositionAndRemoveCollateral function removes asset from Singularity market if the data.removeAndRepayData.removeAssetFromSGL is true. The amount is taken from data.removeAndRepayData.removeAmount. Then, if data.removeAndRepayData.assetWithdrawData.withdraw is true, the _withdrawToChain is called.
In _withdrawToChain, if the data.lzSendParams.sendParam.dstEid is zero, the _withdrawHere is called that transfers asset to data.lzSendParams.sendParam.to.
Summing up, the following marketMsg_ struct can be used to steal userB's assets from singularity market by userA.
Here is the modified version of the test_market_remove_asset test that achieves the same result, but with unauthorized call to executeModule function. The userA is the attacker, and userB is the victim.
The executeModule function should inspect and validate the _data parameter to make sure that the caller is the same address as the user who executes the operations.
ComposableSecurity
high
Unprotected
executeModule
function allows to steal the tokensSummary
The
executeModule
function allows anyone to execute any module with any params. That allows attacker to execute operations on behalf of other users.Vulnerability Detail
Here is the
executeModule
function:https://github.com/sherlock-audit/2024-02-tapioca/blob/main/Tapioca-bar/contracts/usdo/Usdo.sol#L152-L159
All its parameters are controlled by the caller and anyone can be the caller. Anyone can execute any module on behalf of any user.
Let's try to steal someone's tokens using
UsdoMarketReceiver
module andremoveAssetReceiver
function (below is the PoC).Here is the code that will call the
executeModule
function:The important value here is the
marketMsg_
parameter. TheremoveAssetReceiver
function forwards the call toexitPositionAndRemoveCollateral
function via magnetar contract.https://github.com/sherlock-audit/2024-02-tapioca/blob/main/Tapioca-bar/gitmodule/tapioca-periph/contracts/Magnetar/modules/MagnetarOptionModule.sol#L150-L165
The
exitPositionAndRemoveCollateral
function removes asset from Singularity market if thedata.removeAndRepayData.removeAssetFromSGL
istrue
. The amount is taken fromdata.removeAndRepayData.removeAmount
. Then, ifdata.removeAndRepayData.assetWithdrawData.withdraw
istrue
, the_withdrawToChain
is called.https://github.com/sherlock-audit/2024-02-tapioca/blob/main/Tapioca-bar/gitmodule/tapioca-periph/contracts/Magnetar/modules/MagnetarOptionModule.sol#L51-L61
In
_withdrawToChain
, if thedata.lzSendParams.sendParam.dstEid
is zero, the_withdrawHere
is called that transfers asset todata.lzSendParams.sendParam.to
.Summing up, the following
marketMsg_
struct can be used to stealuserB
's assets from singularity market byuserA
.Here is the modified version of the
test_market_remove_asset
test that achieves the same result, but with unauthorized call toexecuteModule
function. TheuserA
is the attacker, anduserB
is the victim.Note: The
burst
function was modified in the MagnetarMock contract and add call to_checkSender
function to reproduce the real situation.https://github.com/sherlock-audit/2024-02-tapioca/blob/main/Tapioca-bar/test/MagnetarMock.sol#L62-L67
That is also why the
bUsdo
has been whitelisted in the test.Impact
HIGH - Anyone can steal others' tokens from their markets.
Code Snippet
https://github.com/sherlock-audit/2024-02-tapioca/blob/main/Tapioca-bar/contracts/usdo/Usdo.sol#L152-L159
https://github.com/sherlock-audit/2024-02-tapioca/blob/main/TapiocaZ/contracts/tOFT/mTOFT.sol#L198-L205
https://github.com/sherlock-audit/2024-02-tapioca/blob/main/TapiocaZ/contracts/tOFT/TOFT.sol#L146-L153
Tool used
Manual Review
Recommendation
The
executeModule
function should inspect and validate the_data
parameter to make sure that the caller is the same address as the user who executes the operations.