Search code examples
ethereumsolidity

Constructor of factory-like smart contract keeps reverting


I'm working with 2 contracts, one that manages users bets for a specific football match and another (factory style) that generates these individual contracts to be managed separately.

The Generator contract is this:

pragma solidity ^0.8.0;

contract Generator {
    address immutable public owner;
    string public matchGenerated;
    Management[] public bettingHistory;

    constructor(string memory _league, string memory _match) {
        owner = msg.sender;
        matchGenerated = string(abi.encodePacked(_league, "_", _match));
        Management newBetContract = new Management(address(this));
        bettingHistory.push(newBetContract);
    }
}

The Management contract receives data from the Generator to define the manager and the match values, as follows (short version):

contract Management {
    address payable immutable public manager;

    string public matchDispute;
    
    Generator generator;

    constructor(address _contract) {
        generator = Generator(_contract);
        manager = payable(generator.owner());
        matchDispute = generator.matchGenerated();
    }

Once I try to deploy the Generator contract in Remix it results in a reverting error. If I remove the instance of the generator in the Management contract and repeat the constructor arguments in both contracts it works, but I want to avoid the redundancy and get the values already stored in the Generator variables automatically.


Solution

  • To implement the above using interface, your solution will be like:

    Generator.sol file

    pragma solidity ^0.8.0;
    
    contract Generator {
        address immutable public owner;
        string public matchGenerated;
        Management[] public bettingHistory;
    
        constructor(string memory _league, string memory _match) {
            owner = msg.sender;
            matchGenerated = string(abi.encodePacked(_league, "_", _match));
            Management newBetContract = new Management(address(this));
            bettingHistory.push(newBetContract);
        }
    }
    

    IGenerator.sol file

     pragma solidity ^0.8.0;
     interface IGenerator{
         function owner() external view returns (address);
         function matchGenerated() external view returns (string)
     }
    

    Management.sol file

    pragma solidity ^0.8.0;
    
    import "IGenerator.sol";
    
    contract Management {
    address payable immutable public manager;
    
    string public matchDispute;
    
    constructor(address _contract) {
        manager = payable(IGenerator(_contract).owner());
        matchDispute = IGenerator(_contract).matchGenerated();
    }
    

    As you can see above, I have exposed all functions of Generator that management needed and separated the definitions of the two. Try that and see if it works and if not let's know what the new error messages are.