0

pretty new to coding and solidiy - I'm testing a covered-call option smart contract in hardhat - specifically a function to refund the call writer if the option is not executed but I keep getting a range error.

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 my test in JS on the refund function:

it('should refund the writer if option not executed', async () => {
    const expiryDate = await coveredCallContract.expiryDate();
    const unixSeconds = Math.round(Date.now() / 1000);
    const oneWeek = 8 * 24 * 60 * 60;
    assert.equal(expiryDate, await hre.network.provider.request({
      method: "evm_setNextBlockTimestamp",
      params: [unixSeconds + oneWeek]
    }));
    await hre.network.provider.request({ method: "evm_mine" });
    await coveredCallContract.refund({value: amount});
  });

Not quite sure how to make this work - any advice would be greatly appreciated. Thanks!

5
  • Do you know which line causes the problem? The only suspicious line seems to be unixSeconds + oneWeek, but I'm unsure if that line can cause that error. If you provide a complete minimal example we could check.
    – Ismael
    Dec 6, 2022 at 6:45
  • Hi! so it was intially line 66 and 70 as Date.Now() was a decimal and not in integer form. I used Math.round(Date.Now()/1000) to get around it however it's now throwing this error:
    – 0xJI
    Dec 7, 2022 at 10:00
  • Error: VM Exception while processing transaction: reverted with reason string 'Option has not expired yet'........at line 61 of the smartcontract code i.e. require(block.timestamp >= expiryDate, "Option has not expired yet");
    – 0xJI
    Dec 7, 2022 at 10:01
  • this is the test now: it('should refund the writer if option not executed', async () => { const expiryDate = await coveredCallContract.expiryDate(); const unixSeconds = Math.round(Date.now() / 1000); const oneWeek = 7 * 24 * 60 * 60; assert.isAtLeast(expiryDate, await hre.network.provider.request({ method: "evm_setNextBlockTimestamp", params: [unixSeconds + oneWeek] })); await hre.network.provider.request({ method: "evm_mine" }); await coveredCallContract.refund({value: amount}); }); })
    – 0xJI
    Dec 7, 2022 at 10:04
  • Please, edit the question when you want to add more details.
    – Ismael
    Dec 8, 2022 at 4:07

0

Your Answer

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

Browse other questions tagged or ask your own question.