// Vulnerability label: DC1
{"AbqErc20.sol":{"content":"// SPDX-License-Identifier:MIT\npragma solidity \u003e=0.7.0;\nimport \"./SafeMathTyped.sol\";\n\n// The MIT License\n//\n// Copyright (c) 2017-2018 0xcert, d.o.o. https://0xcert.org\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n/**\n * @title ERC20 standard token implementation.\n * @dev Standard ERC20 token. This contract follows the implementation at https://goo.gl/mLbAPJ.\n */\ncontract Token\n{\n  string internal tokenName;\n\n  string internal tokenSymbol;\n\n  uint8 internal tokenDecimals;\n\n  uint256 internal tokenTotalSupply;\n\n  mapping (address =\u003e uint256) internal balances;\n\n  mapping (address =\u003e mapping (address =\u003e uint256)) internal allowed;\n\n  /**\n   * @dev Trigger when tokens are transferred, including zero value transfers.\n   */\n  event Transfer(\n    address indexed from,\n    address indexed to,\n    uint256 value\n  );\n\n  /**\n   * @dev Trigger on any successful call to approve(address _spender, uint256 _value).\n   */\n  event Approval(\n    address indexed owner,\n    address indexed spender,\n    uint256 value\n  );\n\n  /**\n   * @dev Returns the name of the token.\n   */\n  function name()\n    external\n    view\n    returns (string memory _name)\n  {\n    _name = tokenName;\n  }\n\n  /**\n   * @dev Returns the symbol of the token.\n   */\n  function symbol()\n    external\n    view\n    returns (string memory _symbol)\n  {\n    _symbol = tokenSymbol;\n  }\n\n  /**\n   * @dev Returns the number of decimals the token uses.\n   */\n  function decimals()\n    external\n    view\n    returns (uint8 _decimals)\n  {\n    _decimals = tokenDecimals;\n  }\n\n  /**\n   * @dev Returns the total token supply.\n   */\n  function totalSupply()\n    external\n    view\n    returns (uint256 _totalSupply)\n  {\n    _totalSupply = tokenTotalSupply;\n  }\n\n  /**\n   * @dev Returns the account balance of another account with address _owner.\n   * @param _owner The address from which the balance will be retrieved.\n   */\n  function balanceOf(\n    address _owner\n  )\n    external\n    view\n    returns (uint256 _balance)\n  {\n    _balance = balances[_owner];\n  }\n\n  /**\n   * @dev Transfers _value amount of tokens to address _to, and MUST fire the Transfer event. The\n   * function SHOULD throw if the _from account balance does not have enough tokens to spend.\n   * @param _to The address of the recipient.\n   * @param _value The amount of token to be transferred.\n   */\n  function transfer(\n    address _to,\n    uint256 _value\n  )\n    public\n    returns (bool _success)\n  {\n    require(_value \u003c= balances[msg.sender]);\n\n    balances[msg.sender] = SafeMathTyped.sub256(balances[msg.sender], _value);\n    balances[_to] = SafeMathTyped.add256(balances[_to], _value);\n\n    emit Transfer(msg.sender, _to, _value);\n    _success = true;\n  }\n\n  /**\n   * @dev Allows _spender to withdraw from your account multiple times, up to the _value amount. If\n   * this function is called again it overwrites the current allowance with _value.\n   * @param _spender The address of the account able to transfer the tokens.\n   * @param _value The amount of tokens to be approved for transfer.\n   */\n  function approve(\n    address _spender,\n    uint256 _value\n  )\n    public\n    returns (bool _success)\n  {\n    allowed[msg.sender][_spender] = _value;\n\n    emit Approval(msg.sender, _spender, _value);\n    _success = true;\n  }\n\n  /**\n   * @dev Returns the amount which _spender is still allowed to withdraw from _owner.\n   * @param _owner The address of the account owning tokens.\n   * @param _spender The address of the account able to transfer the tokens.\n   */\n  function allowance(\n    address _owner,\n    address _spender\n  )\n    external\n    view\n    returns (uint256 _remaining)\n  {\n    _remaining = allowed[_owner][_spender];\n  }\n\n  /**\n   * @dev Transfers _value amount of tokens from address _from to address _to, and MUST fire the\n   * Transfer event.\n   * @param _from The address of the sender.\n   * @param _to The address of the recipient.\n   * @param _value The amount of token to be transferred.\n   */\n  function transferFrom(\n    address _from,\n    address _to,\n    uint256 _value\n  )\n    public\n    returns (bool _success)\n  {\n    require(_value \u003c= balances[_from]);\n    require(_value \u003c= allowed[_from][msg.sender]);\n\n    balances[_from] = SafeMathTyped.sub256(balances[_from], _value);\n    balances[_to] = SafeMathTyped.add256(balances[_to], _value);\n    allowed[_from][msg.sender] = SafeMathTyped.sub256(allowed[_from][msg.sender], _value);\n\n    emit Transfer(_from, _to, _value);\n    _success = true;\n  }\n\n}\n\n/// @notice This is the ABQ token. It allows the owner (the Aardbanq DAO) to mint new tokens. It also allow the \n/// owner to change owners. The ABQ token has 18 decimals.\ncontract AbqErc20 is Token\n{\n    /// @notice The owner of the ABQ Token. This is the Aardbanq DAO.\n    address public owner;\n    /// @notice The address for the founders\u0027 contract.\n    address public founderContract;\n\n    constructor(address _owner, address _founderContract)\n    {\n        tokenName = \"Aardbanq DAO\";\n        tokenSymbol = \"ABQ\";\n        tokenDecimals = 18;\n        tokenTotalSupply = 0;\n        owner = _owner;\n        founderContract = _founderContract;\n    }\n\n    modifier onlyOwner()\n    {\n        require(msg.sender == owner, \"ABQ/only-owner\");\n        _;\n    }\n\n    event OwnerChange(address indexed newOwner);\n    /// @notice Allows the owner to change the ownership to another address.\n    /// @param _newOwner The address that should be the new owner.\n    function changeOwner(address _newOwner)\n        external\n        onlyOwner()\n    {\n        owner = _newOwner;\n        emit OwnerChange(_newOwner);\n    }\n\n    /// @notice Allows the owner to mint tokens.\n    /// @param _target The address to mint the tokens to.\n    /// @param _abqAmount The amount of ABQ to mint.\n    function mint(address _target, uint256 _abqAmount)\n        external\n        onlyOwner()\n    {\n        balances[_target] = SafeMathTyped.add256(balances[_target], _abqAmount);\n        emit Transfer(address(0), _target, _abqAmount);\n\n        // CG: Founder\u0027s part 15% of total that will be issued\n        // MATH:\n        // totalIncrease = mintAmount + founderPart {A}\n        // also:\n        // founderPart = 0.15 * totalIncrease\n        // ... founderPart / 0.15 = totalIncrease   {B}\n        // substituting {A} in {B}\n        // ... founderPart / 0.15 = mintAmount + founderPart\n        // ... (founderPart / 0.15) - founderPart = mintAmount\n        // ... (founderPart - (0.15 * founderPart)) / 0.15 = mintAmount\n        // ... (0.85 * founderPart) / 0.15 = mintAmount\n        // ... 0.85 * founderPart = 0.15 * mintAmount\n        // ... founderPart = (0.15 / 0.85) * mintAmount\n        // ... founderPart ~= (mintAmount * 17647) / 100000\n        uint256 founderShare = SafeMathTyped.mul256(_abqAmount, 17647) / 100000;\n        balances[founderContract] = SafeMathTyped.add256(balances[founderContract], founderShare);\n        tokenTotalSupply = SafeMathTyped.add256(SafeMathTyped.add256(tokenTotalSupply, _abqAmount), founderShare);\n        emit Transfer(address(0), founderContract, founderShare);\n    }\n\n    /// @notice Allow the sender to burn tokens in their account.\n    /// @param _abqAmount The amount of tokens to burn from the msg.sender account.\n    function burn(uint256 _abqAmount)\n      external\n    {\n      tokenTotalSupply = SafeMathTyped.sub256(tokenTotalSupply, _abqAmount);\n      balances[msg.sender] = SafeMathTyped.sub256(balances[msg.sender], _abqAmount);\n      emit Transfer(msg.sender, address(0), _abqAmount);\n    }\n\n    event NameChange(string newName);\n    /// @notice Allow the owner to change the name of the token. \n    /// @param _newName The new name for the token\n    function changeName(string calldata _newName)\n      external\n      onlyOwner()\n    {\n      tokenName = _newName;\n      emit NameChange(_newName);\n    }\n\n    event SymbolChange(string newSymbol);\n    /// @notice Allow the owner to change the symbol of the token.\n    /// @param _newSymbol The new symbol for the token.\n    function changeSymbol(string calldata _newSymbol)\n      external\n      onlyOwner()\n    {\n      tokenSymbol = _newSymbol;\n      emit SymbolChange(_newSymbol);\n    }\n}"},"SafeMathTyped.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity \u003e=0.7.0;\n\n/**\n * @title SafeMath\n * @dev Unsigned math operations with safety checks that revert on error\n */\nlibrary SafeMathTyped {\n    /**\n    * @dev Multiplies two unsigned integers, reverts on overflow.\n    */\n    function mul256(uint256 a, uint256 b) internal pure returns (uint256) {\n        // Gas optimization: this is cheaper than requiring \u0027a\u0027 not being zero, but the\n        // benefit is lost if \u0027b\u0027 is also tested.\n        // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522\n        if (a == 0) {\n            return 0;\n        }\n\n        uint256 c = a * b;\n        require(c / a == b, \"uint256 overflow\");\n\n        return c;\n    }\n\n    /**\n    * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.\n    */\n    function div256(uint256 a, uint256 b) internal pure returns (uint256) {\n        // Solidity only automatically asserts when dividing by 0\n        require(b \u003e 0, \"Can\u0027t divide by 0\");\n        uint256 c = a / b;\n        // assert(a == b * c + a % b); // There is no case in which this doesn\u0027t hold\n\n        return c;\n    }\n\n    /**\n    * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.\n    */\n    function div128(uint128 a, uint128 b) internal pure returns (uint128) {\n        // Solidity only automatically asserts when dividing by 0\n        require(b \u003e 0, \"Can\u0027t divide by 0\");\n        uint128 c = a / b;\n        // assert(a == b * c + a % b); // There is no case in which this doesn\u0027t hold\n\n        return c;\n    }\n\n    /**\n    * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).\n    */\n    function sub256(uint256 a, uint256 b) internal pure returns (uint256) {\n        require(b \u003c= a, \"uint256 underflow\");\n        uint256 c = a - b;\n\n        return c;\n    }\n\n    /**\n    * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).\n    */\n    function sub128(uint128 a, uint128 b) internal pure returns (uint128) {\n        require(b \u003c= a, \"uint256 underflow\");\n        uint128 c = a - b;\n\n        return c;\n    }\n\n    /**\n    * @dev Adds two unsigned integers, reverts on overflow.\n    */\n    function add256(uint256 a, uint256 b) internal pure returns (uint256) {\n        uint256 c = a + b;\n        require(c \u003e= a, \"uint256 overflow\");\n\n        return c;\n    }\n\n    /**\n    * @dev Adds two unsigned integers, reverts on overflow.\n    */\n    function add128(uint128 a, uint128 b) internal pure returns (uint128) {\n        uint128 c = a + b;\n        require(c \u003e= a, \"uint128 overflow\");\n\n        return c;\n    }\n\n    /**\n    * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo),\n    * reverts when dividing by zero.\n    */\n    function mod256(uint256 a, uint256 b) internal pure returns (uint256) {\n        require(b != 0, \"Can\u0027t mod by 0\");\n        return a % b;\n    }\n\n    /**\n    * @dev returns the greater of two numbers\n    */\n    function max256(uint256 a, uint256 b) internal pure returns (uint) {\n        return a \u003e b ? a : b;\n    }\n\n    /**\n    * @dev returns the lesser of two numbers\n    */\n    function min256(uint256 a, uint256 b) internal pure returns (uint) {\n        return a \u003c b ? a : b;\n    }\n}"},"SingleOwnerForward.sol":{"content":"pragma solidity \u003e=0.7.0;\n\ncontract SingleOwnerDelegateCall\n{\n    address public implementation;\n    address public owner;\n\n    modifier onlyUninitialized() {\n        require(owner == address(0), \"ABQDAO/only-uninitialized\");\n        _;\n    }\n\n    modifier onlyOwner() {\n        require(msg.sender == owner, \"ABQDAO/only-owner\");\n        _;\n    }\n\n    function setOwner(address _owner)\n        external\n        onlyUninitialized()\n    {\n        owner = _owner;\n        emit OwnerChanged(_owner);\n    }\n\n    event OwnerChanged(address newOwner);\n    function changeOwner(address _newOwner)\n        external\n        onlyOwner()\n    {\n        owner = _newOwner;\n        emit OwnerChanged(_newOwner);\n    }\n\n    event DelegateCallPerformed(address target, bytes data);\n    function performDelegateCall(address _target, bytes calldata _data) \n        external\n        onlyOwner()\n    {\n        (bool success, ) = _target.delegatecall(_data);\n        require(success, \"ABQDAO/could-not-delegate-call\");\n        emit DelegateCallPerformed(_target, _data);\n    }\n}"},"StakedVotingGovernance.sol":{"content":"pragma solidity \u003e=0.7.0;\nimport \"./SafeMathTyped.sol\";\nimport \"./AbqErc20.sol\";\nimport \"./SingleOwnerForward.sol\";\n\nenum GovernanceState \n{\n    SubmissionsAccepted,\n    SubmissionsOpen,\n    SubmissionsSelection,\n    VotingStarted,\n    ProposalConclusion,\n    AwaitingSelectionCall\n}\n\nstruct Proposal \n{\n    // CG: Word 0 start.\n    address proposalAddress;    // CG: Word 0; 160 bits total.\n    uint32 submissionBatchNumber;   // CG: Word0; 160 + 32 = 192 bits total.\n    // CG: Word 0 end.\n\n    // CG: Word 1 start.\n    address proposer;\n    // CG: Word 1 end.\n\n    // CG: Word 2 start.\n    uint256 votesInSupport; // CG: Word 2; 256 bits total.\n    // CG: Word 2 full.\n\n    // CG: Word 3 start.\n    uint256 votesInOpposition;  // CG: Word 3; 256 bits total.\n    // CG: Word 3 full.\n\n    // CG: Word 4 start.\n    uint256 proposalDeposit;  // CG: Word 4; 256 bits total.\n    // CG: Word 4 full.\n\n    bytes proposalData;\n\n    mapping(address =\u003e VoteStatus) votesCasted;\n}\n\nenum VoteStatus \n{\n    Abstain,\n    Support,\n    Oppose\n}\n\nstruct Stake \n{\n    uint256 amount;\n    address delegate;\n}\n\n/// @notice This is a governance contract for the Aardbanq DAO. All ABQ token holders can stake\n/// their tokens and delegate their voting rights to an address, including to themselves. \n/// Only one proposal can be voted on to be executed at a time.\n/// Voters can stake or unstake their ABQ tokens at anytime using the `stake` and `unstake` method.\n/// The protocol for selecting and voting on proposals works as follows:\n/// * If there are no pending proposals, then anyone can submit a proposal candidate to be considered provided they pay an ABQ deposit of `proposalDeposit` (which also stores the 18 decimals).\n/// * For `submissionWindow` seconds after the first proposal candidate was submitted can submit another proposal candidates by also paying an ABQ deposit of `proposalDeposit` (which also stores the 18 decimals).\n/// * When the first proposal candidate is submitted, a proposal to \"do nothing\" is also automatically created.\n/// * During the first `submissionSelectionWindow` seconds after the first proposal candidate was submitted the voters may place their votes with their preferred proposal candidate.\n/// * After the first `submissionSelectionWindow` seconds after the first proposal candidate was submitted, the candidate that received the most votes can be made the proposal all voters should vote on, by calling the `selectMostSupportedProposal` function.\n/// * In the event of a tie between the candidates for most votes the last candidate will receive presidence. However if the \"do nothing\" proposal is also tied for most votes, it will always take precedence.\n/// * Once a proposal candidate has been established as the proposal, all voters may only vote on that proposal. Voting stays open for `votingWindow` seconds after this.\n/// * When `votingWindow` seconds have passed since the proposal candidate has been promoted to the proposal or if the proposal has received more than 50% of all staked votes either for or against it, then the proposal may be executed calling the `resolveProposal` method.\n/// * When a propsal is resolved it is considered successful only if more than 50% of all votes on it is in favor if it AND the proposal was resolved within `resolutionWindow` seconds after it was promoted from a proposal candidate to the proposal.\n/// * Once the proposal has been resolved a new round of proposal candidates may be submitted again.\n/// * All proposal candidates that were not promoted to the proposal and all failed proposals will have their deposits burnt. This is to avoid frivolous and malicious proposals that could cost the voters more gas than the person making the proposal.\n/// * All successful proposals will have their deposits returned.\n/// A proposal consist of an address and data, that the `daoOwnerContract` delegate calls to the address with the data.\ncontract StakedVotingGovernance \n{\n    // CG: Word 0 start.\n    SingleOwnerDelegateCall public daoOwnerContract;   // CG: Word 0; 160 bits total.\n    uint32 public currentSubmissionBatchNumber = 1; // CG: Word 0; 160 + 32 = 192 bits total.\n    uint64 public submissionStartedDate;    // CG: Word 0; 192 + 64 = 256 bits total.\n    // CG: Word 0 full.\n\n    // CG: Word 1 start.\n    AbqErc20 public token;  // CG: Word 1; 160 bits total.\n    uint64 public votingStartedDate;    // CG: Word 1; 160 + 64 = 224 bits total.\n    uint32 public submissionWindow = 2 days;    // CG: Word 1; 224 + 32 = 256 bits.\n    // CG: Word 1 full.\n\n    // CG: Word 2 start.\n    uint32 public submissionSelectionWindow = 4 days;   // CG: Word 2; 32 bits total.\n    uint32 public votingWindow = 3 days;    // CG: Word 2; 32 + 32 = 64 bits total.\n    uint32 public resolutionWindow = 10 days;   // CG: Word 2; 64 + 32 = 96 bits total.\n    // CG: Word 2 end.\n\n    // CG: Word 3 start.\n    uint256 public burnAmount;\n    // CG: Word 3 full.\n\n    // CG: Word 4 start.\n    bytes32 public currentProposalHash;\n    // CG: Word 4 full.\n    \n    // CG: Word 5 start.\n    uint256 public totalVotesStaked;\n    // CG: Word 5 full.\n\n    // CG: Word 6 start.\n    uint256 public proposalDeposit = 100 ether;\n    // CG: Word 6 full.\n\n    bytes32[] public runningProposals;\n    mapping(bytes32 =\u003e Proposal) public proposals;\n    mapping(address =\u003e uint256) public refundAmount;\n\n    mapping(address =\u003e uint256) public votingPower;\n    mapping(address =\u003e Stake) public stakes;\n    mapping(address =\u003e bytes32) public lastVotedOn;\n\n    constructor (SingleOwnerDelegateCall _daoOwnerContract, AbqErc20 _token)\n    {\n        daoOwnerContract = _daoOwnerContract;\n        token = _token;\n    }\n\n    modifier onlyDaoOwner()\n    {\n        require(msg.sender == address(daoOwnerContract), \"ABQDAO/only-dao-owner\");\n        _;\n    }\n\n    modifier onlyAcceptingProposalsState()\n    {\n        GovernanceState governanceState = proposalsState();\n        require(governanceState == GovernanceState.SubmissionsAccepted || governanceState == GovernanceState.SubmissionsOpen, \"ABQDAO/submissions-not-allowed\");\n        _;\n    }\n\n    modifier onlyVotingState()\n    {\n        GovernanceState governanceState = proposalsState();\n        require(governanceState == GovernanceState.VotingStarted, \"ABQDAO/voting-not-allowed\");\n        _;\n    }\n\n    modifier onlyAwaitingSelectionCallState()\n    {\n        GovernanceState governanceState = proposalsState();\n        require(governanceState == GovernanceState.AwaitingSelectionCall, \"ABQDAO/selection-call-not-allowed\");\n        _;\n    }\n\n    function changeTimeWindows(uint32 _submissionWindow, uint32 _submissionSelectionWindow, uint32 _votingWindow, uint32 _resolutionWindow)\n        onlyDaoOwner()\n        external\n    {\n        // CG: ensure all parameters are between [1 days, 31 days] (in seconds).\n        require(_submissionWindow \u003e= 1 days \u0026\u0026 _submissionWindow \u003c= 31 days, \"ABQDAO/out-of-range\");\n        require(_submissionSelectionWindow \u003e= 1 days \u0026\u0026 _submissionSelectionWindow \u003c= 31 days, \"ABQDAO/out-of-range\");\n        require(_votingWindow \u003e= 1 days \u0026\u0026 _votingWindow \u003c= 31 days, \"ABQDAO/out-of-range\");\n        require(_resolutionWindow \u003e= 1 days \u0026\u0026 _resolutionWindow \u003c= 31 days, \"ABQDAO/out-of-range\");\n\n        // CG: Ensure dependend windows occur after in the correct order.\n        // CG: Given the above constraints that these values aren\u0027t greater than 31 days (in seconds), we can safely add 1 day (in seconds) without an overflow happening.\n        require(_submissionSelectionWindow \u003e= (_submissionSelectionWindow + 1 days), \"ABQDAO/out-of-range\");\n        require(_resolutionWindow \u003e= (_votingWindow + 1 days), \"ABQDAO/out-of-range\");\n\n        // CG: Set the values.\n        submissionWindow = submissionWindow;\n        submissionSelectionWindow = _submissionSelectionWindow;\n        votingWindow = _votingWindow;\n        resolutionWindow = _resolutionWindow;\n    }\n\n    function proposalsState()\n        public\n        view\n        returns (GovernanceState _proposalsState)\n    {\n        // CG: If no submission has been filed yet, then submissions are eligible.\n        if (submissionStartedDate == 0)\n        {\n            return GovernanceState.SubmissionsAccepted;\n        }\n        // CG: Allow submissions for submissionWindow after first submission.\n        else if (block.timestamp \u003c= SafeMathTyped.add256(submissionStartedDate, submissionWindow))\n        {\n            return GovernanceState.SubmissionsOpen;\n        }\n        // CG: Allow selection of to close submissionSelectionWindow after the first submission.\n        else if (block.timestamp \u003c= SafeMathTyped.add256(submissionStartedDate, submissionSelectionWindow))\n        {\n            return GovernanceState.SubmissionsSelection;\n        }\n        // CG: If more than submissionSelectionWindow has passed since the submissionStartedDate the voting date should be checked.\n        else \n        {\n            // CG: If voting only happened for votingWindow or less so for, voting is still pending\n            if (votingStartedDate == 0)\n            {\n                return GovernanceState.AwaitingSelectionCall;\n            }\n            else if (block.timestamp \u003c= SafeMathTyped.add256(votingStartedDate, votingWindow))\n            {\n                return GovernanceState.VotingStarted;\n            }\n            // CG: If voting has started more than votingWindow ago, then voting is no longer possible\n            else\n            {\n                return GovernanceState.ProposalConclusion;\n            }\n        }\n    }\n\n    function proposalsCount()\n        public\n        view\n        returns (uint256 _proposalsCount)\n    {\n        return runningProposals.length;\n    }\n\n    function viewVote(bytes32 _proposalHash, address _voter)\n        external\n        view\n        returns (VoteStatus)\n    {\n        return proposals[_proposalHash].votesCasted[_voter];\n    }\n\n    event StakeReceipt(address indexed staker, address indexed delegate, address indexed oldDelegate, bool wasStaked, uint256 amount);\n    /// @notice Stake `_amount` of tokens from msg.sender and delegate the voting rights to `_delegate`.\n    /// The tokens have to be approved by msg.sender before calling this method. All tokens staked by msg.sender\n    /// will be have their voting rights assigned to `_delegate`.\n    /// @param _delegate The address to delegate voting rights to.\n    /// @param _amount The amount of tokens to stake.\n    function stake(address _delegate, uint256 _amount)\n        external\n    {\n        // CG: Transfer ABQ.\n        bool couldTransfer = token.transferFrom(msg.sender, address(this), _amount);\n        require(couldTransfer, \"ABQDAO/could-not-transfer-stake\");\n\n        // CG: Get previous stake details.\n        Stake storage stakerStake = stakes[msg.sender];\n        uint256 previousStake = stakerStake.amount;\n        address previousDelegate = stakerStake.delegate;\n\n        // CG: Remove previous delegate stake\n        votingPower[previousDelegate] = SafeMathTyped.sub256(votingPower[previousDelegate], previousStake);\n\n        // CG: Increase stake counts.\n        stakerStake.amount = SafeMathTyped.add256(stakerStake.amount, _amount);\n        stakerStake.delegate = _delegate;\n        votingPower[stakerStake.delegate] = SafeMathTyped.add256(votingPower[stakerStake.delegate], stakerStake.amount);\n\n        // CG: Update previous vote\n        bytes32 previousDelegateLastProposal = lastVotedOn[previousDelegate];\n        bytes32 newDelegateLastProposal = lastVotedOn[stakerStake.delegate];\n        updateVoteIfNeeded(previousDelegateLastProposal, previousDelegate, previousStake, newDelegateLastProposal, stakerStake.delegate, stakerStake.amount);\n\n        // CG: Update running total.\n        totalVotesStaked = SafeMathTyped.add256(totalVotesStaked, _amount);\n\n        emit StakeReceipt(msg.sender, _delegate, previousDelegate, true, _amount);\n    }\n    \n    /// @notice Unstake `_amount` tokens for msg.sender and send them to msg.sender.\n    /// @param _amount The amount of tokens to unstake.\n    function unstake(uint256 _amount)\n        external\n    {\n        // CG: Decrease stake counts.\n        Stake storage stakerStake = stakes[msg.sender];\n        stakerStake.amount = SafeMathTyped.sub256(stakerStake.amount, _amount);\n        address delegate = stakerStake.delegate;\n        votingPower[delegate] = SafeMathTyped.sub256(votingPower[delegate], _amount);\n\n        // CG: Update previous vote\n        bytes32 lastProposal = lastVotedOn[delegate];\n        updateVoteIfNeeded(lastProposal, delegate, _amount, lastProposal, delegate, 0);\n\n        // CG: Transfer ABQ back.\n        bool couldTransfer = token.transfer(msg.sender, _amount);\n        require(couldTransfer, \"ABQDAO/could-not-transfer-stake\");\n\n        // CG: Update running total.\n        totalVotesStaked = SafeMathTyped.sub256(totalVotesStaked, _amount);\n\n        emit StakeReceipt(msg.sender, delegate, delegate, false, _amount);\n    }\n\n    function updateVoteIfNeeded(bytes32 _proposalHashA, address _voterA, uint256 _voterADecrease, bytes32 _proposalHashB, address _voterB, uint256 _voterBIncrease)\n        private\n    {\n        GovernanceState governanceState = proposalsState();\n        // CG: Only update votes while voting is still open.\n        if (governanceState == GovernanceState.SubmissionsOpen || governanceState == GovernanceState.SubmissionsSelection || governanceState == GovernanceState.VotingStarted)\n        {\n            // CG: Only update votes for current submission round on proposal A.\n            Proposal storage proposalA = proposals[_proposalHashA];\n            if (proposalA.submissionBatchNumber == currentSubmissionBatchNumber)\n            {\n                // CG: If voter A has a decrease, decrease it.\n                if (_voterADecrease \u003e 0)\n                {\n                    VoteStatus voterAVote = proposalA.votesCasted[_voterA];\n                    if (voterAVote == VoteStatus.Support)\n                    {\n                        proposalA.votesInSupport = SafeMathTyped.sub256(proposalA.votesInSupport, _voterADecrease);\n                        emit Ballot(_voterA, _proposalHashA, voterAVote, votingPower[_voterA]);\n                    }\n                    else if (voterAVote == VoteStatus.Oppose)\n                    {\n                        proposalA.votesInOpposition = SafeMathTyped.sub256(proposalA.votesInOpposition, _voterADecrease);\n                        emit Ballot(_voterA, _proposalHashA, voterAVote, votingPower[_voterA]);\n                    }\n                }\n            }\n\n            // CG: Only update votes for current submission round on proposal B.\n            Proposal storage proposalB = proposals[_proposalHashB];\n            if (proposalB.submissionBatchNumber == currentSubmissionBatchNumber)\n            {\n                // CG: If voter B has an increase, increase it.\n                if (_voterBIncrease \u003e 0)\n                {\n                    VoteStatus voterBVote = proposalB.votesCasted[_voterB];\n                    if (voterBVote == VoteStatus.Support)\n                    {\n                        proposalB.votesInSupport = SafeMathTyped.add256(proposalB.votesInSupport, _voterBIncrease);\n                        emit Ballot(_voterB, _proposalHashB, voterBVote, votingPower[_voterB]);\n                    }\n                    else if (voterBVote == VoteStatus.Oppose)\n                    {\n                        proposalB.votesInOpposition = SafeMathTyped.add256(proposalB.votesInOpposition, _voterBIncrease);\n                        emit Ballot(_voterB, _proposalHashB, voterBVote, votingPower[_voterB]);\n                    }\n                }\n            }\n        }\n    }\n\n    event ProposalReceipt(bytes32 proposalHash);\n    /// @notice Make a poposal for a resolution.\n    /// @param _executionAddress The address containing the smart contract to delegate call.\n    /// @param _data The data to send when executing the proposal.\n    function propose(address _executionAddress, bytes calldata _data)\n        onlyAcceptingProposalsState()\n        external\n        returns (bytes32 _hash)\n    {\n        // CG: Get proposal hash and make sure it is not already submitted.\n        bytes32 proposalHash = keccak256(abi.encodePacked(currentSubmissionBatchNumber, _executionAddress, _data));\n        Proposal storage proposal = proposals[proposalHash];\n        require(proposal.submissionBatchNumber == 0, \"ABQDAO/proposal-already-submitted\");\n\n        // CG: Transfer deposit.\n        bool couldTransferDeposit = token.transferFrom(msg.sender, address(this), proposalDeposit);\n        require(couldTransferDeposit, \"ABQDAO/could-not-transfer-deposit\");\n\n        // CG: If this is the first proposal, add a \"do nothing\" proposal as the first proposal\n        if (runningProposals.length == 0)\n        {\n            address doNothingAddress = address(0);\n            bytes memory doNothingData = new bytes(0);\n            bytes32 doNothingHash = keccak256(abi.encodePacked(currentSubmissionBatchNumber, doNothingAddress, doNothingData));\n            \n            Proposal storage doNothingProposal = proposals[doNothingHash];\n            doNothingProposal.proposalAddress = doNothingAddress;\n            doNothingProposal.proposalDeposit = 0;\n            doNothingProposal.submissionBatchNumber = currentSubmissionBatchNumber;\n            doNothingProposal.proposer = address(0);\n            doNothingProposal.votesInSupport = 0;\n            doNothingProposal.votesInOpposition = 0;\n            doNothingProposal.proposalData = doNothingData;\n\n            runningProposals.push(doNothingHash);\n            emit ProposalReceipt(doNothingHash);\n\n            submissionStartedDate = uint64(block.timestamp);\n        }\n\n        // CG: Set the proposal data\n        proposal.proposalAddress = _executionAddress;\n        proposal.proposalDeposit = proposalDeposit;\n        proposal.submissionBatchNumber = currentSubmissionBatchNumber;\n        proposal.proposer = msg.sender;\n        proposal.votesInSupport = 0;\n        proposal.votesInOpposition = 0;\n        proposal.proposalData = _data;\n\n        runningProposals.push(proposalHash);\n        emit ProposalReceipt(proposalHash);\n\n        return proposalHash;\n    }\n\n    event VoteOpenedReceipt(bytes32 proposalHash);\n    /// @notice Select the most supported proposal.\n    /// @param maxIterations The max iteration to execute. This is used to throttle gas useage per call.\n    function selectMostSupportedProposal(uint8 maxIterations)\n        onlyAwaitingSelectionCallState()\n        external\n        returns (bool _isSelectionComplete)\n    {\n        if (votingStartedDate != 0)\n        {\n            return true;\n        }\n\n        while (runningProposals.length \u003e 1 \u0026\u0026 maxIterations \u003e 0)\n        {\n            Proposal storage firstProposal = proposals[runningProposals[0]];\n            Proposal storage lastProposal = proposals[runningProposals[runningProposals.length - 1]];  // CG: runningProposals.length - 1 will always be \u003e= 1 since we check runningProposals.length \u003e 1 in the while\u0027s condition. Hence no overflow will occur.\n            if (firstProposal.votesInSupport \u003c lastProposal.votesInSupport)\n            {\n                burnAmount = SafeMathTyped.add256(burnAmount, firstProposal.proposalDeposit);\n                runningProposals[0] = runningProposals[runningProposals.length - 1];  // CG: runningProposals.length - 1 will always be \u003e= 1 since we check runningProposals.length \u003e 1 in the while\u0027s condition. Hence no overflow will occur.\n            }\n            else\n            {\n                burnAmount = SafeMathTyped.add256(burnAmount, lastProposal.proposalDeposit);\n            }\n            runningProposals.pop();\n            maxIterations = maxIterations - 1;  // CG: We can safely subtract 1 without overflow issues, since the while test for maxIterations \u003e 0;\n        }\n\n        if (runningProposals.length == 1)\n        {\n            currentProposalHash = runningProposals[0];\n            votingStartedDate = uint64(block.timestamp);\n            runningProposals.pop();\n\n            emit VoteOpenedReceipt(currentProposalHash);\n            return true;\n        }\n        else\n        {\n            return false;\n        }\n    }\n\n    event Ballot(address indexed voter, bytes32 proposalHash, VoteStatus vote, uint256 votes);\n    /// @notice Cast a vote for a specific proposal for msg.sender.\n    /// @param _proposalHash The hash for the proposal to vote on.\n    /// @param _vote Indication of if msg.sender is voting in support, opposition, or abstaining.\n    function vote(bytes32 _proposalHash, VoteStatus _vote)\n        external\n    {\n        // CG: Must be in submission selection or voting state.\n        GovernanceState state = proposalsState();\n        require(state == GovernanceState.SubmissionsOpen || state == GovernanceState.SubmissionsSelection || state == GovernanceState.VotingStarted, \"ABQDAO/voting-not-open\");\n        \n        // CG: If in voting state, only votes on the current proposal allowed.\n        if (state == GovernanceState.VotingStarted)\n        {\n            require(currentProposalHash == _proposalHash, \"ABQDAO/only-votes-on-current-proposal\");\n        }\n\n        uint256 voteCount = votingPower[msg.sender];\n\n        // CG: Reverse previous vote on the current proposal round.\n        Proposal storage previousProposal = proposals[lastVotedOn[msg.sender]];\n        if (previousProposal.submissionBatchNumber == currentSubmissionBatchNumber)\n        {\n            VoteStatus previousVote = previousProposal.votesCasted[msg.sender];\n            if (previousVote == VoteStatus.Support)\n            {\n                previousProposal.votesInSupport = SafeMathTyped.sub256(previousProposal.votesInSupport, voteCount);\n                previousProposal.votesCasted[msg.sender] = VoteStatus.Abstain;\n            }\n            else if (previousVote == VoteStatus.Oppose)\n            {\n                previousProposal.votesInOpposition = SafeMathTyped.sub256(previousProposal.votesInOpposition, voteCount);\n                previousProposal.votesCasted[msg.sender] = VoteStatus.Abstain;\n            }\n        }\n\n        // CG: Only votes allowed on current proposal round.\n        Proposal storage proposal = proposals[_proposalHash];\n        require(proposal.submissionBatchNumber == currentSubmissionBatchNumber, \"ABQDAO/only-votes-on-current-submissions\");\n        \n        // CG: Cast the voter\u0027s vote\n        if (_vote == VoteStatus.Support)\n        {\n            proposal.votesInSupport = SafeMathTyped.add256(proposal.votesInSupport, voteCount);\n            proposal.votesCasted[msg.sender] = VoteStatus.Support;\n        }\n        else if (_vote == VoteStatus.Oppose)\n        {\n            proposal.votesInOpposition = SafeMathTyped.add256(proposal.votesInOpposition, voteCount);\n            proposal.votesCasted[msg.sender] = VoteStatus.Oppose;\n        }\n\n        lastVotedOn[msg.sender] = _proposalHash;\n        emit Ballot(msg.sender, _proposalHash, _vote, voteCount);\n    }\n\n    event ProposalResolution(bytes32 proposalHash, bool wasPassed);\n    /// @notice Resolve the proposal that was voted on.\n    function resolveProposal()\n        external\n    {\n        require(currentProposalHash != 0, \"ABQDAO/no-proposal\");\n        GovernanceState state = proposalsState();\n        require(state == GovernanceState.VotingStarted || state == GovernanceState.ProposalConclusion, \"ABQDAO/cannot-resolve-yet\");\n\n        bool hasPassed = false;\n        Proposal storage proposal = proposals[currentProposalHash];\n        \n        if (state == GovernanceState.VotingStarted)\n        {\n            // CG: If a proposal already has more than 50% of all staked votes then it can be passed before voting concluded.\n            if (proposal.votesInSupport \u003e= SafeMathTyped.add256(SafeMathTyped.div256(totalVotesStaked,2), 1))\n            {\n                hasPassed = true;\n            }\n            // CG: If a proposal already has more than 50% of all staked votes against it then it can be defeated before voting concluded.\n            else if (proposal.votesInOpposition \u003e= SafeMathTyped.add256(SafeMathTyped.div256(totalVotesStaked,2), 1))\n            {\n                hasPassed = false;\n            }\n            else\n            {\n                revert(\"ABQDAO/voting-in-progress\");\n            }\n        }\n        else if (state == GovernanceState.ProposalConclusion)\n        {\n            // CG: If the proposal was started voting on less than resolutionWindow ago, then resolve based on amount of votes.\n            if (SafeMathTyped.add256(votingStartedDate, resolutionWindow) \u003e block.timestamp)\n            {\n                // CG: After voting time has concluded it is a pass if more votes are in support than in opposition.\n                hasPassed = proposal.votesInSupport \u003e proposal.votesInOpposition;\n            }\n            // CG: Since voting started resolutionWindow or more ago already and have not been executed yet, fail the proposal.\n            else\n            {\n                hasPassed = false;\n            }\n        }\n\n        // CG: Emit the event before we lose the hash stored in currentProposalHash.\n        emit ProposalResolution(currentProposalHash, hasPassed);\n\n        // CG: Close the proposal\n        currentProposalHash = 0;\n        currentSubmissionBatchNumber += 1;\n        submissionStartedDate = 0;\n        votingStartedDate = 0;\n\n        if (hasPassed)\n        {\n            // CG: Refund deposit to proposer.\n            refundAmount[proposal.proposer] = SafeMathTyped.add256(refundAmount[proposal.proposer], proposal.proposalDeposit);\n\n            // CG: Call into owner to execute the proposal.\n            daoOwnerContract.performDelegateCall(proposal.proposalAddress, proposal.proposalData);\n        }\n        else\n        {\n            // CG: If it isn\u0027t a passed proposal, then the deposit should be burned.\n            burnAmount = SafeMathTyped.add256(burnAmount, proposal.proposalDeposit);\n        }\n    }\n\n    /// @notice Burns the deposits of failed submissions.\n    function burnDepositsOfFailedSubmissions()\n        external\n    {\n        token.burn(burnAmount);\n        burnAmount = 0;\n    }\n\n    /// @notice Refund the deposits for `_for` that was associated to succesful resolutions.\n    /// @param _for The address to refund deposits for.\n    function refundSuccessfulSubmissions(address _for)\n        external\n    {\n        uint256 amount = refundAmount[_for];\n        refundAmount[_for] = 0;\n\n        bool couldRefund = token.transfer(_for, amount);\n        require(couldRefund, \"ABQDAO/could-not-refund\");\n    }\n}"}}