Solidity - why does fallback() get called even though address.call{value:msg.value}("") does not have data?

Viewed 310

The following contract calls another contract using an interface method (code to change):

pragma solidity 0.8.7;

interface MyStorage {
    function setStorageValue(uint256) external;
}

contract StorageFactory {
  uint256 storageValue;

  constructor(uint256 _storageValue) {
    storage = _storageValue;
  }

  function initStorage(MyStorage store) public payable {
    store.setStorageValue(storageValue);
    address payable storeAddress = payable(address(store));
    storeAddress.call{value: msg.value}("");
  }
}

Following is the StorageContract (code cannot be changed):

pragma solidity 0.8.7;

contract Storage {

  int _storageValue;

  function setStorageValue(int storageValue) public {
    _storageValue = storageValue;
  }

  receive() external payable {
    require(_storageValue == -1 || address(this).balance <= uint(_storageValue), "Invalid storage value");
  }

  fallback() external {
    _storageValue = -1;
  }
}

I use a test to call initStorage of the first contract by passing a Storage object, where the test is meant to fail because the value is set to a large amount. But somehow, the fallback() function seems to get called, setting the value to -1. I can't figure out why. Any help is appreciated.

1 Answers

Due to the solidity doc:

The fallback function is executed on a call to the contract if none of the other functions match the given function signature, or if no data was supplied at all and there is no receive Ether function. The fallback function always receives data, but in order to also receive Ether it must be marked payable.

Your function getting called because there's no overloading for the function

function setStorageValue(uint256 storageValue) public

So change the storageValue from int to uint256 will help.

Related