// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity =0.8.19;

import { IAzorius } from "./interfaces/IAzorius.sol";
import { IBaseStrategy } from "./interfaces/IBaseStrategy.sol";
import { FactoryFriendly } from "@gnosis.pm/zodiac/contracts/factory/FactoryFriendly.sol";
import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";

/**
 * The base abstract contract for all voting strategies in Azorius.
 */
abstract contract BaseStrategy is OwnableUpgradeable, FactoryFriendly, IBaseStrategy {

    event AzoriusSet(address indexed azoriusModule);
    event StrategySetUp(address indexed azoriusModule, address indexed owner);

    error OnlyAzorius();

    IAzorius public azoriusModule;

    /**
     * Ensures that only the [Azorius](./Azorius.md) contract that pertains to this 
     * [BaseStrategy](./BaseStrategy.md) can call functions on it.
     */
    modifier onlyAzorius() {
        if (msg.sender != address(azoriusModule)) revert OnlyAzorius();
        _;
    }

    constructor() {
      _disableInitializers();
    }

    /** @inheritdoc IBaseStrategy*/
    function setAzorius(address _azoriusModule) external onlyOwner {
        azoriusModule = IAzorius(_azoriusModule);
        emit AzoriusSet(_azoriusModule);
    }

    /** @inheritdoc IBaseStrategy*/
    function initializeProposal(bytes memory _data) external virtual;

    /** @inheritdoc IBaseStrategy*/
    function isPassed(uint32 _proposalId) external view virtual returns (bool);

    /** @inheritdoc IBaseStrategy*/
    function isProposer(address _address) external view virtual returns (bool);

    /** @inheritdoc IBaseStrategy*/
    function votingEndBlock(uint32 _proposalId) external view virtual returns (uint32);

    /**
     * Sets the address of the [Azorius](Azorius.md) module contract.
     *
     * @param _azoriusModule address of the Azorius module
     */
    function _setAzorius(address _azoriusModule) internal {
        azoriusModule = IAzorius(_azoriusModule);
        emit AzoriusSet(_azoriusModule);
    }
}
[{"inputs":[],"name":"AlreadyVoted","type":"error"},{"inputs":[],"name":"InvalidBasisNumerator","type":"error"},{"inputs":[],"name":"InvalidProposal","type":"error"},{"inputs":[],"name":"InvalidQuorumNumerator","type":"error"},{"inputs":[],"name":"InvalidTokenAddress","type":"error"},{"inputs":[],"name":"InvalidVote","type":"error"},{"inputs":[],"name":"OnlyAzorius","type":"error"},{"inputs":[],"name":"VotingEnded","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"azoriusModule","type":"address"}],"name":"AzoriusSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"basisNumerator","type":"uint256"}],"name":"BasisNumeratorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"proposalId","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"votingEndBlock","type":"uint32"}],"name":"ProposalInitialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"quorumNumerator","type":"uint256"}],"name":"QuorumNumeratorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"requiredProposerWeight","type":"uint256"}],"name":"RequiredProposerWeightUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"azoriusModule","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"}],"name":"StrategySetUp","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"voter","type":"address"},{"indexed":false,"internalType":"uint32","name":"proposalId","type":"uint32"},{"indexed":false,"internalType":"uint8","name":"voteType","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"weight","type":"uint256"}],"name":"Voted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"votingPeriod","type":"uint32"}],"name":"VotingPeriodUpdated","type":"event"},{"inputs":[],"name":"BASIS_DENOMINATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"QUORUM_DENOMINATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"azoriusModule","outputs":[{"internalType":"contract IAzorius","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"basisNumerator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_proposalId","type":"uint32"}],"name":"getProposalVotes","outputs":[{"internalType":"uint256","name":"noVotes","type":"uint256"},{"internalType":"uint256","name":"yesVotes","type":"uint256"},{"internalType":"uint256","name":"abstainVotes","type":"uint256"},{"internalType":"uint32","name":"startBlock","type":"uint32"},{"internalType":"uint32","name":"endBlock","type":"uint32"},{"internalType":"uint256","name":"votingSupply","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_proposalId","type":"uint32"}],"name":"getProposalVotingSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_voter","type":"address"},{"internalType":"uint32","name":"_proposalId","type":"uint32"}],"name":"getVotingWeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governanceToken","outputs":[{"internalType":"contract IVotes","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_proposalId","type":"uint32"},{"internalType":"address","name":"_address","type":"address"}],"name":"hasVoted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"initializeProposal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_proposalId","type":"uint32"}],"name":"isPassed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"isProposer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_yesVotes","type":"uint256"},{"internalType":"uint256","name":"_noVotes","type":"uint256"}],"name":"meetsBasis","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_totalSupply","type":"uint256"},{"internalType":"uint256","name":"_yesVotes","type":"uint256"},{"internalType":"uint256","name":"_abstainVotes","type":"uint256"}],"name":"meetsQuorum","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"quorumNumerator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_proposalId","type":"uint32"}],"name":"quorumVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"requiredProposerWeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_azoriusModule","type":"address"}],"name":"setAzorius","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"initializeParams","type":"bytes"}],"name":"setUp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_basisNumerator","type":"uint256"}],"name":"updateBasisNumerator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_quorumNumerator","type":"uint256"}],"name":"updateQuorumNumerator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_requiredProposerWeight","type":"uint256"}],"name":"updateRequiredProposerWeight","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_votingPeriod","type":"uint32"}],"name":"updateVotingPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_proposalId","type":"uint32"},{"internalType":"uint8","name":"_voteType","type":"uint8"}],"name":"vote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_proposalId","type":"uint32"}],"name":"votingEndBlock","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"votingPeriod","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"}]