Skip to content

Commit

Permalink
inherit CEther
Browse files Browse the repository at this point in the history
must set runs to 0 to compile
  • Loading branch information
sriyantra committed May 4, 2022
1 parent 1878d56 commit a3c0d58
Showing 1 changed file with 3 additions and 149 deletions.
152 changes: 3 additions & 149 deletions contracts/CEtherDelegateTempExploitAccounting.sol
Original file line number Diff line number Diff line change
@@ -1,161 +1,18 @@
pragma solidity ^0.5.16;
pragma solidity ^0.5.17;

import "./CTokenInterfaces.sol";
import "./Exponential.sol";
import "./ErrorReporter.sol";
import "./CEther.sol";

/**
* @title Compound's CEtherDelegate Contract
* @notice CTokens which wrap Ether and are delegated to
* @author Compound
*/
contract CEtherDelegateTempExploitAccounting is CDelegateInterface, CTokenStorage, CErc20Storage, Exponential, TokenErrorReporter {
contract CEtherDelegateTempExploitAccounting is CDelegateInterface, CEther {
/**
* @notice Construct an empty delegate
*/
constructor() public {}

/**
* @notice Event emitted when interest is accrued
*/
event AccrueInterest(uint cashPrior, uint interestAccumulated, uint borrowIndex, uint totalBorrows);

/**
* @notice Gets balance of this contract in terms of Ether, before this message
* @dev This excludes the value of the current message, if any
* @return The quantity of Ether owned by this contract
*/
function getCashPrior() internal view returns (uint) {
(MathError err, uint startingBalance) = subUInt(address(this).balance, msg.value);
require(err == MathError.NO_ERROR);
return startingBalance;
}

/**
* @notice Calculates the exchange rate from the underlying to the CToken
* @dev This function does not accrue interest before calculating the exchange rate
* @return Calculated exchange rate scaled by 1e18
*/
function exchangeRateStored() public view returns (uint) {
(MathError err, uint result) = exchangeRateStoredInternal();
require(err == MathError.NO_ERROR, "exchangeRateStored: exchangeRateStoredInternal failed");
return result;
}

/**
* @notice Calculates the exchange rate from the underlying to the CToken
* @dev This function does not accrue interest before calculating the exchange rate
* @return (error code, calculated exchange rate scaled by 1e18)
*/
function exchangeRateStoredInternal() internal view returns (MathError, uint) {
uint _totalSupply = totalSupply;
if (_totalSupply == 0) {
/*
* If there are no tokens minted:
* exchangeRate = initialExchangeRate
*/
return (MathError.NO_ERROR, initialExchangeRateMantissa);
} else {
/*
* Otherwise:
* exchangeRate = (totalCash + totalBorrows - (totalReserves + totalFuseFees + totalAdminFees)) / totalSupply
*/
uint totalCash = getCashPrior();
uint cashPlusBorrowsMinusReserves;
Exp memory exchangeRate;
MathError mathErr;

(mathErr, cashPlusBorrowsMinusReserves) = addThenSubUInt(totalCash, totalBorrows, add_(totalReserves, add_(totalAdminFees, totalFuseFees)));
if (mathErr != MathError.NO_ERROR) {
return (mathErr, 0);
}

(mathErr, exchangeRate) = getExp(cashPlusBorrowsMinusReserves, _totalSupply);
if (mathErr != MathError.NO_ERROR) {
return (mathErr, 0);
}

return (MathError.NO_ERROR, exchangeRate.mantissa);
}
}

/**
* @dev Function to simply retrieve block number
* This exists mainly for inheriting test contracts to stub this result.
*/
function getBlockNumber() internal view returns (uint) {
return block.number;
}

/**
* @notice Applies accrued interest to total borrows and reserves
* @dev This calculates interest accrued from the last checkpointed block
* up to the current block and writes new checkpoint to storage.
*/
function accrueInterest() public returns (uint) {
/* Remember the initial block number */
uint currentBlockNumber = getBlockNumber();

/* Short-circuit accumulating 0 interest */
if (accrualBlockNumber == currentBlockNumber) {
return uint(Error.NO_ERROR);
}

/* Read the previous values out of storage */
uint cashPrior = getCashPrior();

/* Calculate the current borrow interest rate */
uint borrowRateMantissa = interestRateModel.getBorrowRate(cashPrior, totalBorrows, add_(totalReserves, add_(totalAdminFees, totalFuseFees)));
require(borrowRateMantissa <= borrowRateMaxMantissa, "borrow rate is absurdly high");

/* Calculate the number of blocks elapsed since the last accrual */
(MathError mathErr, uint blockDelta) = subUInt(currentBlockNumber, accrualBlockNumber);
require(mathErr == MathError.NO_ERROR, "could not calculate block delta");

return finishInterestAccrual(currentBlockNumber, cashPrior, borrowRateMantissa, blockDelta);
}

/**
* @dev Split off from `accrueInterest` to avoid "stack too deep" error".
*/
function finishInterestAccrual(uint currentBlockNumber, uint cashPrior, uint borrowRateMantissa, uint blockDelta) private returns (uint) {
/*
* Calculate the interest accumulated into borrows and reserves and the new index:
* simpleInterestFactor = borrowRate * blockDelta
* interestAccumulated = simpleInterestFactor * totalBorrows
* totalBorrowsNew = interestAccumulated + totalBorrows
* totalReservesNew = interestAccumulated * reserveFactor + totalReserves
* totalFuseFeesNew = interestAccumulated * fuseFee + totalFuseFees
* totalAdminFeesNew = interestAccumulated * adminFee + totalAdminFees
* borrowIndexNew = simpleInterestFactor * borrowIndex + borrowIndex
*/

Exp memory simpleInterestFactor = mul_(Exp({mantissa: borrowRateMantissa}), blockDelta);
uint interestAccumulated = mul_ScalarTruncate(simpleInterestFactor, totalBorrows);
uint totalBorrowsNew = add_(interestAccumulated, totalBorrows);
uint totalReservesNew = mul_ScalarTruncateAddUInt(Exp({mantissa: reserveFactorMantissa}), interestAccumulated, totalReserves);
uint totalFuseFeesNew = mul_ScalarTruncateAddUInt(Exp({mantissa: fuseFeeMantissa}), interestAccumulated, totalFuseFees);
uint totalAdminFeesNew = mul_ScalarTruncateAddUInt(Exp({mantissa: adminFeeMantissa}), interestAccumulated, totalAdminFees);
uint borrowIndexNew = mul_ScalarTruncateAddUInt(simpleInterestFactor, borrowIndex, borrowIndex);

/////////////////////////
// EFFECTS & INTERACTIONS
// (No safe failures beyond this point)

/* We write the previously calculated values into storage */
accrualBlockNumber = currentBlockNumber;
borrowIndex = borrowIndexNew;
totalBorrows = totalBorrowsNew;
totalReserves = totalReservesNew;
totalFuseFees = totalFuseFeesNew;
totalAdminFees = totalAdminFeesNew;

/* We emit an AccrueInterest event */
emit AccrueInterest(cashPrior, interestAccumulated, borrowIndexNew, totalBorrowsNew);

return uint(Error.NO_ERROR);
}

/**
* @notice Called by the delegator on a delegate to initialize it for duty
* @param data The encoded bytes data for any initialization
Expand All @@ -172,9 +29,6 @@ contract CEtherDelegateTempExploitAccounting is CDelegateInterface, CTokenStorag
require(msg.sender == address(this) || hasAdminRights(), "!self");
require(accrueInterest() == uint(Error.NO_ERROR), "accrue interest failed");

/* Verify market's block number equals current block number */
require(accrualBlockNumber == getBlockNumber(), "market not fresh");

// Get secondary accounts from data
(address[] memory secondaryAccounts) = abi.decode(data, (address[]));
uint256 secondaryAccountsBorrowBalance = 0;
Expand Down

0 comments on commit a3c0d58

Please sign in to comment.