Closed code423n4 closed 2 years ago
For a short order, it's preferred for the taker to fulfill the order later than sooner, as later means the option will be valid for a longer time.
This is an incorrect assumption. It is preferred for the taker to fulfil the order whenever they believe the IV is priced correctly. This is because there are other participants who are also watching the same order book and will lift the order as soon as it's priced correctly.
However, the proof of concept and other parts of the reported issue align with "Orders with low durations can be easily DOS’d and prevent possibility of exercise".
Duplicate: Orders with low durations can be easily DOS’d and prevent possibility of exercise: https://github.com/code-423n4/2022-06-putty-findings/issues/265
Lines of code
https://github.com/code-423n4/2022-06-putty/blob/3b6b844bc39e897bd0bbb69897f2deff12dc3893/contracts/src/PuttyV2.sol#L315-L316
Vulnerability details
Unlike other American Option systems, which the expiration time is set by the maker, in PuttyV2, the maker will set a
duration
and an order expiration time (order.expiration
).This means that the final expiration time of the option will be decided by the taker.
For a short order, it's preferred for the taker to fulfill the order later than sooner, as later means the option will be valid for a longer time.
Furthermore, the current implementation allows the maker to set the duration to an arbitrary value, which can be very short or even
0
, renders the option useless as it will expired immediately:https://github.com/code-423n4/2022-06-putty/blob/3b6b844bc39e897bd0bbb69897f2deff12dc3893/contracts/src/PuttyV2.sol#L315-L316
The option's expiration time (
positionExpirations
) is base onblock.timestamp
andorder.duration
, whenorder.duration == 0
, the option's expiration time will beblock.timestamp
.Even if
exercise()
is called within the same block will revert with"Position has expired"
.https://github.com/code-423n4/2022-06-putty/blob/3b6b844bc39e897bd0bbb69897f2deff12dc3893/contracts/src/PuttyV2.sol#L389-L401
Proof of Concept
Given:
Punk#100
market price = 100 ETHPunk#100
Punk#100
transferred from Alice to contractBob tried to
exercise()
immediately, the transaction reverted with error: "Position has expired"Alice called
withdraw()
and retrieved thePunk#100
Recommended Mitigation Steps
order.duration
and useorder.expiration
for theexpiration
time of the option;order.deadline
for the order's expiration time, and the maker order can only be filled before that time;order.deadline < order.expiration
.order.duration > MIN_DURATION
.The
MIN_DURATION
should be meaningful for a regular end-user to exercise the option even when the network is congested, eg, 12 hours.