Closed code423n4 closed 2 years ago
The finding seems correct, the owner doesn't get the fee in 2 / 4 cases
Fees should only be paid on exercise as is explained in the comments; https://github.com/code-423n4/2022-06-putty/blob/main/contracts/src/PuttyV2.sol#L135
Agree with sponsor; the intended functionality is for the fee to be applied only upon exercising of the option as stated in the comment. It is correct for no fee to be collected for an expired call.
Lines of code
https://github.com/code-423n4/2022-06-putty/blob/3b6b844bc39e897bd0bbb69897f2deff12dc3893/contracts/src/PuttyV2.sol#L494-L506 https://github.com/code-423n4/2022-06-putty/blob/3b6b844bc39e897bd0bbb69897f2deff12dc3893/contracts/src/PuttyV2.sol#L508-L519 https://github.com/code-423n4/2022-06-putty/blob/3b6b844bc39e897bd0bbb69897f2deff12dc3893/contracts/src/PuttyV2.sol#L366-L371 https://github.com/code-423n4/2022-06-putty/blob/3b6b844bc39e897bd0bbb69897f2deff12dc3893/contracts/src/PuttyV2.sol#L435-L437
Vulnerability details
Owner\creators lose profit by not collecting the fees on half the expired cases (all calls).
The only place where owner receives fee is when withdrawing an exercised call or expired put: https://github.com/code-423n4/2022-06-putty/blob/3b6b844bc39e897bd0bbb69897f2deff12dc3893/contracts/src/PuttyV2.sol#L494-L506
But when a call expired, no fee has been collected on any part of the order life-cycle.
Proof of Concept
Will not write another test here to show this, but consider the following:
https://github.com/code-423n4/2022-06-putty/blob/3b6b844bc39e897bd0bbb69897f2deff12dc3893/contracts/src/PuttyV2.sol#L435-L437
The full strike amount is being transferred, and no fee is paid along the whole order life-cycle.
Tools Used
forge, editor, code review
Recommended Mitigation Steps
Decide who should pay the fees in this case. Providing solution for both cases:
A. you can either make the short pay the fee, he should pay the feeAmount when his asset returns to him when withdraw on expired.
https://github.com/code-423n4/2022-06-putty/blob/3b6b844bc39e897bd0bbb69897f2deff12dc3893/contracts/src/PuttyV2.sol#L508-L519 Change block mentioned above to:
B. On the other hand you can make the long pay the fee (when he already pays the premium),
https://github.com/code-423n4/2022-06-putty/blob/3b6b844bc39e897bd0bbb69897f2deff12dc3893/contracts/src/PuttyV2.sol#L366-L371 Change code block mentioned above to:
And if call exercised, long must only pay to complete the strike (strike-feePayed)
https://github.com/code-423n4/2022-06-putty/blob/3b6b844bc39e897bd0bbb69897f2deff12dc3893/contracts/src/PuttyV2.sol#L435-L437 Change code block mentioned above to:
and if expired - no worry as fee already payed.