contract RenVMSignatureVerifierV1 is
    Initializable,
    ContextUpgradeable,
    OwnableUpgradeable,
    RenVMSignatureVerifierStateV1,
    IERC1271,
    IRenVMSignatureVerifier
{
    string public constant NAME = "RenVMSignatureVerifier";

    event LogMintAuthorityUpdated(address indexed mintAuthority);

    // bytes4(keccak256("isValidSignature(bytes32,bytes)")
    bytes4 public constant CORRECT_SIGNATURE_RETURN_VALUE = 0x1626ba7e; // CORRECT_SIGNATURE_RETURN_VALUE_
    bytes4 public constant INCORRECT_SIGNATURE_RETURN_VALUE = 0x000000;

    function __RenVMSignatureVerifier_init(
        string calldata chain_,
        address mintAuthority_,
        address contractOwner
    ) external initializer {
        __Context_init();
        __Ownable_init();
        _chain = chain_;
        updateMintAuthority(mintAuthority_);

        if (owner() != contractOwner) {
            transferOwnership(contractOwner);
        }
    }

    function getChain() public view override returns (string memory) {
        return _chain;
    }

    function getMintAuthority() public view override returns (address) {
        return _mintAuthority;
    }

    // GOVERNANCE //////////////////////////////////////////////////////////////

    modifier onlyOwnerOrMintAuthority() {
        require(_msgSender() == owner() || _msgSender() == getMintAuthority(), "SignatureVerifier: not authorized");
        _;
    }

    /// @notice Allow the owner or mint authority to update the mint authority.
    ///
    /// @param nextMintAuthority The new mint authority address.
    function updateMintAuthority(address nextMintAuthority) public onlyOwnerOrMintAuthority {
        require(nextMintAuthority != address(0), "SignatureVerifier: mintAuthority cannot be set to address zero");
        _mintAuthority = nextMintAuthority;
        emit LogMintAuthorityUpdated(_mintAuthority);
    }

    // PUBLIC //////////////////////////////////////////////////////////////////

    /// @notice verifySignature checks the the provided signature matches the
    /// provided parameters. Returns a 4-byte value as defined by ERC1271.
    function isValidSignature(bytes32 sigHash, bytes calldata signature) external view override returns (bytes4) {
        address mintAuthority_ = getMintAuthority();
        require(mintAuthority_ != address(0x0), "SignatureVerifier: mintAuthority not initialized");
        if (mintAuthority_ == ECDSA.recover(sigHash, signature)) {
            return CORRECT_SIGNATURE_RETURN_VALUE;
        } else {
            return INCORRECT_SIGNATURE_RETURN_VALUE;
        }
    }
}
function isValidSignature(bytes32 sigHash, bytes calldata signature) external view override returns (bytes4) {
    address mintAuthority_ = getMintAuthority();
    require(mintAuthority_ != address(0x0), "SignatureVerifier: mintAuthority not initialized");
    if (mintAuthority_ == ECDSA.recover(sigHash, signature)) {
        return CORRECT_SIGNATURE_RETURN_VALUE;
    } else {
        return INCORRECT_SIGNATURE_RETURN_VALUE;
    }
}

/// @notice verifySignature checks the the provided signature matches the
/// provided parameters. Returns a 4-byte value as defined by ERC1271.