Assessment reports>Wasabi>Threat Models>executeOption

Function: executeOption(uint256 _optionId)

Given the ID of any option NFT associated with this pool, this function executes it.

Inputs

  • _optionId

    • Control: Fully controlled by the user.

    • Constraints: Membership in optionIds and ownership by sender in optionNFT.

    • Impact: Determines which option is executed; validation confirms that the option indeed belongs to the pool and has not expired.

Branches and code coverage (including function calls)

Intended branches

  • Options that belong to the pool and are not expired can be executed.

  • Valid put options will transfer the strike price to the option holder and the NFT to the pool.

  • Valid call options will transfer the NFT to the option holder and the strike price to the pool.

  • Option NFTs are burned after execution.

Negative behavior

  • Existing options that do not belong to the pool cannot be executed.

  • Options that have expired cannot be executed.

  • Options that have already been executed cannot be executed.

  • Only the owner of the option can execute it.

  • Put options cannot be executed with invalid NFT IDs.

  • Call options cannot be executed with insufficient payment.

Function call analysis

  • validateOptionForExecution -> optionNFT.ownerOf

  • What is controllable? The input option ID.

    • If return value controllable, how is it used and how can it go wrong? The return value is used to determine whether the sender can execute the given option. It depends on the implementation of the optionNFT provided during construction.

    • What happens if it reverts, reenters, or does other unusual control flow? The caller (executeOption) uses the OpenZeppelin reentrancy guard. A revert would cause option execution to fail, which could be a centralization risk depending on how the option NFT is implemented.

  • validateOptionForExecution -> nft.ownerOf

  • What is controllable? The input token ID.

    • If return value controllable, how is it used and how can it go wrong? The value is used to check that the put option is really controlled by the holder. This ownership is implicitly checked during the transfer as well.

    • What happens if it reverts, reenters, or does other unusual control flow? A revert would cause option execution to fail.

  • clearOption -> nft.safeTransferFrom

  • What is controllable? The sender and the token ID.

    • If return value controllable, how is it used and how can it go wrong? The return value is not used.

    • What happens if it reverts, reenters, or does other unusual control flow? A revert would cause option execution to fail.

  • clearOption -> factory.burnOption

  • What is controllable? The option ID.

    • If return value controllable, how is it used and how can it go wrong? The return value is not used.

    • What happens if it reverts, reenters, or does other unusual control flow? A revert would cause option execution to fail. This could again be a centralization risk depending on how the option NFT is implemented.

  • validateAndWithdrawPayment -> token.allowance

  • What is controllable? The sender.

    • If return value controllable, how is it used and how can it go wrong? The return value is used to confirm that the sender has approved sufficient funds for the transfer.

    • What happens if it reverts, reenters, or does other unusual control flow? Execution fails.

  • validateAndWithdrawPayment -> factory.getFeeManager

  • What is controllable? N/A.

    • If return value controllable, how is it used and how can it go wrong? The return value decides which fee manager to use. This in turn decides the magnitude of fees as well as the recipient of fees. The controller of the fee manager can arbitrarily set fees, even for options that have already been created.

    • What happens if it reverts, reenters, or does other unusual control flow? Execution fails.

  • validateAndWithdrawPayment -> feeManager.getFeeData

  • What is controllable? The user controls nothing; the factory owner can set the fee manager.

    • If return value controllable, how is it used and how can it go wrong? The return value decides the magnitude of fees. This means that the controller of the fee manager can set fees.

    • What happens if it reverts, reenters, or does other unusual control flow? If this reverts, then execution fails. That means that the owner of the factory can block option execution.

  • validateAndWithdrawPayment -> token.transferFrom

  • What is controllable? N/A.

    • If return value controllable, how is it used and how can it go wrong? The return value is not used (but likely should be used!).

    • What happens if it reverts, reenters, or does other unusual control flow? The option execution fails.

  • validateAndWithdrawPayment -> feeReceiver.transfer

  • What is controllable? The owner controls the fee receiver.

    • If return value controllable, how is it used and how can it go wrong? The return value is not used (but likely should be used!).

    • What happens if it reverts, reenters, or does other unusual control flow? The option execution fails. This could be a centralization risk because the owner of the factory can change the fee receiver.

  • payAddress -> factory.getFeeManager

  • What is controllable? N/A.

    • If return value controllable, how is it used and how can it go wrong? The return value decides what fee manager to use. This can go wrong if the owner maliciously changes the manager.

    • What happens if it reverts, reenters, or does other unusual control flow? Execution fails.

  • payAddress -> feeManager.getFeeData

  • What is controllable? The owner controls the fee manager.

    • If return value controllable, how is it used and how can it go wrong? The return value decides the magnitude of fees. This means that the controller of the fee manager can set fees arbitrarily.

    • What happens if it reverts, reenters, or does other unusual control flow? Execution fails. Again, this might be a centralization risk.

  • payAddress -> token.transfer

  • What is controllable? N/A.

    • If return value controllable, how is it used and how can it go wrong? The return value is not used (but likely should be used).

    • What happens if it reverts, reenters, or does other unusual control flow? Execution fails.

  • payAddress -> token.transferFrom

  • What is controllable? N/A.

    • If return value controllable, how is it used and how can it go wrong? The return value is not used but should be checked.

    • What happens if it reverts, reenters, or does other unusual control flow? Execution fails.

  • payAddress -> _seller.transfer

  • What is controllable? N/A.

    • If return value controllable, how is it used and how can it go wrong? The return value is not used.

    • What happens if it reverts, reenters, or does other unusual control flow? Execution fails.

  • payAddress -> feeReceiver.transfer

    • What is controllable? The owner controls the fee receiver.

    • If return value controllable, how is it used and how can it go wrong? The return value is not used.

    • What happens if it reverts, reenters, or does other unusual control flow? Execution fails. This could again be a centralization risk.

Zellic © 2024Back to top ↑