0

I'm testing a covered-call option smart contract in hardhat - specifically the execute function where the call buyer executes the option at a specific trike price. However I keep getting a transaction revert with no reason and I'm not sure how to solve it.

Here is my smart contract:

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

contract CoveredCallContract {

    address public callWriter;
    address public callBuyer;
    uint public amount;
    uint public optionPrice;
    uint public strikePrice;
    uint public expiryDate;
    bool wasPurchased;

    constructor(uint _amount, uint _optionPrice, uint _strikePrice) {
        callWriter = msg.sender;
        amount = _amount;
        optionPrice = _optionPrice;
        strikePrice = _strikePrice;
        expiryDate = block.timestamp + 1 weeks;
    }

    // this function is how the callwriter deposits the collateral to cover the option
    function depositCollateral() public payable {
        require(msg.value >= amount, " Insufficient balance");
    }

    // this function allows the buyer to purchase the contract and pay the premium
    function purchaseOption() external payable {
        // ensure buyer hasn't already bought the option
        require(wasPurchased == false);
        // ensure buyer sends the correct amount
        require(msg.value == optionPrice, "Incorrect purchase price");
        // set the option buyer to the callbuyer
        callBuyer = msg.sender;
        // if the buyer buys the option, the price is transfered directly to the writer
        payable(callWriter).transfer(msg.value);
        // set the wasPurchased to true one the option has been purchased
        wasPurchased = true;

    }

    // the option will be executed if the price of ETH is above the strike price 
    function executeOption() external payable {
        // ensure the buyer has purchased the option
        require(wasPurchased == true);
        // make sure it's the buyer executing the contract
        require(msg.sender == callBuyer, "Unauthorized");
        // ensure the contract has been funded by the call writer
        require(address(this).balance == amount, "Funding error");
        // ensure the amount the buyer pays at execution is equal to the strikeprice
        require(msg.value == strikePrice, "Payment error");
        // make sure the contract has not expired
        require(block.timestamp < expiryDate, "Option has already expired");
        // if all the above hold transfer the amount to the buyer
        payable(callBuyer).transfer(address(this).balance);
    }

    // if the option is not executed the initial funds will be sent back to the call writer
    function refund() public payable {
        if(wasPurchased == false) {
            require(block.timestamp >= expiryDate, "Option has not expired yet");    
        }
        payable(callWriter).transfer((address(this).balance));
    }
}

Here is the test to test the execute function:

describe("CoveredCallContract", function () {

  let coveredCallContract;
  let callWriter;
  let callBuyer;
  const amount = ethers.utils.parseEther("1");
  const optionPrice = ethers.utils.parseEther("0.1");
  const strikePrice = ethers.utils.parseEther("1.5");

  this.beforeEach(async () => {
    [callWriter, callBuyer] = await ethers.getSigners();
    const CoveredCallContract = await ethers.getContractFactory("CoveredCallContract");
    coveredCallContract = await CoveredCallContract.deploy(amount, optionPrice, strikePrice);
    await coveredCallContract.deployed();
  });

...
it(**'should execute option'**, async () => {
    await coveredCallContract.connect(callBuyer).executeOption({value: strikePrice});
  });

I'm pretty new to solidity and coding generally so any advice would be greatly appreciated.

1 Answer 1

0

In the executeOption function, the first require misses a revert messages.

    // the option will be executed if the price of ETH is above the strike price 
    function executeOption() external payable {
        // ensure the buyer has purchased the option
        require(wasPurchased == true);

Here your contract likely fails (without a error message). Based on the contract logic, you should call purchaseOption first. You can use console.log to get more information about the contract state during execution.

1
  • as in use console.log in the smart contract or the JS test - just to clarify?
    – 0xJI
    Dec 8, 2022 at 17:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.