Skip to content

Instantly share code, notes, and snippets.

@alexkroeger
Last active October 11, 2021 23:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexkroeger/d817d1ca115c7be1f64831ed31381639 to your computer and use it in GitHub Desktop.
Save alexkroeger/d817d1ca115c7be1f64831ed31381639 to your computer and use it in GitHub Desktop.
a=0x234B619B4f4E405665F7d94F2CE60c24256032B5, b=0xBafE01ff935C7305907c33BF824352eE5979B526
diff --git a/old_comptroller.sol b/new_comptroller.sol
index 13ddf7b..4399c3f 100644
--- a/old_comptroller.sol
+++ b/new_comptroller.sol
@@ -12,7 +12,7 @@ import "./Governance/Comp.sol";
* @title Compound's Comptroller Contract
* @author Compound
*/
-contract Comptroller is ComptrollerV6Storage, ComptrollerInterface, ComptrollerErrorReporter, ExponentialNoError {
+contract Comptroller is ComptrollerV7Storage, ComptrollerInterface, ComptrollerErrorReporter, ExponentialNoError {
/// @notice Emitted when an admin supports a market
event MarketListed(CToken cToken);
@@ -67,6 +67,12 @@ contract Comptroller is ComptrollerV6Storage, ComptrollerInterface, ComptrollerE
/// @notice Emitted when COMP is granted by admin
event CompGranted(address recipient, uint amount);
+ /// @notice Emitted when COMP accrued for a user has been manually adjusted.
+ event CompAccruedAdjusted(address indexed user, uint oldCompAccrued, uint newCompAccrued);
+
+ /// @notice Emitted when COMP receivable for a user has been updated.
+ event CompReceivableUpdated(address indexed user, uint oldCompReceivable, uint newCompReceivable);
+
/// @notice The initial COMP index for a market
uint224 public constant compInitialIndex = 1e36;
@@ -1079,6 +1085,54 @@ contract Comptroller is ComptrollerV6Storage, ComptrollerInterface, ComptrollerE
require(unitroller._acceptImplementation() == 0, "change not authorized");
}
+ /// @notice Delete this function after proposal 65 is executed
+ function fixBadAccruals(address[] calldata affectedUsers, uint[] calldata amounts) external {
+ require(msg.sender == admin, "Only admin can call this function"); // Only the timelock can call this function
+ require(!proposal65FixExecuted, "Already executed this one-off function"); // Require that this function is only called once
+ require(affectedUsers.length == amounts.length, "Invalid input");
+
+ // Loop variables
+ address user;
+ uint currentAccrual;
+ uint amountToSubtract;
+ uint newAccrual;
+
+ // Iterate through all affected users
+ for (uint i = 0; i < affectedUsers.length; ++i) {
+ user = affectedUsers[i];
+ currentAccrual = compAccrued[user];
+
+ amountToSubtract = amounts[i];
+
+ // The case where the user has claimed and received an incorrect amount of COMP.
+ // The user has less currently accrued than the amount they incorrectly received.
+ if (amountToSubtract > currentAccrual) {
+ // Amount of COMP the user owes the protocol
+ uint accountReceivable = amountToSubtract - currentAccrual; // Underflow safe since amountToSubtract > currentAccrual
+
+ uint oldReceivable = compReceivable[user];
+ uint newReceivable = add_(oldReceivable, accountReceivable);
+
+ // Accounting: record the COMP debt for the user
+ compReceivable[user] = newReceivable;
+
+ emit CompReceivableUpdated(user, oldReceivable, newReceivable);
+
+ amountToSubtract = currentAccrual;
+ }
+
+ if (amountToSubtract > 0) {
+ // Subtract the bad accrual amount from what they have accrued.
+ // Users will keep whatever they have correctly accrued.
+ compAccrued[user] = newAccrual = sub_(currentAccrual, amountToSubtract);
+
+ emit CompAccruedAdjusted(user, currentAccrual, newAccrual);
+ }
+ }
+
+ proposal65FixExecuted = true; // Makes it so that this function cannot be called again
+ }
+
/**
* @notice Checks caller is admin, or this contract is becoming the new implementation
*/
@@ -1315,18 +1369,6 @@ contract Comptroller is ComptrollerV6Storage, ComptrollerInterface, ComptrollerE
* @return The amount of COMP which was NOT transferred to the user
*/
function grantCompInternal(address user, uint amount) internal returns (uint) {
- for (uint i = 0; i < allMarkets.length; ++i) {
- address market = address(allMarkets[i]);
-
- bool noOriginalSpeed = compBorrowSpeeds[market] == 0;
- bool invalidSupply = noOriginalSpeed && compSupplierIndex[market][user] > 0;
- bool invalidBorrow = noOriginalSpeed && compBorrowerIndex[market][user] > 0;
-
- if (invalidSupply || invalidBorrow) {
- return amount;
- }
- }
-
Comp comp = Comp(getCompAddress());
uint compRemaining = comp.balanceOf(address(this));
if (amount > 0 && amount <= compRemaining) {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment