GovernorCompatibilityBravoUpgradeable.sol 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. // SPDX-License-Identifier: MIT
  2. // OpenZeppelin Contracts (last updated v4.5.0-rc.0) (governance/compatibility/GovernorCompatibilityBravo.sol)
  3. pragma solidity ^0.8.0;
  4. import "../../utils/CountersUpgradeable.sol";
  5. import "../../utils/math/SafeCastUpgradeable.sol";
  6. import "../extensions/IGovernorTimelockUpgradeable.sol";
  7. import "../GovernorUpgradeable.sol";
  8. import "./IGovernorCompatibilityBravoUpgradeable.sol";
  9. import "../../proxy/utils/Initializable.sol";
  10. /**
  11. * @dev Compatibility layer that implements GovernorBravo compatibility on to of {Governor}.
  12. *
  13. * This compatibility layer includes a voting system and requires a {IGovernorTimelock} compatible module to be added
  14. * through inheritance. It does not include token bindings, not does it include any variable upgrade patterns.
  15. *
  16. * NOTE: When using this module, you may need to enable the Solidity optimizer to avoid hitting the contract size limit.
  17. *
  18. * _Available since v4.3._
  19. */
  20. abstract contract GovernorCompatibilityBravoUpgradeable is Initializable, IGovernorTimelockUpgradeable, IGovernorCompatibilityBravoUpgradeable, GovernorUpgradeable {
  21. function __GovernorCompatibilityBravo_init() internal onlyInitializing {
  22. }
  23. function __GovernorCompatibilityBravo_init_unchained() internal onlyInitializing {
  24. }
  25. using CountersUpgradeable for CountersUpgradeable.Counter;
  26. using TimersUpgradeable for TimersUpgradeable.BlockNumber;
  27. enum VoteType {
  28. Against,
  29. For,
  30. Abstain
  31. }
  32. struct ProposalDetails {
  33. address proposer;
  34. address[] targets;
  35. uint256[] values;
  36. string[] signatures;
  37. bytes[] calldatas;
  38. uint256 forVotes;
  39. uint256 againstVotes;
  40. uint256 abstainVotes;
  41. mapping(address => Receipt) receipts;
  42. bytes32 descriptionHash;
  43. }
  44. mapping(uint256 => ProposalDetails) private _proposalDetails;
  45. // solhint-disable-next-line func-name-mixedcase
  46. function COUNTING_MODE() public pure virtual override returns (string memory) {
  47. return "support=bravo&quorum=bravo";
  48. }
  49. // ============================================== Proposal lifecycle ==============================================
  50. /**
  51. * @dev See {IGovernor-propose}.
  52. */
  53. function propose(
  54. address[] memory targets,
  55. uint256[] memory values,
  56. bytes[] memory calldatas,
  57. string memory description
  58. ) public virtual override(IGovernorUpgradeable, GovernorUpgradeable) returns (uint256) {
  59. _storeProposal(_msgSender(), targets, values, new string[](calldatas.length), calldatas, description);
  60. return super.propose(targets, values, calldatas, description);
  61. }
  62. /**
  63. * @dev See {IGovernorCompatibilityBravo-propose}.
  64. */
  65. function propose(
  66. address[] memory targets,
  67. uint256[] memory values,
  68. string[] memory signatures,
  69. bytes[] memory calldatas,
  70. string memory description
  71. ) public virtual override returns (uint256) {
  72. _storeProposal(_msgSender(), targets, values, signatures, calldatas, description);
  73. return propose(targets, values, _encodeCalldata(signatures, calldatas), description);
  74. }
  75. /**
  76. * @dev See {IGovernorCompatibilityBravo-queue}.
  77. */
  78. function queue(uint256 proposalId) public virtual override {
  79. ProposalDetails storage details = _proposalDetails[proposalId];
  80. queue(
  81. details.targets,
  82. details.values,
  83. _encodeCalldata(details.signatures, details.calldatas),
  84. details.descriptionHash
  85. );
  86. }
  87. /**
  88. * @dev See {IGovernorCompatibilityBravo-execute}.
  89. */
  90. function execute(uint256 proposalId) public payable virtual override {
  91. ProposalDetails storage details = _proposalDetails[proposalId];
  92. execute(
  93. details.targets,
  94. details.values,
  95. _encodeCalldata(details.signatures, details.calldatas),
  96. details.descriptionHash
  97. );
  98. }
  99. function cancel(uint256 proposalId) public virtual override {
  100. ProposalDetails storage details = _proposalDetails[proposalId];
  101. require(
  102. _msgSender() == details.proposer || getVotes(details.proposer, block.number - 1) < proposalThreshold(),
  103. "GovernorBravo: proposer above threshold"
  104. );
  105. _cancel(
  106. details.targets,
  107. details.values,
  108. _encodeCalldata(details.signatures, details.calldatas),
  109. details.descriptionHash
  110. );
  111. }
  112. /**
  113. * @dev Encodes calldatas with optional function signature.
  114. */
  115. function _encodeCalldata(string[] memory signatures, bytes[] memory calldatas)
  116. private
  117. pure
  118. returns (bytes[] memory)
  119. {
  120. bytes[] memory fullcalldatas = new bytes[](calldatas.length);
  121. for (uint256 i = 0; i < signatures.length; ++i) {
  122. fullcalldatas[i] = bytes(signatures[i]).length == 0
  123. ? calldatas[i]
  124. : abi.encodePacked(bytes4(keccak256(bytes(signatures[i]))), calldatas[i]);
  125. }
  126. return fullcalldatas;
  127. }
  128. /**
  129. * @dev Store proposal metadata for later lookup
  130. */
  131. function _storeProposal(
  132. address proposer,
  133. address[] memory targets,
  134. uint256[] memory values,
  135. string[] memory signatures,
  136. bytes[] memory calldatas,
  137. string memory description
  138. ) private {
  139. bytes32 descriptionHash = keccak256(bytes(description));
  140. uint256 proposalId = hashProposal(targets, values, _encodeCalldata(signatures, calldatas), descriptionHash);
  141. ProposalDetails storage details = _proposalDetails[proposalId];
  142. if (details.descriptionHash == bytes32(0)) {
  143. details.proposer = proposer;
  144. details.targets = targets;
  145. details.values = values;
  146. details.signatures = signatures;
  147. details.calldatas = calldatas;
  148. details.descriptionHash = descriptionHash;
  149. }
  150. }
  151. // ==================================================== Views =====================================================
  152. /**
  153. * @dev See {IGovernorCompatibilityBravo-proposals}.
  154. */
  155. function proposals(uint256 proposalId)
  156. public
  157. view
  158. virtual
  159. override
  160. returns (
  161. uint256 id,
  162. address proposer,
  163. uint256 eta,
  164. uint256 startBlock,
  165. uint256 endBlock,
  166. uint256 forVotes,
  167. uint256 againstVotes,
  168. uint256 abstainVotes,
  169. bool canceled,
  170. bool executed
  171. )
  172. {
  173. id = proposalId;
  174. eta = proposalEta(proposalId);
  175. startBlock = proposalSnapshot(proposalId);
  176. endBlock = proposalDeadline(proposalId);
  177. ProposalDetails storage details = _proposalDetails[proposalId];
  178. proposer = details.proposer;
  179. forVotes = details.forVotes;
  180. againstVotes = details.againstVotes;
  181. abstainVotes = details.abstainVotes;
  182. ProposalState status = state(proposalId);
  183. canceled = status == ProposalState.Canceled;
  184. executed = status == ProposalState.Executed;
  185. }
  186. /**
  187. * @dev See {IGovernorCompatibilityBravo-getActions}.
  188. */
  189. function getActions(uint256 proposalId)
  190. public
  191. view
  192. virtual
  193. override
  194. returns (
  195. address[] memory targets,
  196. uint256[] memory values,
  197. string[] memory signatures,
  198. bytes[] memory calldatas
  199. )
  200. {
  201. ProposalDetails storage details = _proposalDetails[proposalId];
  202. return (details.targets, details.values, details.signatures, details.calldatas);
  203. }
  204. /**
  205. * @dev See {IGovernorCompatibilityBravo-getReceipt}.
  206. */
  207. function getReceipt(uint256 proposalId, address voter) public view virtual override returns (Receipt memory) {
  208. return _proposalDetails[proposalId].receipts[voter];
  209. }
  210. /**
  211. * @dev See {IGovernorCompatibilityBravo-quorumVotes}.
  212. */
  213. function quorumVotes() public view virtual override returns (uint256) {
  214. return quorum(block.number - 1);
  215. }
  216. // ==================================================== Voting ====================================================
  217. /**
  218. * @dev See {IGovernor-hasVoted}.
  219. */
  220. function hasVoted(uint256 proposalId, address account) public view virtual override returns (bool) {
  221. return _proposalDetails[proposalId].receipts[account].hasVoted;
  222. }
  223. /**
  224. * @dev See {Governor-_quorumReached}. In this module, only forVotes count toward the quorum.
  225. */
  226. function _quorumReached(uint256 proposalId) internal view virtual override returns (bool) {
  227. ProposalDetails storage details = _proposalDetails[proposalId];
  228. return quorum(proposalSnapshot(proposalId)) <= details.forVotes;
  229. }
  230. /**
  231. * @dev See {Governor-_voteSucceeded}. In this module, the forVotes must be scritly over the againstVotes.
  232. */
  233. function _voteSucceeded(uint256 proposalId) internal view virtual override returns (bool) {
  234. ProposalDetails storage details = _proposalDetails[proposalId];
  235. return details.forVotes > details.againstVotes;
  236. }
  237. /**
  238. * @dev See {Governor-_countVote}. In this module, the support follows Governor Bravo.
  239. */
  240. function _countVote(
  241. uint256 proposalId,
  242. address account,
  243. uint8 support,
  244. uint256 weight
  245. ) internal virtual override {
  246. ProposalDetails storage details = _proposalDetails[proposalId];
  247. Receipt storage receipt = details.receipts[account];
  248. require(!receipt.hasVoted, "GovernorCompatibilityBravo: vote already cast");
  249. receipt.hasVoted = true;
  250. receipt.support = support;
  251. receipt.votes = SafeCastUpgradeable.toUint96(weight);
  252. if (support == uint8(VoteType.Against)) {
  253. details.againstVotes += weight;
  254. } else if (support == uint8(VoteType.For)) {
  255. details.forVotes += weight;
  256. } else if (support == uint8(VoteType.Abstain)) {
  257. details.abstainVotes += weight;
  258. } else {
  259. revert("GovernorCompatibilityBravo: invalid vote type");
  260. }
  261. }
  262. /**
  263. * This empty reserved space is put in place to allow future versions to add new
  264. * variables without shifting down storage in the inheritance chain.
  265. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
  266. */
  267. uint256[49] private __gap;
  268. }