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)