diff --git a/.circleci/config.yml b/.circleci/config.yml index 163fd5016..041715c77 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -11,7 +11,7 @@ jobs: steps: - run: | - sudo wget https://github.com/ethereum/solidity/releases/download/v0.8.10/solc-static-linux -O /usr/local/bin/solc + sudo wget https://github.com/ethereum/solidity/releases/download/v0.8.15/solc-static-linux -O /usr/local/bin/solc sudo chmod +x /usr/local/bin/solc - checkout - restore_cache: @@ -79,7 +79,7 @@ jobs: steps: - run: | - sudo wget https://github.com/ethereum/solidity/releases/download/v0.8.10/solc-static-linux -O /usr/local/bin/solc + sudo wget https://github.com/ethereum/solidity/releases/download/v0.8.15/solc-static-linux -O /usr/local/bin/solc sudo chmod +x /usr/local/bin/solc - checkout - restore_cache: diff --git a/Dockerfile b/Dockerfile index 0f8cd2a1e..8d655777d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ FROM mhart/alpine-node:13.8.0 RUN apk update && apk add --no-cache --virtual build-dependencies git python g++ make -RUN wget https://github.com/ethereum/solidity/releases/download/v0.8.10/solc-static-linux -O /bin/solc && chmod +x /bin/solc +RUN wget https://github.com/ethereum/solidity/releases/download/v0.8.15/solc-static-linux -O /bin/solc && chmod +x /bin/solc RUN mkdir -p /compound-protocol WORKDIR /compound-protocol diff --git a/contracts/BaseJumpRateModelV2.sol b/contracts/BaseJumpRateModelV2.sol index 4d6828c39..e6d588071 100644 --- a/contracts/BaseJumpRateModelV2.sol +++ b/contracts/BaseJumpRateModelV2.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "./InterestRateModel.sol"; diff --git a/contracts/CDaiDelegate.sol b/contracts/CDaiDelegate.sol index 423640c51..b2dcce8c5 100644 --- a/contracts/CDaiDelegate.sol +++ b/contracts/CDaiDelegate.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "./CErc20Delegate.sol"; diff --git a/contracts/CErc20.sol b/contracts/CErc20.sol index 940cc2638..1689ded2d 100644 --- a/contracts/CErc20.sol +++ b/contracts/CErc20.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "./CToken.sol"; diff --git a/contracts/CErc20Delegate.sol b/contracts/CErc20Delegate.sol index 2b09af7fa..5e5a758af 100644 --- a/contracts/CErc20Delegate.sol +++ b/contracts/CErc20Delegate.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "./CErc20.sol"; diff --git a/contracts/CErc20Delegator.sol b/contracts/CErc20Delegator.sol index ecc0d883e..8d9a6c2dc 100644 --- a/contracts/CErc20Delegator.sol +++ b/contracts/CErc20Delegator.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "./CTokenInterfaces.sol"; diff --git a/contracts/CErc20Immutable.sol b/contracts/CErc20Immutable.sol index 0782db629..ff82d997f 100644 --- a/contracts/CErc20Immutable.sol +++ b/contracts/CErc20Immutable.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "./CErc20.sol"; diff --git a/contracts/CEther.sol b/contracts/CEther.sol index 183eb2935..b088c2616 100644 --- a/contracts/CEther.sol +++ b/contracts/CEther.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "./CToken.sol"; diff --git a/contracts/CToken.sol b/contracts/CToken.sol index b8c878c79..9a75738e0 100644 --- a/contracts/CToken.sol +++ b/contracts/CToken.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "./ComptrollerInterface.sol"; import "./CTokenInterfaces.sol"; diff --git a/contracts/CTokenInterfaces.sol b/contracts/CTokenInterfaces.sol index ba8d69a00..ec2043817 100644 --- a/contracts/CTokenInterfaces.sol +++ b/contracts/CTokenInterfaces.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "./ComptrollerInterface.sol"; import "./InterestRateModel.sol"; diff --git a/contracts/Comptroller.sol b/contracts/Comptroller.sol index 1d94cc756..98599a3c0 100644 --- a/contracts/Comptroller.sol +++ b/contracts/Comptroller.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "./CToken.sol"; import "./ErrorReporter.sol"; diff --git a/contracts/ComptrollerG7.sol b/contracts/ComptrollerG7.sol index 15ab1f953..6cae0a77b 100644 --- a/contracts/ComptrollerG7.sol +++ b/contracts/ComptrollerG7.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "./CToken.sol"; import "./ErrorReporter.sol"; diff --git a/contracts/ComptrollerInterface.sol b/contracts/ComptrollerInterface.sol index 8d60a336d..a9aeb83b8 100644 --- a/contracts/ComptrollerInterface.sol +++ b/contracts/ComptrollerInterface.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; abstract contract ComptrollerInterface { /// @notice Indicator that this is a Comptroller contract (for inspection) diff --git a/contracts/ComptrollerStorage.sol b/contracts/ComptrollerStorage.sol index 0455598ef..7a178b6c9 100644 --- a/contracts/ComptrollerStorage.sol +++ b/contracts/ComptrollerStorage.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "./CToken.sol"; import "./PriceOracle.sol"; diff --git a/contracts/DAIInterestRateModelV3.sol b/contracts/DAIInterestRateModelV3.sol index d78f18d1f..423bbc0db 100644 --- a/contracts/DAIInterestRateModelV3.sol +++ b/contracts/DAIInterestRateModelV3.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "./JumpRateModelV2.sol"; @@ -66,7 +66,7 @@ contract DAIInterestRateModelV3 is JumpRateModelV2 { * @param reserveFactorMantissa The current reserve factor the market has * @return The supply rate per block (as a percentage, and scaled by BASE) */ - function getSupplyRate(uint cash, uint borrows, uint reserves, uint reserveFactorMantissa) override public view returns (uint) { + function getSupplyRate(uint cash, uint borrows, uint reserves, uint reserveFactorMantissa) override(InterestRateModel, BaseJumpRateModelV2) public view returns (uint) { uint protocolRate = super.getSupplyRate(cash, borrows, reserves, reserveFactorMantissa); uint underlying = cash + borrows - reserves; diff --git a/contracts/EIP20Interface.sol b/contracts/EIP20Interface.sol index b35fd1e4d..363fb893f 100644 --- a/contracts/EIP20Interface.sol +++ b/contracts/EIP20Interface.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; /** * @title ERC 20 Token Standard Interface diff --git a/contracts/EIP20NonStandardInterface.sol b/contracts/EIP20NonStandardInterface.sol index 54602f966..9c1f76e86 100644 --- a/contracts/EIP20NonStandardInterface.sol +++ b/contracts/EIP20NonStandardInterface.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; /** * @title EIP20NonStandardInterface diff --git a/contracts/ErrorReporter.sol b/contracts/ErrorReporter.sol index 928ea0ed1..11544e0a2 100644 --- a/contracts/ErrorReporter.sol +++ b/contracts/ErrorReporter.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; contract ComptrollerErrorReporter { enum Error { diff --git a/contracts/ExponentialNoError.sol b/contracts/ExponentialNoError.sol index 23f833760..5ea3e8392 100644 --- a/contracts/ExponentialNoError.sol +++ b/contracts/ExponentialNoError.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; /** * @title Exponential module for storing fixed-precision decimals diff --git a/contracts/Governance/Comp.sol b/contracts/Governance/Comp.sol index 4d3228baf..26dd6bb67 100644 --- a/contracts/Governance/Comp.sol +++ b/contracts/Governance/Comp.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; contract Comp { /// @notice EIP-20 token name for this token diff --git a/contracts/Governance/GovernorAlpha.sol b/contracts/Governance/GovernorAlpha.sol index f1436f76e..7a6c36d6a 100644 --- a/contracts/Governance/GovernorAlpha.sol +++ b/contracts/Governance/GovernorAlpha.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; contract GovernorAlpha { /// @notice The name of this contract diff --git a/contracts/Governance/GovernorBravoDelegate.sol b/contracts/Governance/GovernorBravoDelegate.sol index e2496310f..5e14b71e4 100644 --- a/contracts/Governance/GovernorBravoDelegate.sol +++ b/contracts/Governance/GovernorBravoDelegate.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "./GovernorBravoInterfaces.sol"; diff --git a/contracts/Governance/GovernorBravoDelegateG1.sol b/contracts/Governance/GovernorBravoDelegateG1.sol index 63aebfb5b..65af7a042 100644 --- a/contracts/Governance/GovernorBravoDelegateG1.sol +++ b/contracts/Governance/GovernorBravoDelegateG1.sol @@ -1,10 +1,13 @@ -pragma solidity ^0.8.10; +// SPDX-License-Identifier: BSD-3-Clause +pragma solidity ^0.8.15; pragma experimental ABIEncoderV2; import "./GovernorBravoInterfaces.sol"; -contract GovernorBravoDelegate is GovernorBravoDelegateStorageV1, GovernorBravoEvents { - +contract GovernorBravoDelegate is + GovernorBravoDelegateStorageV1, + GovernorBravoEvents +{ /// @notice The name of this contract string public constant name = "Compound Governor Bravo"; @@ -33,27 +36,58 @@ contract GovernorBravoDelegate is GovernorBravoDelegateStorageV1, GovernorBravoE uint public constant proposalMaxOperations = 10; // 10 actions /// @notice The EIP-712 typehash for the contract's domain - bytes32 public constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)"); + bytes32 public constant DOMAIN_TYPEHASH = + keccak256( + "EIP712Domain(string name,uint256 chainId,address verifyingContract)" + ); /// @notice The EIP-712 typehash for the ballot struct used by the contract - bytes32 public constant BALLOT_TYPEHASH = keccak256("Ballot(uint256 proposalId,uint8 support)"); + bytes32 public constant BALLOT_TYPEHASH = + keccak256("Ballot(uint256 proposalId,uint8 support)"); /** - * @notice Used to initialize the contract during delegator constructor - * @param timelock_ The address of the Timelock - * @param comp_ The address of the COMP token - * @param votingPeriod_ The initial voting period - * @param votingDelay_ The initial voting delay - * @param proposalThreshold_ The initial proposal threshold - */ - function initialize(address timelock_, address comp_, uint votingPeriod_, uint votingDelay_, uint proposalThreshold_) public { - require(address(timelock) == address(0), "GovernorBravo::initialize: can only initialize once"); + * @notice Used to initialize the contract during delegator constructor + * @param timelock_ The address of the Timelock + * @param comp_ The address of the COMP token + * @param votingPeriod_ The initial voting period + * @param votingDelay_ The initial voting delay + * @param proposalThreshold_ The initial proposal threshold + */ + function initialize( + address timelock_, + address comp_, + uint votingPeriod_, + uint votingDelay_, + uint proposalThreshold_ + ) public { + require( + address(timelock) == address(0), + "GovernorBravo::initialize: can only initialize once" + ); require(msg.sender == admin, "GovernorBravo::initialize: admin only"); - require(timelock_ != address(0), "GovernorBravo::initialize: invalid timelock address"); - require(comp_ != address(0), "GovernorBravo::initialize: invalid comp address"); - require(votingPeriod_ >= MIN_VOTING_PERIOD && votingPeriod_ <= MAX_VOTING_PERIOD, "GovernorBravo::initialize: invalid voting period"); - require(votingDelay_ >= MIN_VOTING_DELAY && votingDelay_ <= MAX_VOTING_DELAY, "GovernorBravo::initialize: invalid voting delay"); - require(proposalThreshold_ >= MIN_PROPOSAL_THRESHOLD && proposalThreshold_ <= MAX_PROPOSAL_THRESHOLD, "GovernorBravo::initialize: invalid proposal threshold"); + require( + timelock_ != address(0), + "GovernorBravo::initialize: invalid timelock address" + ); + require( + comp_ != address(0), + "GovernorBravo::initialize: invalid comp address" + ); + require( + votingPeriod_ >= MIN_VOTING_PERIOD && + votingPeriod_ <= MAX_VOTING_PERIOD, + "GovernorBravo::initialize: invalid voting period" + ); + require( + votingDelay_ >= MIN_VOTING_DELAY && + votingDelay_ <= MAX_VOTING_DELAY, + "GovernorBravo::initialize: invalid voting delay" + ); + require( + proposalThreshold_ >= MIN_PROPOSAL_THRESHOLD && + proposalThreshold_ <= MAX_PROPOSAL_THRESHOLD, + "GovernorBravo::initialize: invalid proposal threshold" + ); timelock = TimelockInterface(timelock_); comp = CompInterface(comp_); @@ -63,27 +97,59 @@ contract GovernorBravoDelegate is GovernorBravoDelegateStorageV1, GovernorBravoE } /** - * @notice Function used to propose a new proposal. Sender must have delegates above the proposal threshold - * @param targets Target addresses for proposal calls - * @param values Eth values for proposal calls - * @param signatures Function signatures for proposal calls - * @param calldatas Calldatas for proposal calls - * @param description String description of the proposal - * @return Proposal id of new proposal - */ - function propose(address[] memory targets, uint[] memory values, string[] memory signatures, bytes[] memory calldatas, string memory description) public returns (uint) { + * @notice Function used to propose a new proposal. Sender must have delegates above the proposal threshold + * @param targets Target addresses for proposal calls + * @param values Eth values for proposal calls + * @param signatures Function signatures for proposal calls + * @param calldatas Calldatas for proposal calls + * @param description String description of the proposal + * @return Proposal id of new proposal + */ + function propose( + address[] memory targets, + uint[] memory values, + string[] memory signatures, + bytes[] memory calldatas, + string memory description + ) public returns (uint) { // Reject proposals before initiating as Governor - require(initialProposalId != 0, "GovernorBravo::propose: Governor Bravo not active"); - require(comp.getPriorVotes(msg.sender, sub256(block.number, 1)) > proposalThreshold, "GovernorBravo::propose: proposer votes below proposal threshold"); - require(targets.length == values.length && targets.length == signatures.length && targets.length == calldatas.length, "GovernorBravo::propose: proposal function information arity mismatch"); - require(targets.length != 0, "GovernorBravo::propose: must provide actions"); - require(targets.length <= proposalMaxOperations, "GovernorBravo::propose: too many actions"); + require( + initialProposalId != 0, + "GovernorBravo::propose: Governor Bravo not active" + ); + require( + comp.getPriorVotes(msg.sender, sub256(block.number, 1)) > + proposalThreshold, + "GovernorBravo::propose: proposer votes below proposal threshold" + ); + require( + targets.length == values.length && + targets.length == signatures.length && + targets.length == calldatas.length, + "GovernorBravo::propose: proposal function information arity mismatch" + ); + require( + targets.length != 0, + "GovernorBravo::propose: must provide actions" + ); + require( + targets.length <= proposalMaxOperations, + "GovernorBravo::propose: too many actions" + ); uint latestProposalId = latestProposalIds[msg.sender]; if (latestProposalId != 0) { - ProposalState proposersLatestProposalState = state(latestProposalId); - require(proposersLatestProposalState != ProposalState.Active, "GovernorBravo::propose: one live proposal per proposer, found an already active proposal"); - require(proposersLatestProposalState != ProposalState.Pending, "GovernorBravo::propose: one live proposal per proposer, found an already pending proposal"); + ProposalState proposersLatestProposalState = state( + latestProposalId + ); + require( + proposersLatestProposalState != ProposalState.Active, + "GovernorBravo::propose: one live proposal per proposer, found an already active proposal" + ); + require( + proposersLatestProposalState != ProposalState.Pending, + "GovernorBravo::propose: one live proposal per proposer, found an already pending proposal" + ); } uint startBlock = add256(block.number, votingDelay); @@ -92,7 +158,10 @@ contract GovernorBravoDelegate is GovernorBravoDelegateStorageV1, GovernorBravoE proposalCount++; Proposal storage newProposal = proposals[proposalCount]; // This should never happen but add a check in case. - require(newProposal.id == 0, "GovernorBravo::propose: ProposalID collsion"); + require( + newProposal.id == 0, + "GovernorBravo::propose: ProposalID collsion" + ); newProposal.id = proposalCount; newProposal.proposer = msg.sender; newProposal.eta = 0; @@ -110,92 +179,161 @@ contract GovernorBravoDelegate is GovernorBravoDelegateStorageV1, GovernorBravoE latestProposalIds[newProposal.proposer] = newProposal.id; - emit ProposalCreated(newProposal.id, msg.sender, targets, values, signatures, calldatas, startBlock, endBlock, description); + emit ProposalCreated( + newProposal.id, + msg.sender, + targets, + values, + signatures, + calldatas, + startBlock, + endBlock, + description + ); return newProposal.id; } /** - * @notice Queues a proposal of state succeeded - * @param proposalId The id of the proposal to queue - */ + * @notice Queues a proposal of state succeeded + * @param proposalId The id of the proposal to queue + */ function queue(uint proposalId) external { - require(state(proposalId) == ProposalState.Succeeded, "GovernorBravo::queue: proposal can only be queued if it is succeeded"); + require( + state(proposalId) == ProposalState.Succeeded, + "GovernorBravo::queue: proposal can only be queued if it is succeeded" + ); Proposal storage proposal = proposals[proposalId]; uint eta = add256(block.timestamp, timelock.delay()); for (uint i = 0; i < proposal.targets.length; i++) { - queueOrRevertInternal(proposal.targets[i], proposal.values[i], proposal.signatures[i], proposal.calldatas[i], eta); + queueOrRevertInternal( + proposal.targets[i], + proposal.values[i], + proposal.signatures[i], + proposal.calldatas[i], + eta + ); } proposal.eta = eta; emit ProposalQueued(proposalId, eta); } - function queueOrRevertInternal(address target, uint value, string memory signature, bytes memory data, uint eta) internal { - require(!timelock.queuedTransactions(keccak256(abi.encode(target, value, signature, data, eta))), "GovernorBravo::queueOrRevertInternal: identical proposal action already queued at eta"); + function queueOrRevertInternal( + address target, + uint value, + string memory signature, + bytes memory data, + uint eta + ) internal { + require( + !timelock.queuedTransactions( + keccak256(abi.encode(target, value, signature, data, eta)) + ), + "GovernorBravo::queueOrRevertInternal: identical proposal action already queued at eta" + ); timelock.queueTransaction(target, value, signature, data, eta); } /** - * @notice Executes a queued proposal if eta has passed - * @param proposalId The id of the proposal to execute - */ + * @notice Executes a queued proposal if eta has passed + * @param proposalId The id of the proposal to execute + */ function execute(uint proposalId) external payable { - require(state(proposalId) == ProposalState.Queued, "GovernorBravo::execute: proposal can only be executed if it is queued"); + require( + state(proposalId) == ProposalState.Queued, + "GovernorBravo::execute: proposal can only be executed if it is queued" + ); Proposal storage proposal = proposals[proposalId]; proposal.executed = true; for (uint i = 0; i < proposal.targets.length; i++) { - timelock.executeTransaction{value: proposal.values[i]}(proposal.targets[i], proposal.values[i], proposal.signatures[i], proposal.calldatas[i], proposal.eta); + timelock.executeTransaction{value: proposal.values[i]}( + proposal.targets[i], + proposal.values[i], + proposal.signatures[i], + proposal.calldatas[i], + proposal.eta + ); } emit ProposalExecuted(proposalId); } /** - * @notice Cancels a proposal only if sender is the proposer, or proposer delegates dropped below proposal threshold - * @param proposalId The id of the proposal to cancel - */ + * @notice Cancels a proposal only if sender is the proposer, or proposer delegates dropped below proposal threshold + * @param proposalId The id of the proposal to cancel + */ function cancel(uint proposalId) external { - require(state(proposalId) != ProposalState.Executed, "GovernorBravo::cancel: cannot cancel executed proposal"); + require( + state(proposalId) != ProposalState.Executed, + "GovernorBravo::cancel: cannot cancel executed proposal" + ); Proposal storage proposal = proposals[proposalId]; - require(msg.sender == proposal.proposer || comp.getPriorVotes(proposal.proposer, sub256(block.number, 1)) < proposalThreshold, "GovernorBravo::cancel: proposer above threshold"); + require( + msg.sender == proposal.proposer || + comp.getPriorVotes(proposal.proposer, sub256(block.number, 1)) < + proposalThreshold, + "GovernorBravo::cancel: proposer above threshold" + ); proposal.canceled = true; for (uint i = 0; i < proposal.targets.length; i++) { - timelock.cancelTransaction(proposal.targets[i], proposal.values[i], proposal.signatures[i], proposal.calldatas[i], proposal.eta); + timelock.cancelTransaction( + proposal.targets[i], + proposal.values[i], + proposal.signatures[i], + proposal.calldatas[i], + proposal.eta + ); } emit ProposalCanceled(proposalId); } /** - * @notice Gets actions of a proposal - * @param proposalId the id of the proposal - * @return targets of the proposal actions - * @return values of the proposal actions - * @return signatures of the proposal actions - * @return calldatas of the proposal actions - */ - function getActions(uint proposalId) external view returns (address[] memory targets, uint[] memory values, string[] memory signatures, bytes[] memory calldatas) { + * @notice Gets actions of a proposal + * @param proposalId the id of the proposal + * @return targets of the proposal actions + * @return values of the proposal actions + * @return signatures of the proposal actions + * @return calldatas of the proposal actions + */ + function getActions(uint proposalId) + external + view + returns ( + address[] memory targets, + uint[] memory values, + string[] memory signatures, + bytes[] memory calldatas + ) + { Proposal storage p = proposals[proposalId]; return (p.targets, p.values, p.signatures, p.calldatas); } /** - * @notice Gets the receipt for a voter on a given proposal - * @param proposalId the id of proposal - * @param voter The address of the voter - * @return The voting receipt - */ - function getReceipt(uint proposalId, address voter) external view returns (Receipt memory) { + * @notice Gets the receipt for a voter on a given proposal + * @param proposalId the id of proposal + * @param voter The address of the voter + * @return The voting receipt + */ + function getReceipt(uint proposalId, address voter) + external + view + returns (Receipt memory) + { return proposals[proposalId].receipts[voter]; } /** - * @notice Gets the state of a proposal - * @param proposalId The id of the proposal - * @return Proposal state - */ + * @notice Gets the state of a proposal + * @param proposalId The id of the proposal + * @return Proposal state + */ function state(uint proposalId) public view returns (ProposalState) { - require(proposalCount >= proposalId && proposalId > initialProposalId, "GovernorBravo::state: invalid proposal id"); + require( + proposalCount >= proposalId && proposalId > initialProposalId, + "GovernorBravo::state: invalid proposal id" + ); Proposal storage proposal = proposals[proposalId]; if (proposal.canceled) { return ProposalState.Canceled; @@ -203,13 +341,18 @@ contract GovernorBravoDelegate is GovernorBravoDelegateStorageV1, GovernorBravoE return ProposalState.Pending; } else if (block.number <= proposal.endBlock) { return ProposalState.Active; - } else if (proposal.forVotes <= proposal.againstVotes || proposal.forVotes < quorumVotes) { + } else if ( + proposal.forVotes <= proposal.againstVotes || + proposal.forVotes < quorumVotes + ) { return ProposalState.Defeated; } else if (proposal.eta == 0) { return ProposalState.Succeeded; } else if (proposal.executed) { return ProposalState.Executed; - } else if (block.timestamp >= add256(proposal.eta, timelock.GRACE_PERIOD())) { + } else if ( + block.timestamp >= add256(proposal.eta, timelock.GRACE_PERIOD()) + ) { return ProposalState.Expired; } else { return ProposalState.Queued; @@ -217,50 +360,105 @@ contract GovernorBravoDelegate is GovernorBravoDelegateStorageV1, GovernorBravoE } /** - * @notice Cast a vote for a proposal - * @param proposalId The id of the proposal to vote on - * @param support The support value for the vote. 0=against, 1=for, 2=abstain - */ + * @notice Cast a vote for a proposal + * @param proposalId The id of the proposal to vote on + * @param support The support value for the vote. 0=against, 1=for, 2=abstain + */ function castVote(uint proposalId, uint8 support) external { - emit VoteCast(msg.sender, proposalId, support, castVoteInternal(msg.sender, proposalId, support), ""); + emit VoteCast( + msg.sender, + proposalId, + support, + castVoteInternal(msg.sender, proposalId, support), + "" + ); } /** - * @notice Cast a vote for a proposal with a reason - * @param proposalId The id of the proposal to vote on - * @param support The support value for the vote. 0=against, 1=for, 2=abstain - * @param reason The reason given for the vote by the voter - */ - function castVoteWithReason(uint proposalId, uint8 support, string calldata reason) external { - emit VoteCast(msg.sender, proposalId, support, castVoteInternal(msg.sender, proposalId, support), reason); + * @notice Cast a vote for a proposal with a reason + * @param proposalId The id of the proposal to vote on + * @param support The support value for the vote. 0=against, 1=for, 2=abstain + * @param reason The reason given for the vote by the voter + */ + function castVoteWithReason( + uint proposalId, + uint8 support, + string calldata reason + ) external { + emit VoteCast( + msg.sender, + proposalId, + support, + castVoteInternal(msg.sender, proposalId, support), + reason + ); } /** - * @notice Cast a vote for a proposal by signature - * @dev External function that accepts EIP-712 signatures for voting on proposals. - */ - function castVoteBySig(uint proposalId, uint8 support, uint8 v, bytes32 r, bytes32 s) external { - bytes32 domainSeparator = keccak256(abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name)), getChainIdInternal(), address(this))); - bytes32 structHash = keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support)); - bytes32 digest = keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); + * @notice Cast a vote for a proposal by signature + * @dev External function that accepts EIP-712 signatures for voting on proposals. + */ + function castVoteBySig( + uint proposalId, + uint8 support, + uint8 v, + bytes32 r, + bytes32 s + ) external { + bytes32 domainSeparator = keccak256( + abi.encode( + DOMAIN_TYPEHASH, + keccak256(bytes(name)), + getChainIdInternal(), + address(this) + ) + ); + bytes32 structHash = keccak256( + abi.encode(BALLOT_TYPEHASH, proposalId, support) + ); + bytes32 digest = keccak256( + abi.encodePacked("\x19\x01", domainSeparator, structHash) + ); address signatory = ecrecover(digest, v, r, s); - require(signatory != address(0), "GovernorBravo::castVoteBySig: invalid signature"); - emit VoteCast(signatory, proposalId, support, castVoteInternal(signatory, proposalId, support), ""); + require( + signatory != address(0), + "GovernorBravo::castVoteBySig: invalid signature" + ); + emit VoteCast( + signatory, + proposalId, + support, + castVoteInternal(signatory, proposalId, support), + "" + ); } /** - * @notice Internal function that caries out voting logic - * @param voter The voter that is casting their vote - * @param proposalId The id of the proposal to vote on - * @param support The support value for the vote. 0=against, 1=for, 2=abstain - * @return The number of votes cast - */ - function castVoteInternal(address voter, uint proposalId, uint8 support) internal returns (uint96) { - require(state(proposalId) == ProposalState.Active, "GovernorBravo::castVoteInternal: voting is closed"); - require(support <= 2, "GovernorBravo::castVoteInternal: invalid vote type"); + * @notice Internal function that caries out voting logic + * @param voter The voter that is casting their vote + * @param proposalId The id of the proposal to vote on + * @param support The support value for the vote. 0=against, 1=for, 2=abstain + * @return The number of votes cast + */ + function castVoteInternal( + address voter, + uint proposalId, + uint8 support + ) internal returns (uint96) { + require( + state(proposalId) == ProposalState.Active, + "GovernorBravo::castVoteInternal: voting is closed" + ); + require( + support <= 2, + "GovernorBravo::castVoteInternal: invalid vote type" + ); Proposal storage proposal = proposals[proposalId]; Receipt storage receipt = proposal.receipts[voter]; - require(receipt.hasVoted == false, "GovernorBravo::castVoteInternal: voter already voted"); + require( + receipt.hasVoted == false, + "GovernorBravo::castVoteInternal: voter already voted" + ); uint96 votes = comp.getPriorVotes(voter, proposal.startBlock); if (support == 0) { @@ -279,25 +477,39 @@ contract GovernorBravoDelegate is GovernorBravoDelegateStorageV1, GovernorBravoE } /** - * @notice Admin function for setting the voting delay - * @param newVotingDelay new voting delay, in blocks - */ + * @notice Admin function for setting the voting delay + * @param newVotingDelay new voting delay, in blocks + */ function _setVotingDelay(uint newVotingDelay) external { - require(msg.sender == admin, "GovernorBravo::_setVotingDelay: admin only"); - require(newVotingDelay >= MIN_VOTING_DELAY && newVotingDelay <= MAX_VOTING_DELAY, "GovernorBravo::_setVotingDelay: invalid voting delay"); + require( + msg.sender == admin, + "GovernorBravo::_setVotingDelay: admin only" + ); + require( + newVotingDelay >= MIN_VOTING_DELAY && + newVotingDelay <= MAX_VOTING_DELAY, + "GovernorBravo::_setVotingDelay: invalid voting delay" + ); uint oldVotingDelay = votingDelay; votingDelay = newVotingDelay; - emit VotingDelaySet(oldVotingDelay,votingDelay); + emit VotingDelaySet(oldVotingDelay, votingDelay); } /** - * @notice Admin function for setting the voting period - * @param newVotingPeriod new voting period, in blocks - */ + * @notice Admin function for setting the voting period + * @param newVotingPeriod new voting period, in blocks + */ function _setVotingPeriod(uint newVotingPeriod) external { - require(msg.sender == admin, "GovernorBravo::_setVotingPeriod: admin only"); - require(newVotingPeriod >= MIN_VOTING_PERIOD && newVotingPeriod <= MAX_VOTING_PERIOD, "GovernorBravo::_setVotingPeriod: invalid voting period"); + require( + msg.sender == admin, + "GovernorBravo::_setVotingPeriod: admin only" + ); + require( + newVotingPeriod >= MIN_VOTING_PERIOD && + newVotingPeriod <= MAX_VOTING_PERIOD, + "GovernorBravo::_setVotingPeriod: invalid voting period" + ); uint oldVotingPeriod = votingPeriod; votingPeriod = newVotingPeriod; @@ -305,13 +517,20 @@ contract GovernorBravoDelegate is GovernorBravoDelegateStorageV1, GovernorBravoE } /** - * @notice Admin function for setting the proposal threshold - * @dev newProposalThreshold must be greater than the hardcoded min - * @param newProposalThreshold new proposal threshold - */ + * @notice Admin function for setting the proposal threshold + * @dev newProposalThreshold must be greater than the hardcoded min + * @param newProposalThreshold new proposal threshold + */ function _setProposalThreshold(uint newProposalThreshold) external { - require(msg.sender == admin, "GovernorBravo::_setProposalThreshold: admin only"); - require(newProposalThreshold >= MIN_PROPOSAL_THRESHOLD && newProposalThreshold <= MAX_PROPOSAL_THRESHOLD, "GovernorBravo::_setProposalThreshold: invalid proposal threshold"); + require( + msg.sender == admin, + "GovernorBravo::_setProposalThreshold: admin only" + ); + require( + newProposalThreshold >= MIN_PROPOSAL_THRESHOLD && + newProposalThreshold <= MAX_PROPOSAL_THRESHOLD, + "GovernorBravo::_setProposalThreshold: invalid proposal threshold" + ); uint oldProposalThreshold = proposalThreshold; proposalThreshold = newProposalThreshold; @@ -319,26 +538,32 @@ contract GovernorBravoDelegate is GovernorBravoDelegateStorageV1, GovernorBravoE } /** - * @notice Initiate the GovernorBravo contract - * @dev Admin only. Sets initial proposal id which initiates the contract, ensuring a continuous proposal id count - * @param governorAlpha The address for the Governor to continue the proposal id count from - */ + * @notice Initiate the GovernorBravo contract + * @dev Admin only. Sets initial proposal id which initiates the contract, ensuring a continuous proposal id count + * @param governorAlpha The address for the Governor to continue the proposal id count from + */ function _initiate(address governorAlpha) external { require(msg.sender == admin, "GovernorBravo::_initiate: admin only"); - require(initialProposalId == 0, "GovernorBravo::_initiate: can only initiate once"); + require( + initialProposalId == 0, + "GovernorBravo::_initiate: can only initiate once" + ); proposalCount = GovernorAlpha(governorAlpha).proposalCount(); initialProposalId = proposalCount; timelock.acceptAdmin(); } /** - * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer. - * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer. - * @param newPendingAdmin New pending admin. - */ + * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer. + * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer. + * @param newPendingAdmin New pending admin. + */ function _setPendingAdmin(address newPendingAdmin) external { // Check caller = admin - require(msg.sender == admin, "GovernorBravo:_setPendingAdmin: admin only"); + require( + msg.sender == admin, + "GovernorBravo:_setPendingAdmin: admin only" + ); // Save current value, if any, for inclusion in log address oldPendingAdmin = pendingAdmin; @@ -351,12 +576,15 @@ contract GovernorBravoDelegate is GovernorBravoDelegateStorageV1, GovernorBravoE } /** - * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin - * @dev Admin function for pending admin to accept role and update admin - */ + * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin + * @dev Admin function for pending admin to accept role and update admin + */ function _acceptAdmin() external { // Check caller is pendingAdmin and pendingAdmin ≠ address(0) - require(msg.sender == pendingAdmin && msg.sender != address(0), "GovernorBravo:_acceptAdmin: pending admin only"); + require( + msg.sender == pendingAdmin && msg.sender != address(0), + "GovernorBravo:_acceptAdmin: pending admin only" + ); // Save current values for inclusion in log address oldAdmin = admin; @@ -385,7 +613,9 @@ contract GovernorBravoDelegate is GovernorBravoDelegateStorageV1, GovernorBravoE function getChainIdInternal() internal view returns (uint) { uint chainId; - assembly { chainId := chainid() } + assembly { + chainId := chainid() + } return chainId; } } diff --git a/contracts/Governance/GovernorBravoDelegateG2.sol b/contracts/Governance/GovernorBravoDelegateG2.sol index cc8ea398a..6d8df98a8 100644 --- a/contracts/Governance/GovernorBravoDelegateG2.sol +++ b/contracts/Governance/GovernorBravoDelegateG2.sol @@ -1,10 +1,13 @@ -pragma solidity ^0.5.16; +// SPDX-License-Identifier: BSD-3-Clause +pragma solidity ^0.8.15; pragma experimental ABIEncoderV2; import "./GovernorBravoInterfaces.sol"; -contract GovernorBravoDelegate is GovernorBravoDelegateStorageV2, GovernorBravoEvents { - +contract GovernorBravoDelegate is + GovernorBravoDelegateStorageV2, + GovernorBravoEvents +{ /// @notice The name of this contract string public constant name = "Compound Governor Bravo"; @@ -33,27 +36,58 @@ contract GovernorBravoDelegate is GovernorBravoDelegateStorageV2, GovernorBravoE uint public constant proposalMaxOperations = 10; // 10 actions /// @notice The EIP-712 typehash for the contract's domain - bytes32 public constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)"); + bytes32 public constant DOMAIN_TYPEHASH = + keccak256( + "EIP712Domain(string name,uint256 chainId,address verifyingContract)" + ); /// @notice The EIP-712 typehash for the ballot struct used by the contract - bytes32 public constant BALLOT_TYPEHASH = keccak256("Ballot(uint256 proposalId,uint8 support)"); + bytes32 public constant BALLOT_TYPEHASH = + keccak256("Ballot(uint256 proposalId,uint8 support)"); /** - * @notice Used to initialize the contract during delegator contructor - * @param timelock_ The address of the Timelock - * @param comp_ The address of the COMP token - * @param votingPeriod_ The initial voting period - * @param votingDelay_ The initial voting delay - * @param proposalThreshold_ The initial proposal threshold - */ - function initialize(address timelock_, address comp_, uint votingPeriod_, uint votingDelay_, uint proposalThreshold_) public { - require(address(timelock) == address(0), "GovernorBravo::initialize: can only initialize once"); + * @notice Used to initialize the contract during delegator constructor + * @param timelock_ The address of the Timelock + * @param comp_ The address of the COMP token + * @param votingPeriod_ The initial voting period + * @param votingDelay_ The initial voting delay + * @param proposalThreshold_ The initial proposal threshold + */ + function initialize( + address timelock_, + address comp_, + uint votingPeriod_, + uint votingDelay_, + uint proposalThreshold_ + ) public { + require( + address(timelock) == address(0), + "GovernorBravo::initialize: can only initialize once" + ); require(msg.sender == admin, "GovernorBravo::initialize: admin only"); - require(timelock_ != address(0), "GovernorBravo::initialize: invalid timelock address"); - require(comp_ != address(0), "GovernorBravo::initialize: invalid comp address"); - require(votingPeriod_ >= MIN_VOTING_PERIOD && votingPeriod_ <= MAX_VOTING_PERIOD, "GovernorBravo::initialize: invalid voting period"); - require(votingDelay_ >= MIN_VOTING_DELAY && votingDelay_ <= MAX_VOTING_DELAY, "GovernorBravo::initialize: invalid voting delay"); - require(proposalThreshold_ >= MIN_PROPOSAL_THRESHOLD && proposalThreshold_ <= MAX_PROPOSAL_THRESHOLD, "GovernorBravo::initialize: invalid proposal threshold"); + require( + timelock_ != address(0), + "GovernorBravo::initialize: invalid timelock address" + ); + require( + comp_ != address(0), + "GovernorBravo::initialize: invalid comp address" + ); + require( + votingPeriod_ >= MIN_VOTING_PERIOD && + votingPeriod_ <= MAX_VOTING_PERIOD, + "GovernorBravo::initialize: invalid voting period" + ); + require( + votingDelay_ >= MIN_VOTING_DELAY && + votingDelay_ <= MAX_VOTING_DELAY, + "GovernorBravo::initialize: invalid voting delay" + ); + require( + proposalThreshold_ >= MIN_PROPOSAL_THRESHOLD && + proposalThreshold_ <= MAX_PROPOSAL_THRESHOLD, + "GovernorBravo::initialize: invalid proposal threshold" + ); timelock = TimelockInterface(timelock_); comp = CompInterface(comp_); @@ -63,147 +97,261 @@ contract GovernorBravoDelegate is GovernorBravoDelegateStorageV2, GovernorBravoE } /** - * @notice Function used to propose a new proposal. Sender must have delegates above the proposal threshold - * @param targets Target addresses for proposal calls - * @param values Eth values for proposal calls - * @param signatures Function signatures for proposal calls - * @param calldatas Calldatas for proposal calls - * @param description String description of the proposal - * @return Proposal id of new proposal - */ - function propose(address[] memory targets, uint[] memory values, string[] memory signatures, bytes[] memory calldatas, string memory description) public returns (uint) { + * @notice Function used to propose a new proposal. Sender must have delegates above the proposal threshold + * @param targets Target addresses for proposal calls + * @param values Eth values for proposal calls + * @param signatures Function signatures for proposal calls + * @param calldatas Calldatas for proposal calls + * @param description String description of the proposal + * @return Proposal id of new proposal + */ + function propose( + address[] memory targets, + uint[] memory values, + string[] memory signatures, + bytes[] memory calldatas, + string memory description + ) public returns (uint) { // Reject proposals before initiating as Governor - require(initialProposalId != 0, "GovernorBravo::propose: Governor Bravo not active"); + require( + initialProposalId != 0, + "GovernorBravo::propose: Governor Bravo not active" + ); // Allow addresses above proposal threshold and whitelisted addresses to propose - require(comp.getPriorVotes(msg.sender, sub256(block.number, 1)) > proposalThreshold || isWhitelisted(msg.sender), "GovernorBravo::propose: proposer votes below proposal threshold"); - require(targets.length == values.length && targets.length == signatures.length && targets.length == calldatas.length, "GovernorBravo::propose: proposal function information arity mismatch"); - require(targets.length != 0, "GovernorBravo::propose: must provide actions"); - require(targets.length <= proposalMaxOperations, "GovernorBravo::propose: too many actions"); + require( + comp.getPriorVotes(msg.sender, sub256(block.number, 1)) > + proposalThreshold || + isWhitelisted(msg.sender), + "GovernorBravo::propose: proposer votes below proposal threshold" + ); + require( + targets.length == values.length && + targets.length == signatures.length && + targets.length == calldatas.length, + "GovernorBravo::propose: proposal function information arity mismatch" + ); + require( + targets.length != 0, + "GovernorBravo::propose: must provide actions" + ); + require( + targets.length <= proposalMaxOperations, + "GovernorBravo::propose: too many actions" + ); uint latestProposalId = latestProposalIds[msg.sender]; if (latestProposalId != 0) { - ProposalState proposersLatestProposalState = state(latestProposalId); - require(proposersLatestProposalState != ProposalState.Active, "GovernorBravo::propose: one live proposal per proposer, found an already active proposal"); - require(proposersLatestProposalState != ProposalState.Pending, "GovernorBravo::propose: one live proposal per proposer, found an already pending proposal"); + ProposalState proposersLatestProposalState = state( + latestProposalId + ); + require( + proposersLatestProposalState != ProposalState.Active, + "GovernorBravo::propose: one live proposal per proposer, found an already active proposal" + ); + require( + proposersLatestProposalState != ProposalState.Pending, + "GovernorBravo::propose: one live proposal per proposer, found an already pending proposal" + ); } uint startBlock = add256(block.number, votingDelay); uint endBlock = add256(startBlock, votingPeriod); proposalCount++; - Proposal memory newProposal = Proposal({ - id: proposalCount, - proposer: msg.sender, - eta: 0, - targets: targets, - values: values, - signatures: signatures, - calldatas: calldatas, - startBlock: startBlock, - endBlock: endBlock, - forVotes: 0, - againstVotes: 0, - abstainVotes: 0, - canceled: false, - executed: false - }); - - proposals[newProposal.id] = newProposal; + Proposal storage newProposal = proposals[proposalCount]; + // This should never happen but add a check in case. + require( + newProposal.id == 0, + "GovernorBravo::propose: ProposalID collsion" + ); + newProposal.id = proposalCount; + newProposal.proposer = msg.sender; + newProposal.eta = 0; + newProposal.targets = targets; + newProposal.values = values; + newProposal.signatures = signatures; + newProposal.calldatas = calldatas; + newProposal.startBlock = startBlock; + newProposal.endBlock = endBlock; + newProposal.forVotes = 0; + newProposal.againstVotes = 0; + newProposal.abstainVotes = 0; + newProposal.canceled = false; + newProposal.executed = false; + latestProposalIds[newProposal.proposer] = newProposal.id; - emit ProposalCreated(newProposal.id, msg.sender, targets, values, signatures, calldatas, startBlock, endBlock, description); + emit ProposalCreated( + newProposal.id, + msg.sender, + targets, + values, + signatures, + calldatas, + startBlock, + endBlock, + description + ); return newProposal.id; } /** - * @notice Queues a proposal of state succeeded - * @param proposalId The id of the proposal to queue - */ + * @notice Queues a proposal of state succeeded + * @param proposalId The id of the proposal to queue + */ function queue(uint proposalId) external { - require(state(proposalId) == ProposalState.Succeeded, "GovernorBravo::queue: proposal can only be queued if it is succeeded"); + require( + state(proposalId) == ProposalState.Succeeded, + "GovernorBravo::queue: proposal can only be queued if it is succeeded" + ); Proposal storage proposal = proposals[proposalId]; uint eta = add256(block.timestamp, timelock.delay()); for (uint i = 0; i < proposal.targets.length; i++) { - queueOrRevertInternal(proposal.targets[i], proposal.values[i], proposal.signatures[i], proposal.calldatas[i], eta); + queueOrRevertInternal( + proposal.targets[i], + proposal.values[i], + proposal.signatures[i], + proposal.calldatas[i], + eta + ); } proposal.eta = eta; emit ProposalQueued(proposalId, eta); } - function queueOrRevertInternal(address target, uint value, string memory signature, bytes memory data, uint eta) internal { - require(!timelock.queuedTransactions(keccak256(abi.encode(target, value, signature, data, eta))), "GovernorBravo::queueOrRevertInternal: identical proposal action already queued at eta"); + function queueOrRevertInternal( + address target, + uint value, + string memory signature, + bytes memory data, + uint eta + ) internal { + require( + !timelock.queuedTransactions( + keccak256(abi.encode(target, value, signature, data, eta)) + ), + "GovernorBravo::queueOrRevertInternal: identical proposal action already queued at eta" + ); timelock.queueTransaction(target, value, signature, data, eta); } /** - * @notice Executes a queued proposal if eta has passed - * @param proposalId The id of the proposal to execute - */ + * @notice Executes a queued proposal if eta has passed + * @param proposalId The id of the proposal to execute + */ function execute(uint proposalId) external payable { - require(state(proposalId) == ProposalState.Queued, "GovernorBravo::execute: proposal can only be executed if it is queued"); + require( + state(proposalId) == ProposalState.Queued, + "GovernorBravo::execute: proposal can only be executed if it is queued" + ); Proposal storage proposal = proposals[proposalId]; proposal.executed = true; for (uint i = 0; i < proposal.targets.length; i++) { - timelock.executeTransaction.value(proposal.values[i])(proposal.targets[i], proposal.values[i], proposal.signatures[i], proposal.calldatas[i], proposal.eta); + timelock.executeTransaction{value: proposal.values[i]}( + proposal.targets[i], + proposal.values[i], + proposal.signatures[i], + proposal.calldatas[i], + proposal.eta + ); } emit ProposalExecuted(proposalId); } /** - * @notice Cancels a proposal only if sender is the proposer, or proposer delegates dropped below proposal threshold - * @param proposalId The id of the proposal to cancel - */ + * @notice Cancels a proposal only if sender is the proposer, or proposer delegates dropped below proposal threshold + * @param proposalId The id of the proposal to cancel + */ function cancel(uint proposalId) external { - require(state(proposalId) != ProposalState.Executed, "GovernorBravo::cancel: cannot cancel executed proposal"); + require( + state(proposalId) != ProposalState.Executed, + "GovernorBravo::cancel: cannot cancel executed proposal" + ); Proposal storage proposal = proposals[proposalId]; // Proposer can cancel - if(msg.sender != proposal.proposer) { + if (msg.sender != proposal.proposer) { // Whitelisted proposers can't be canceled for falling below proposal threshold - if(isWhitelisted(proposal.proposer)) { - require((comp.getPriorVotes(proposal.proposer, sub256(block.number, 1)) < proposalThreshold) && msg.sender == whitelistGuardian, "GovernorBravo::cancel: whitelisted proposer"); - } - else { - require((comp.getPriorVotes(proposal.proposer, sub256(block.number, 1)) < proposalThreshold), "GovernorBravo::cancel: proposer above threshold"); + if (isWhitelisted(proposal.proposer)) { + require( + (comp.getPriorVotes( + proposal.proposer, + sub256(block.number, 1) + ) < proposalThreshold) && msg.sender == whitelistGuardian, + "GovernorBravo::cancel: whitelisted proposer" + ); + } else { + require( + (comp.getPriorVotes( + proposal.proposer, + sub256(block.number, 1) + ) < proposalThreshold), + "GovernorBravo::cancel: proposer above threshold" + ); } } - + proposal.canceled = true; for (uint i = 0; i < proposal.targets.length; i++) { - timelock.cancelTransaction(proposal.targets[i], proposal.values[i], proposal.signatures[i], proposal.calldatas[i], proposal.eta); + timelock.cancelTransaction( + proposal.targets[i], + proposal.values[i], + proposal.signatures[i], + proposal.calldatas[i], + proposal.eta + ); } emit ProposalCanceled(proposalId); } /** - * @notice Gets actions of a proposal - * @param proposalId the id of the proposal - * @return Targets, values, signatures, and calldatas of the proposal actions - */ - function getActions(uint proposalId) external view returns (address[] memory targets, uint[] memory values, string[] memory signatures, bytes[] memory calldatas) { + * @notice Gets actions of a proposal + * @param proposalId the id of the proposal + * @return targets of the proposal actions + * @return values of the proposal actions + * @return signatures of the proposal actions + * @return calldatas of the proposal actions + */ + function getActions(uint proposalId) + external + view + returns ( + address[] memory targets, + uint[] memory values, + string[] memory signatures, + bytes[] memory calldatas + ) + { Proposal storage p = proposals[proposalId]; return (p.targets, p.values, p.signatures, p.calldatas); } /** - * @notice Gets the receipt for a voter on a given proposal - * @param proposalId the id of proposal - * @param voter The address of the voter - * @return The voting receipt - */ - function getReceipt(uint proposalId, address voter) external view returns (Receipt memory) { + * @notice Gets the receipt for a voter on a given proposal + * @param proposalId the id of proposal + * @param voter The address of the voter + * @return The voting receipt + */ + function getReceipt(uint proposalId, address voter) + external + view + returns (Receipt memory) + { return proposals[proposalId].receipts[voter]; } /** - * @notice Gets the state of a proposal - * @param proposalId The id of the proposal - * @return Proposal state - */ + * @notice Gets the state of a proposal + * @param proposalId The id of the proposal + * @return Proposal state + */ function state(uint proposalId) public view returns (ProposalState) { - require(proposalCount >= proposalId && proposalId > initialProposalId, "GovernorBravo::state: invalid proposal id"); + require( + proposalCount >= proposalId && proposalId > initialProposalId, + "GovernorBravo::state: invalid proposal id" + ); Proposal storage proposal = proposals[proposalId]; if (proposal.canceled) { return ProposalState.Canceled; @@ -211,13 +359,18 @@ contract GovernorBravoDelegate is GovernorBravoDelegateStorageV2, GovernorBravoE return ProposalState.Pending; } else if (block.number <= proposal.endBlock) { return ProposalState.Active; - } else if (proposal.forVotes <= proposal.againstVotes || proposal.forVotes < quorumVotes) { + } else if ( + proposal.forVotes <= proposal.againstVotes || + proposal.forVotes < quorumVotes + ) { return ProposalState.Defeated; } else if (proposal.eta == 0) { return ProposalState.Succeeded; } else if (proposal.executed) { return ProposalState.Executed; - } else if (block.timestamp >= add256(proposal.eta, timelock.GRACE_PERIOD())) { + } else if ( + block.timestamp >= add256(proposal.eta, timelock.GRACE_PERIOD()) + ) { return ProposalState.Expired; } else { return ProposalState.Queued; @@ -225,50 +378,105 @@ contract GovernorBravoDelegate is GovernorBravoDelegateStorageV2, GovernorBravoE } /** - * @notice Cast a vote for a proposal - * @param proposalId The id of the proposal to vote on - * @param support The support value for the vote. 0=against, 1=for, 2=abstain - */ + * @notice Cast a vote for a proposal + * @param proposalId The id of the proposal to vote on + * @param support The support value for the vote. 0=against, 1=for, 2=abstain + */ function castVote(uint proposalId, uint8 support) external { - emit VoteCast(msg.sender, proposalId, support, castVoteInternal(msg.sender, proposalId, support), ""); + emit VoteCast( + msg.sender, + proposalId, + support, + castVoteInternal(msg.sender, proposalId, support), + "" + ); } /** - * @notice Cast a vote for a proposal with a reason - * @param proposalId The id of the proposal to vote on - * @param support The support value for the vote. 0=against, 1=for, 2=abstain - * @param reason The reason given for the vote by the voter - */ - function castVoteWithReason(uint proposalId, uint8 support, string calldata reason) external { - emit VoteCast(msg.sender, proposalId, support, castVoteInternal(msg.sender, proposalId, support), reason); + * @notice Cast a vote for a proposal with a reason + * @param proposalId The id of the proposal to vote on + * @param support The support value for the vote. 0=against, 1=for, 2=abstain + * @param reason The reason given for the vote by the voter + */ + function castVoteWithReason( + uint proposalId, + uint8 support, + string calldata reason + ) external { + emit VoteCast( + msg.sender, + proposalId, + support, + castVoteInternal(msg.sender, proposalId, support), + reason + ); } /** - * @notice Cast a vote for a proposal by signature - * @dev External function that accepts EIP-712 signatures for voting on proposals. - */ - function castVoteBySig(uint proposalId, uint8 support, uint8 v, bytes32 r, bytes32 s) external { - bytes32 domainSeparator = keccak256(abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name)), getChainIdInternal(), address(this))); - bytes32 structHash = keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support)); - bytes32 digest = keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); + * @notice Cast a vote for a proposal by signature + * @dev External function that accepts EIP-712 signatures for voting on proposals. + */ + function castVoteBySig( + uint proposalId, + uint8 support, + uint8 v, + bytes32 r, + bytes32 s + ) external { + bytes32 domainSeparator = keccak256( + abi.encode( + DOMAIN_TYPEHASH, + keccak256(bytes(name)), + getChainIdInternal(), + address(this) + ) + ); + bytes32 structHash = keccak256( + abi.encode(BALLOT_TYPEHASH, proposalId, support) + ); + bytes32 digest = keccak256( + abi.encodePacked("\x19\x01", domainSeparator, structHash) + ); address signatory = ecrecover(digest, v, r, s); - require(signatory != address(0), "GovernorBravo::castVoteBySig: invalid signature"); - emit VoteCast(signatory, proposalId, support, castVoteInternal(signatory, proposalId, support), ""); + require( + signatory != address(0), + "GovernorBravo::castVoteBySig: invalid signature" + ); + emit VoteCast( + signatory, + proposalId, + support, + castVoteInternal(signatory, proposalId, support), + "" + ); } /** - * @notice Internal function that caries out voting logic - * @param voter The voter that is casting their vote - * @param proposalId The id of the proposal to vote on - * @param support The support value for the vote. 0=against, 1=for, 2=abstain - * @return The number of votes cast - */ - function castVoteInternal(address voter, uint proposalId, uint8 support) internal returns (uint96) { - require(state(proposalId) == ProposalState.Active, "GovernorBravo::castVoteInternal: voting is closed"); - require(support <= 2, "GovernorBravo::castVoteInternal: invalid vote type"); + * @notice Internal function that caries out voting logic + * @param voter The voter that is casting their vote + * @param proposalId The id of the proposal to vote on + * @param support The support value for the vote. 0=against, 1=for, 2=abstain + * @return The number of votes cast + */ + function castVoteInternal( + address voter, + uint proposalId, + uint8 support + ) internal returns (uint96) { + require( + state(proposalId) == ProposalState.Active, + "GovernorBravo::castVoteInternal: voting is closed" + ); + require( + support <= 2, + "GovernorBravo::castVoteInternal: invalid vote type" + ); Proposal storage proposal = proposals[proposalId]; Receipt storage receipt = proposal.receipts[voter]; - require(receipt.hasVoted == false, "GovernorBravo::castVoteInternal: voter already voted"); + require( + receipt.hasVoted == false, + "GovernorBravo::castVoteInternal: voter already voted" + ); uint96 votes = comp.getPriorVotes(voter, proposal.startBlock); if (support == 0) { @@ -292,29 +500,51 @@ contract GovernorBravoDelegate is GovernorBravoDelegateStorageV2, GovernorBravoE * @return If the account is whitelisted */ function isWhitelisted(address account) public view returns (bool) { - return (whitelistAccountExpirations[account] > now); + uint currentBlockTimestamp = getBlockTimestamp(); + return (whitelistAccountExpirations[account] > currentBlockTimestamp); } /** - * @notice Admin function for setting the voting delay - * @param newVotingDelay new voting delay, in blocks - */ + * @dev Function to simply retrieve block timestamp + */ + function getBlockTimestamp() internal view returns (uint) { + return block.timestamp; + } + + /** + * @notice Admin function for setting the voting delay + * @param newVotingDelay new voting delay, in blocks + */ function _setVotingDelay(uint newVotingDelay) external { - require(msg.sender == admin, "GovernorBravo::_setVotingDelay: admin only"); - require(newVotingDelay >= MIN_VOTING_DELAY && newVotingDelay <= MAX_VOTING_DELAY, "GovernorBravo::_setVotingDelay: invalid voting delay"); + require( + msg.sender == admin, + "GovernorBravo::_setVotingDelay: admin only" + ); + require( + newVotingDelay >= MIN_VOTING_DELAY && + newVotingDelay <= MAX_VOTING_DELAY, + "GovernorBravo::_setVotingDelay: invalid voting delay" + ); uint oldVotingDelay = votingDelay; votingDelay = newVotingDelay; - emit VotingDelaySet(oldVotingDelay,votingDelay); + emit VotingDelaySet(oldVotingDelay, votingDelay); } /** - * @notice Admin function for setting the voting period - * @param newVotingPeriod new voting period, in blocks - */ + * @notice Admin function for setting the voting period + * @param newVotingPeriod new voting period, in blocks + */ function _setVotingPeriod(uint newVotingPeriod) external { - require(msg.sender == admin, "GovernorBravo::_setVotingPeriod: admin only"); - require(newVotingPeriod >= MIN_VOTING_PERIOD && newVotingPeriod <= MAX_VOTING_PERIOD, "GovernorBravo::_setVotingPeriod: invalid voting period"); + require( + msg.sender == admin, + "GovernorBravo::_setVotingPeriod: admin only" + ); + require( + newVotingPeriod >= MIN_VOTING_PERIOD && + newVotingPeriod <= MAX_VOTING_PERIOD, + "GovernorBravo::_setVotingPeriod: invalid voting period" + ); uint oldVotingPeriod = votingPeriod; votingPeriod = newVotingPeriod; @@ -322,13 +552,20 @@ contract GovernorBravoDelegate is GovernorBravoDelegateStorageV2, GovernorBravoE } /** - * @notice Admin function for setting the proposal threshold - * @dev newProposalThreshold must be greater than the hardcoded min - * @param newProposalThreshold new proposal threshold - */ + * @notice Admin function for setting the proposal threshold + * @dev newProposalThreshold must be greater than the hardcoded min + * @param newProposalThreshold new proposal threshold + */ function _setProposalThreshold(uint newProposalThreshold) external { - require(msg.sender == admin, "GovernorBravo::_setProposalThreshold: admin only"); - require(newProposalThreshold >= MIN_PROPOSAL_THRESHOLD && newProposalThreshold <= MAX_PROPOSAL_THRESHOLD, "GovernorBravo::_setProposalThreshold: invalid proposal threshold"); + require( + msg.sender == admin, + "GovernorBravo::_setProposalThreshold: admin only" + ); + require( + newProposalThreshold >= MIN_PROPOSAL_THRESHOLD && + newProposalThreshold <= MAX_PROPOSAL_THRESHOLD, + "GovernorBravo::_setProposalThreshold: invalid proposal threshold" + ); uint oldProposalThreshold = proposalThreshold; proposalThreshold = newProposalThreshold; @@ -340,8 +577,13 @@ contract GovernorBravoDelegate is GovernorBravoDelegateStorageV2, GovernorBravoE * @param account Account address to set whitelist expiration for * @param expiration Expiration for account whitelist status as timestamp (if now < expiration, whitelisted) */ - function _setWhitelistAccountExpiration(address account, uint expiration) external { - require(msg.sender == admin || msg.sender == whitelistGuardian, "GovernorBravo::_setWhitelistAccountExpiration: admin only"); + function _setWhitelistAccountExpiration(address account, uint expiration) + external + { + require( + msg.sender == admin || msg.sender == whitelistGuardian, + "GovernorBravo::_setWhitelistAccountExpiration: admin only" + ); whitelistAccountExpirations[account] = expiration; emit WhitelistAccountExpirationSet(account, expiration); @@ -351,35 +593,44 @@ contract GovernorBravoDelegate is GovernorBravoDelegateStorageV2, GovernorBravoE * @notice Admin function for setting the whitelistGuardian. WhitelistGuardian can cancel proposals from whitelisted addresses * @param account Account to set whitelistGuardian to (0x0 to remove whitelistGuardian) */ - function _setWhitelistGuardian(address account) external { - require(msg.sender == admin, "GovernorBravo::_setWhitelistGuardian: admin only"); + function _setWhitelistGuardian(address account) external { + require( + msg.sender == admin, + "GovernorBravo::_setWhitelistGuardian: admin only" + ); address oldGuardian = whitelistGuardian; whitelistGuardian = account; emit WhitelistGuardianSet(oldGuardian, whitelistGuardian); - } + } /** - * @notice Initiate the GovernorBravo contract - * @dev Admin only. Sets initial proposal id which initiates the contract, ensuring a continuous proposal id count - * @param governorAlpha The address for the Governor to continue the proposal id count from - */ + * @notice Initiate the GovernorBravo contract + * @dev Admin only. Sets initial proposal id which initiates the contract, ensuring a continuous proposal id count + * @param governorAlpha The address for the Governor to continue the proposal id count from + */ function _initiate(address governorAlpha) external { require(msg.sender == admin, "GovernorBravo::_initiate: admin only"); - require(initialProposalId == 0, "GovernorBravo::_initiate: can only initiate once"); + require( + initialProposalId == 0, + "GovernorBravo::_initiate: can only initiate once" + ); proposalCount = GovernorAlpha(governorAlpha).proposalCount(); initialProposalId = proposalCount; timelock.acceptAdmin(); } /** - * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer. - * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer. - * @param newPendingAdmin New pending admin. - */ + * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer. + * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer. + * @param newPendingAdmin New pending admin. + */ function _setPendingAdmin(address newPendingAdmin) external { // Check caller = admin - require(msg.sender == admin, "GovernorBravo:_setPendingAdmin: admin only"); + require( + msg.sender == admin, + "GovernorBravo:_setPendingAdmin: admin only" + ); // Save current value, if any, for inclusion in log address oldPendingAdmin = pendingAdmin; @@ -392,12 +643,15 @@ contract GovernorBravoDelegate is GovernorBravoDelegateStorageV2, GovernorBravoE } /** - * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin - * @dev Admin function for pending admin to accept role and update admin - */ + * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin + * @dev Admin function for pending admin to accept role and update admin + */ function _acceptAdmin() external { // Check caller is pendingAdmin and pendingAdmin ≠ address(0) - require(msg.sender == pendingAdmin && msg.sender != address(0), "GovernorBravo:_acceptAdmin: pending admin only"); + require( + msg.sender == pendingAdmin && msg.sender != address(0), + "GovernorBravo:_acceptAdmin: pending admin only" + ); // Save current values for inclusion in log address oldAdmin = admin; @@ -424,9 +678,11 @@ contract GovernorBravoDelegate is GovernorBravoDelegateStorageV2, GovernorBravoE return a - b; } - function getChainIdInternal() internal pure returns (uint) { + function getChainIdInternal() internal view returns (uint) { uint chainId; - assembly { chainId := chainid() } + assembly { + chainId := chainid() + } return chainId; } -} \ No newline at end of file +} diff --git a/contracts/Governance/GovernorBravoDelegator.sol b/contracts/Governance/GovernorBravoDelegator.sol index e18f817b9..1a6eb7fb8 100644 --- a/contracts/Governance/GovernorBravoDelegator.sol +++ b/contracts/Governance/GovernorBravoDelegator.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "./GovernorBravoInterfaces.sol"; diff --git a/contracts/Governance/GovernorBravoInterfaces.sol b/contracts/Governance/GovernorBravoInterfaces.sol index 0ea3f3cb7..b658ad703 100644 --- a/contracts/Governance/GovernorBravoInterfaces.sol +++ b/contracts/Governance/GovernorBravoInterfaces.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; contract GovernorBravoEvents { diff --git a/contracts/InterestRateModel.sol b/contracts/InterestRateModel.sol index e8319fc99..9877a7b9b 100644 --- a/contracts/InterestRateModel.sol +++ b/contracts/InterestRateModel.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; /** * @title Compound's InterestRateModel Interface diff --git a/contracts/JumpRateModel.sol b/contracts/JumpRateModel.sol index 214447582..79202a63a 100644 --- a/contracts/JumpRateModel.sol +++ b/contracts/JumpRateModel.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "./InterestRateModel.sol"; diff --git a/contracts/JumpRateModelV2.sol b/contracts/JumpRateModelV2.sol index 6a99c0e9a..539ee87a8 100644 --- a/contracts/JumpRateModelV2.sol +++ b/contracts/JumpRateModelV2.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "./BaseJumpRateModelV2.sol"; import "./InterestRateModel.sol"; diff --git a/contracts/Lens/CompoundLens.sol b/contracts/Lens/CompoundLens.sol index f7030948e..f53c75dab 100644 --- a/contracts/Lens/CompoundLens.sol +++ b/contracts/Lens/CompoundLens.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "../CErc20.sol"; import "../CToken.sol"; diff --git a/contracts/Maximillion.sol b/contracts/Maximillion.sol index 6819e8fa4..9836b3993 100644 --- a/contracts/Maximillion.sol +++ b/contracts/Maximillion.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "./CEther.sol"; diff --git a/contracts/PriceOracle.sol b/contracts/PriceOracle.sol index f58518061..9555e87b1 100644 --- a/contracts/PriceOracle.sol +++ b/contracts/PriceOracle.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "./CToken.sol"; diff --git a/contracts/Reservoir.sol b/contracts/Reservoir.sol index 9bf7784d3..7d759ea69 100644 --- a/contracts/Reservoir.sol +++ b/contracts/Reservoir.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; /** * @title Reservoir Contract diff --git a/contracts/SafeMath.sol b/contracts/SafeMath.sol index ed474c7c3..fa5e2a1ef 100644 --- a/contracts/SafeMath.sol +++ b/contracts/SafeMath.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; // From https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/math/Math.sol // Subject to the MIT license. diff --git a/contracts/SimplePriceOracle.sol b/contracts/SimplePriceOracle.sol index 10b1d576f..86cd2b56c 100644 --- a/contracts/SimplePriceOracle.sol +++ b/contracts/SimplePriceOracle.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "./PriceOracle.sol"; import "./CErc20.sol"; diff --git a/contracts/Timelock.sol b/contracts/Timelock.sol index 69dcf3c1c..d8d64948a 100644 --- a/contracts/Timelock.sol +++ b/contracts/Timelock.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "./SafeMath.sol"; diff --git a/contracts/Unitroller.sol b/contracts/Unitroller.sol index 0ecd22cec..65aa20518 100644 --- a/contracts/Unitroller.sol +++ b/contracts/Unitroller.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "./ErrorReporter.sol"; import "./ComptrollerStorage.sol"; diff --git a/contracts/WhitePaperInterestRateModel.sol b/contracts/WhitePaperInterestRateModel.sol index 59721b5b8..68a62dcc1 100644 --- a/contracts/WhitePaperInterestRateModel.sol +++ b/contracts/WhitePaperInterestRateModel.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "./InterestRateModel.sol"; diff --git a/spec/certora/contracts/CDaiDelegateCertora.sol b/spec/certora/contracts/CDaiDelegateCertora.sol index b93c362c1..a5320f525 100644 --- a/spec/certora/contracts/CDaiDelegateCertora.sol +++ b/spec/certora/contracts/CDaiDelegateCertora.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "../../../contracts/CDaiDelegate.sol"; diff --git a/spec/certora/contracts/CErc20DelegateCertora.sol b/spec/certora/contracts/CErc20DelegateCertora.sol index 5ea2a980e..682643648 100644 --- a/spec/certora/contracts/CErc20DelegateCertora.sol +++ b/spec/certora/contracts/CErc20DelegateCertora.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "../../../contracts/CErc20Delegate.sol"; import "../../../contracts/EIP20Interface.sol"; diff --git a/spec/certora/contracts/CErc20DelegatorCertora.sol b/spec/certora/contracts/CErc20DelegatorCertora.sol index f6870bca3..2ac11b708 100644 --- a/spec/certora/contracts/CErc20DelegatorCertora.sol +++ b/spec/certora/contracts/CErc20DelegatorCertora.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "../../../contracts/CErc20Delegator.sol"; import "../../../contracts/EIP20Interface.sol"; diff --git a/spec/certora/contracts/CErc20ImmutableCertora.sol b/spec/certora/contracts/CErc20ImmutableCertora.sol index 83ec98422..a82cea916 100644 --- a/spec/certora/contracts/CErc20ImmutableCertora.sol +++ b/spec/certora/contracts/CErc20ImmutableCertora.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "../../../contracts/CErc20Immutable.sol"; import "../../../contracts/EIP20Interface.sol"; diff --git a/spec/certora/contracts/CEtherCertora.sol b/spec/certora/contracts/CEtherCertora.sol index 259efc277..a94307696 100644 --- a/spec/certora/contracts/CEtherCertora.sol +++ b/spec/certora/contracts/CEtherCertora.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "../../../contracts/CEther.sol"; diff --git a/spec/certora/contracts/CTokenCollateral.sol b/spec/certora/contracts/CTokenCollateral.sol index 5862c2458..0046af0e0 100644 --- a/spec/certora/contracts/CTokenCollateral.sol +++ b/spec/certora/contracts/CTokenCollateral.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "../../../contracts/CErc20Immutable.sol"; import "../../../contracts/EIP20Interface.sol"; diff --git a/spec/certora/contracts/CompCertora.sol b/spec/certora/contracts/CompCertora.sol index 0569d2cbc..4cfcdbb3c 100644 --- a/spec/certora/contracts/CompCertora.sol +++ b/spec/certora/contracts/CompCertora.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "../../../contracts/Governance/Comp.sol"; diff --git a/spec/certora/contracts/ComptrollerCertora.sol b/spec/certora/contracts/ComptrollerCertora.sol index 3c7316b09..bbe03c6ca 100644 --- a/spec/certora/contracts/ComptrollerCertora.sol +++ b/spec/certora/contracts/ComptrollerCertora.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "../../../contracts/Comptroller.sol"; diff --git a/spec/certora/contracts/GovernorAlphaCertora.sol b/spec/certora/contracts/GovernorAlphaCertora.sol index 4b4a327eb..ada85a6e8 100644 --- a/spec/certora/contracts/GovernorAlphaCertora.sol +++ b/spec/certora/contracts/GovernorAlphaCertora.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; pragma experimental ABIEncoderV2; import "../../../contracts/Governance/GovernorAlpha.sol"; diff --git a/spec/certora/contracts/InterestRateModelModel.sol b/spec/certora/contracts/InterestRateModelModel.sol index c7ab9478d..a880b7f65 100644 --- a/spec/certora/contracts/InterestRateModelModel.sol +++ b/spec/certora/contracts/InterestRateModelModel.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "../../../contracts/InterestRateModel.sol"; diff --git a/spec/certora/contracts/MathCertora.sol b/spec/certora/contracts/MathCertora.sol index 4a7911a60..2de8cbcbe 100644 --- a/spec/certora/contracts/MathCertora.sol +++ b/spec/certora/contracts/MathCertora.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; contract MathCertora { diff --git a/spec/certora/contracts/MaximillionCertora.sol b/spec/certora/contracts/MaximillionCertora.sol index 924412081..2e6082d0c 100644 --- a/spec/certora/contracts/MaximillionCertora.sol +++ b/spec/certora/contracts/MaximillionCertora.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "../../../contracts/Maximillion.sol"; diff --git a/spec/certora/contracts/PriceOracleModel.sol b/spec/certora/contracts/PriceOracleModel.sol index 9d4bce24b..86dc75c67 100644 --- a/spec/certora/contracts/PriceOracleModel.sol +++ b/spec/certora/contracts/PriceOracleModel.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "../../../contracts/PriceOracle.sol"; diff --git a/spec/certora/contracts/SimulationInterface.sol b/spec/certora/contracts/SimulationInterface.sol index 034ea2e55..90e7cd163 100644 --- a/spec/certora/contracts/SimulationInterface.sol +++ b/spec/certora/contracts/SimulationInterface.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; interface SimulationInterface { function dummy() external; diff --git a/spec/certora/contracts/TimelockCertora.sol b/spec/certora/contracts/TimelockCertora.sol index 2e6c60b83..70bc99e94 100644 --- a/spec/certora/contracts/TimelockCertora.sol +++ b/spec/certora/contracts/TimelockCertora.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "../../../contracts/Timelock.sol"; diff --git a/spec/certora/contracts/UnderlyingModelNonStandard.sol b/spec/certora/contracts/UnderlyingModelNonStandard.sol index 4419904d0..9918133dd 100644 --- a/spec/certora/contracts/UnderlyingModelNonStandard.sol +++ b/spec/certora/contracts/UnderlyingModelNonStandard.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "../../../contracts/EIP20NonStandardInterface.sol"; diff --git a/spec/certora/contracts/UnderlyingModelWithFee.sol b/spec/certora/contracts/UnderlyingModelWithFee.sol index 63a813eb4..3f104e8c2 100644 --- a/spec/certora/contracts/UnderlyingModelWithFee.sol +++ b/spec/certora/contracts/UnderlyingModelWithFee.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "../../../contracts/EIP20NonStandardInterface.sol"; diff --git a/spec/certora/contracts/mcd/Dai.sol b/spec/certora/contracts/mcd/Dai.sol index 1ed588ad3..22df867bb 100644 --- a/spec/certora/contracts/mcd/Dai.sol +++ b/spec/certora/contracts/mcd/Dai.sol @@ -13,7 +13,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "./lib.sol"; diff --git a/spec/certora/contracts/mcd/Lib.sol b/spec/certora/contracts/mcd/Lib.sol index a3072e9c7..e8f74af3c 100644 --- a/spec/certora/contracts/mcd/Lib.sol +++ b/spec/certora/contracts/mcd/Lib.sol @@ -11,7 +11,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; contract LibNote { event LogNote( diff --git a/spec/certora/contracts/mcd/Pot.sol b/spec/certora/contracts/mcd/Pot.sol index 58aa1e849..980f01f45 100644 --- a/spec/certora/contracts/mcd/Pot.sol +++ b/spec/certora/contracts/mcd/Pot.sol @@ -15,7 +15,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "./lib.sol"; diff --git a/spec/certora/contracts/mcd/Vat.sol b/spec/certora/contracts/mcd/Vat.sol index 8a802b3af..5bcb82c7e 100644 --- a/spec/certora/contracts/mcd/Vat.sol +++ b/spec/certora/contracts/mcd/Vat.sol @@ -15,7 +15,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; contract Vat { // --- Auth --- diff --git a/spec/certora/contracts/mcd/join.sol b/spec/certora/contracts/mcd/join.sol index 362e19be4..7a58ac06f 100644 --- a/spec/certora/contracts/mcd/join.sol +++ b/spec/certora/contracts/mcd/join.sol @@ -15,7 +15,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "./lib.sol"; diff --git a/tests/Contracts/CErc20Harness.sol b/tests/Contracts/CErc20Harness.sol index d944121a9..69e21eeb9 100644 --- a/tests/Contracts/CErc20Harness.sol +++ b/tests/Contracts/CErc20Harness.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "../../contracts/CErc20Immutable.sol"; import "../../contracts/CErc20Delegator.sol"; diff --git a/tests/Contracts/CEtherHarness.sol b/tests/Contracts/CEtherHarness.sol index ac988d0bb..3044b0d7a 100644 --- a/tests/Contracts/CEtherHarness.sol +++ b/tests/Contracts/CEtherHarness.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "../../contracts/CEther.sol"; import "./ComptrollerScenario.sol"; diff --git a/tests/Contracts/CompHarness.sol b/tests/Contracts/CompHarness.sol index 8cf365265..aef093573 100644 --- a/tests/Contracts/CompHarness.sol +++ b/tests/Contracts/CompHarness.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "../../contracts/Governance/Comp.sol"; diff --git a/tests/Contracts/ComptrollerHarness.sol b/tests/Contracts/ComptrollerHarness.sol index e03edeb5e..31f6e8fd2 100644 --- a/tests/Contracts/ComptrollerHarness.sol +++ b/tests/Contracts/ComptrollerHarness.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "../../contracts/Comptroller.sol"; import "../../contracts/PriceOracle.sol"; diff --git a/tests/Contracts/ComptrollerScenario.sol b/tests/Contracts/ComptrollerScenario.sol index 99cb1f17e..0620cc8ca 100644 --- a/tests/Contracts/ComptrollerScenario.sol +++ b/tests/Contracts/ComptrollerScenario.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "../../contracts/Comptroller.sol"; diff --git a/tests/Contracts/Const.sol b/tests/Contracts/Const.sol index b6af74668..68b070e96 100644 --- a/tests/Contracts/Const.sol +++ b/tests/Contracts/Const.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; contract ConstBase { uint public constant C = 1; diff --git a/tests/Contracts/Counter.sol b/tests/Contracts/Counter.sol index dd747b24b..bdefbf234 100644 --- a/tests/Contracts/Counter.sol +++ b/tests/Contracts/Counter.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; contract Counter { uint public count; diff --git a/tests/Contracts/ERC20.sol b/tests/Contracts/ERC20.sol index e75c718c1..bb732b751 100644 --- a/tests/Contracts/ERC20.sol +++ b/tests/Contracts/ERC20.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "../../contracts/SafeMath.sol"; diff --git a/tests/Contracts/EvilToken.sol b/tests/Contracts/EvilToken.sol index ed93b6328..cdd03f4b6 100644 --- a/tests/Contracts/EvilToken.sol +++ b/tests/Contracts/EvilToken.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "./FaucetToken.sol"; diff --git a/tests/Contracts/FalseMarker.sol b/tests/Contracts/FalseMarker.sol index 615304234..88ad4b556 100644 --- a/tests/Contracts/FalseMarker.sol +++ b/tests/Contracts/FalseMarker.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; contract FalseMarkerMethodComptroller { bool public constant isComptroller = false; diff --git a/tests/Contracts/FaucetToken.sol b/tests/Contracts/FaucetToken.sol index ba5ac483c..ee760593a 100644 --- a/tests/Contracts/FaucetToken.sol +++ b/tests/Contracts/FaucetToken.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "./ERC20.sol"; diff --git a/tests/Contracts/Fauceteer.sol b/tests/Contracts/Fauceteer.sol index 3b8718606..faeb6d3e0 100644 --- a/tests/Contracts/Fauceteer.sol +++ b/tests/Contracts/Fauceteer.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "../../contracts/EIP20NonStandardInterface.sol"; diff --git a/tests/Contracts/FeeToken.sol b/tests/Contracts/FeeToken.sol index 06ec86ae6..3fc03e22b 100644 --- a/tests/Contracts/FeeToken.sol +++ b/tests/Contracts/FeeToken.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "./FaucetToken.sol"; diff --git a/tests/Contracts/FixedPriceOracle.sol b/tests/Contracts/FixedPriceOracle.sol index 88fcf6fd8..d1a02cc4d 100644 --- a/tests/Contracts/FixedPriceOracle.sol +++ b/tests/Contracts/FixedPriceOracle.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "../../contracts/PriceOracle.sol"; diff --git a/tests/Contracts/GovernorAlphaHarness.sol b/tests/Contracts/GovernorAlphaHarness.sol index 4ab8f371f..ba799f4d9 100644 --- a/tests/Contracts/GovernorAlphaHarness.sol +++ b/tests/Contracts/GovernorAlphaHarness.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "../../contracts/Governance/GovernorAlpha.sol"; diff --git a/tests/Contracts/GovernorBravoHarness.sol b/tests/Contracts/GovernorBravoHarness.sol index 20c0ea8a9..6978a632c 100644 --- a/tests/Contracts/GovernorBravoHarness.sol +++ b/tests/Contracts/GovernorBravoHarness.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "../../contracts/Governance/GovernorBravoDelegate.sol"; diff --git a/tests/Contracts/GovernorBravoImmutable.sol b/tests/Contracts/GovernorBravoImmutable.sol index 6317cd5dd..1b5a58f0a 100644 --- a/tests/Contracts/GovernorBravoImmutable.sol +++ b/tests/Contracts/GovernorBravoImmutable.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "../../contracts/Governance/GovernorBravoDelegate.sol"; diff --git a/tests/Contracts/InterestRateModelHarness.sol b/tests/Contracts/InterestRateModelHarness.sol index 44fbbc826..d831dd2d5 100644 --- a/tests/Contracts/InterestRateModelHarness.sol +++ b/tests/Contracts/InterestRateModelHarness.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "../../contracts/InterestRateModel.sol"; diff --git a/tests/Contracts/MathHelpers.sol b/tests/Contracts/MathHelpers.sol index d75668c8b..7678f0d31 100644 --- a/tests/Contracts/MathHelpers.sol +++ b/tests/Contracts/MathHelpers.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; contract MathHelpers { diff --git a/tests/Contracts/MockMCD.sol b/tests/Contracts/MockMCD.sol index 358fefa4f..4b904ed30 100644 --- a/tests/Contracts/MockMCD.sol +++ b/tests/Contracts/MockMCD.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; contract MockPot { diff --git a/tests/Contracts/PriceOracleProxy.sol b/tests/Contracts/PriceOracleProxy.sol index 04f5d5f4b..b7f0196d0 100644 --- a/tests/Contracts/PriceOracleProxy.sol +++ b/tests/Contracts/PriceOracleProxy.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "../../contracts/CErc20.sol"; import "../../contracts/CToken.sol"; diff --git a/tests/Contracts/Structs.sol b/tests/Contracts/Structs.sol index b22f1b00b..9449d6039 100644 --- a/tests/Contracts/Structs.sol +++ b/tests/Contracts/Structs.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; contract Structs { struct Outer { diff --git a/tests/Contracts/TetherInterface.sol b/tests/Contracts/TetherInterface.sol index 0d926811c..a499cbae0 100644 --- a/tests/Contracts/TetherInterface.sol +++ b/tests/Contracts/TetherInterface.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "../../contracts/EIP20Interface.sol"; diff --git a/tests/Contracts/TimelockHarness.sol b/tests/Contracts/TimelockHarness.sol index 43044ce12..5f63a6d8c 100644 --- a/tests/Contracts/TimelockHarness.sol +++ b/tests/Contracts/TimelockHarness.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; import "../../contracts/Timelock.sol"; diff --git a/tests/Contracts/WBTC.sol b/tests/Contracts/WBTC.sol index a8e350c77..29cd96cd0 100644 --- a/tests/Contracts/WBTC.sol +++ b/tests/Contracts/WBTC.sol @@ -3,7 +3,7 @@ */ // SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; +pragma solidity ^0.8.15; // File: openzeppelin-solidity/contracts/token/ERC20/ERC20Basic.sol @@ -498,7 +498,7 @@ contract PausableToken is StandardToken, Pausable { uint256 _value ) virtual - override + override(BasicToken, ERC20Basic) public whenNotPaused returns (bool)