Ethernaut update to Solidity 0.5 - Function overload clash during conversion to external types for arguments

Hi
I am updating Ethernaut to Solidity 0.5 and I am getting this error when try to compile some levels factories (mostly the problem is when level use address payable:

/Users/paulina/projects/ethernaut/contracts/levels/base/Level.sol:7:3: TypeError: Function overload clash during conversion to external types for arguments.
  function validateInstance(address _instance, address _player) public returns (bool);
  ^----------------------------------------------------------------------------------^

I am looking the best way to solve this problem, any ideas?
Below I am adding sample contracts to reproduce the issue:

Fallback.sol

pragma solidity ^0.5.0;

import 'openzeppelin-solidity/contracts/math/SafeMath.sol';

contract Fallback {

  using SafeMath for uint256;
  mapping(address => uint) public contributions;
  address payable public owner;

  constructor() public {
    owner = msg.sender;
    contributions[msg.sender] = 1000 * (1 ether);
  }

  modifier onlyOwner {
        require(
            msg.sender == owner,
            "caller is not the owner"
        );
        _;
    }

  function contribute() public payable {
    require(msg.value < 0.001 ether);
    contributions[msg.sender] += msg.value;
    if(contributions[msg.sender] > contributions[owner]) {
      owner = msg.sender;
    }
  }

  function getContribution() public view returns (uint) {
    return contributions[msg.sender];
  }

  function withdraw() public onlyOwner {
    owner.transfer(address(this).balance);
  }

  function() payable external {
    require(msg.value > 0 && contributions[msg.sender] > 0);
    owner = msg.sender;
  }
}

FallbackFactory.sol:

pragma solidity ^0.5.0;

import './base/Level.sol';
import './Fallback.sol';

contract FallbackFactory is Level {

  function createInstance(address _player) public payable returns (address) {
_player;
Fallback instance = new Fallback();
return address(instance);
  }

  function validateInstance(address payable _instance, address _player) public returns (bool) {
Fallback instance = Fallback(_instance);
return instance.owner() == _player && address(instance).balance == 0;
  }
}

Level.sol

pragma solidity ^0.5.0;

import 'openzeppelin-solidity/contracts/ownership/Ownable.sol';

contract Level is Ownable {
  function createInstance(address _player) public payable returns (address);
  function validateInstance(address _instance, address _player) public returns (bool);
}
2 Likes

Hi @paulinablaszk

I thought it might be related to the following issue (compiler issue prior to 0.5.2.)

What version of solc are you using?
I have tried with 0.5.8 and get the same error as you.

1 Like

Hi! Yes, I also read that, but it didn’t help me to find solution. I have used solc 0.5.0 and also higher versions

1 Like

Hi @paulinablaszk

The issue appears to be the mismatch in the function definitions between validateInstance in Level and in FallbackFactory. There isn’t a compiler error if both take either _instance or payable _instance address parameters.

contract Level is Ownable {
  function validateInstance(address _instance, address _player) public returns (bool);
}
contract FallbackFactory is Level {
  function validateInstance(address payable _instance, address _player) public returns (bool) {
  }
}

@abcoathup thank you :slight_smile: I’m considering how to solve this issue because Level.sol is an interface for contracts that need to has address payable _instance or address payable. Should we create other Level interfaces for both situations?

1 Like

Is there any harm in having all the levels be address payable _instance?

https://solidity.readthedocs.io/en/latest/050-breaking-changes.html?highlight=payable
An address payable can be directly converted to an address , but the other way around is not allowed.

I think that to use address payable _instance in all levels we should add function() payable external to other levels but I am not sure if it might be problematic?

1 Like

I assume you only need to change the validateInstance function in all levels and Level to take an address payable _instance parameter so that they all match.

I didn’t think other changes are required.

2 Likes

It worked, thank you! Finally, all contracts have compiled successfully :tada: :tada: :tada:

So there are “only” tests left to do :smiley:

2 Likes