Open sherlock-admin3 opened 4 months ago
I'd put it at low/informational
. Can only be true based on the statement
There is a valid case of zero paymentAmount in TapiocaOptionBroker's exerciseOption()
However there's a requirement in TapiocaOptionBroker
that forces at least 1 TAP to be exercised
https://github.com/Tapioca-DAO/tap-token/blob/main/contracts/options/TapiocaOptionBroker.sol#L395
chosenAmount
will not be zero, while _tapAmount == 0
. I.e. TapiocaOptionBroker
will not revert in that case.
The protocol team fixed this issue in PR/commit https://github.com/Tapioca-DAO/TapiocaZ/pull/185; https://github.com/Tapioca-DAO/Tapioca-bar/pull/370.
hyh
medium
TOFTOptionsReceiverModule's and UsdoOptionReceiverModule's exerciseOptionsReceiver can lose the option payment provided
Summary
There is a valid case of zero
paymentAmount
in TapiocaOptionBroker'sexerciseOption()
. When this happens,exerciseOptionsReceiver()
does not return any exercise funds remainder to the caller.Vulnerability Detail
Zero amount can happen due to rounding and is allowed in the logic. However, the reimbursement logic is conditioned on non-zero balance change (while it cannot be the case as the exercise reverts on all the errors, there is no possibility to just exit), so user will not be reimbursed in this case.
Impact
The
_options.paymentTokenAmount
provided by the caller can be lost for them ifexerciseOption()
ended up requesting no payment due to rounding. These user provided funds can be immediately stolen by any back-running attacker, as attacker's_options.paymentTokenAmount
can be less than what they need for exercise, i.e. currently anyone can freely use the funds from the contract balance to pay for their options' exercise as user provided funds aren't controlled to match with option strike payment ones.The probability of such rounding can be estimated as low, while fund freezing impact is high.
Likelihood: Low + Impact: High = Severity: Medium.
Code Snippet
TapiocaOptionBroker's
exerciseOption()
can request zeropaymentAmount
due to rounding in_getDiscountedPaymentAmount()
:https://github.com/Tapioca-DAO/tap-token/blob/main/contracts/options/TapiocaOptionBroker.sol#L592-L599
Zero
discountedPaymentAmount
is allowed:https://github.com/Tapioca-DAO/tap-token/blob/main/contracts/options/TapiocaOptionBroker.sol#L557-L574
In this case for
exerciseOptionsReceiver()
it isbBefore == bAfter
and nothing will be refunded from_options.paymentTokenAmount
:https://github.com/sherlock-audit/2024-02-tapioca/blob/main/TapiocaZ/contracts/tOFT/modules/TOFTOptionsReceiverModule.sol#L174-L180
I.e. given
exerciseOption()
was run successfully thebBefore == bAfter
state doesn't imply that no refund is needed.In the same time
_options.paymentTokenAmount
is user provided and can be arbitrary large.Tool used
Manual Review
Recommendation
Consider including zero amount case in TOFTOptionsReceiverModule's and UsdoOptionReceiverModule's
exerciseOptionsReceiver()
functions, e.g.:https://github.com/sherlock-audit/2024-02-tapioca/blob/main/TapiocaZ/contracts/tOFT/modules/TOFTOptionsReceiverModule.sol#L174-L180
https://github.com/sherlock-audit/2024-02-tapioca/blob/main/Tapioca-bar/contracts/usdo/modules/UsdoOptionReceiverModule.sol#L98-L104