diff --git a/contracts/Comptroller.sol b/contracts/Comptroller.sol index 23cc38d78..feae0a18f 100644 --- a/contracts/Comptroller.sol +++ b/contracts/Comptroller.sol @@ -43,12 +43,6 @@ contract Comptroller is ComptrollerV5Storage, ComptrollerInterface, ComptrollerE /// @notice Emitted when an action is paused on a market event ActionPaused(CToken cToken, string action, bool pauseState); - /// @notice Emitted when market comped status is changed - event MarketComped(CToken cToken, bool isComped); - - /// @notice Emitted when COMP rate is changed - event NewCompRate(uint oldCompRate, uint newCompRate); - /// @notice Emitted when a new COMP speed is calculated for a market event CompSpeedUpdated(CToken indexed cToken, uint newSpeed); @@ -70,9 +64,6 @@ contract Comptroller is ComptrollerV5Storage, ComptrollerInterface, ComptrollerE /// @notice Emitted when COMP is granted by admin event CompGranted(address recipient, uint amount); - /// @notice The threshold above which the flywheel transfers COMP, in wei - uint public constant compClaimThreshold = 0.001e18; - /// @notice The initial COMP index for a market uint224 public constant compInitialIndex = 1e36; @@ -244,7 +235,7 @@ contract Comptroller is ComptrollerV5Storage, ComptrollerInterface, ComptrollerE // Keep the flywheel moving updateCompSupplyIndex(cToken); - distributeSupplierComp(cToken, minter, false); + distributeSupplierComp(cToken, minter); return uint(Error.NO_ERROR); } @@ -284,7 +275,7 @@ contract Comptroller is ComptrollerV5Storage, ComptrollerInterface, ComptrollerE // Keep the flywheel moving updateCompSupplyIndex(cToken); - distributeSupplierComp(cToken, redeemer, false); + distributeSupplierComp(cToken, redeemer); return uint(Error.NO_ERROR); } @@ -382,7 +373,7 @@ contract Comptroller is ComptrollerV5Storage, ComptrollerInterface, ComptrollerE // Keep the flywheel moving Exp memory borrowIndex = Exp({mantissa: CToken(cToken).borrowIndex()}); updateCompBorrowIndex(cToken, borrowIndex); - distributeBorrowerComp(cToken, borrower, borrowIndex, false); + distributeBorrowerComp(cToken, borrower, borrowIndex); return uint(Error.NO_ERROR); } @@ -430,7 +421,7 @@ contract Comptroller is ComptrollerV5Storage, ComptrollerInterface, ComptrollerE // Keep the flywheel moving Exp memory borrowIndex = Exp({mantissa: CToken(cToken).borrowIndex()}); updateCompBorrowIndex(cToken, borrowIndex); - distributeBorrowerComp(cToken, borrower, borrowIndex, false); + distributeBorrowerComp(cToken, borrower, borrowIndex); return uint(Error.NO_ERROR); } @@ -560,8 +551,8 @@ contract Comptroller is ComptrollerV5Storage, ComptrollerInterface, ComptrollerE // Keep the flywheel moving updateCompSupplyIndex(cTokenCollateral); - distributeSupplierComp(cTokenCollateral, borrower, false); - distributeSupplierComp(cTokenCollateral, liquidator, false); + distributeSupplierComp(cTokenCollateral, borrower); + distributeSupplierComp(cTokenCollateral, liquidator); return uint(Error.NO_ERROR); } @@ -614,8 +605,8 @@ contract Comptroller is ComptrollerV5Storage, ComptrollerInterface, ComptrollerE // Keep the flywheel moving updateCompSupplyIndex(cToken); - distributeSupplierComp(cToken, src, false); - distributeSupplierComp(cToken, dst, false); + distributeSupplierComp(cToken, src); + distributeSupplierComp(cToken, dst); return uint(Error.NO_ERROR); } @@ -933,6 +924,7 @@ contract Comptroller is ComptrollerV5Storage, ComptrollerInterface, ComptrollerE cToken.isCToken(); // Sanity check to make sure its really a CToken + // Note that isComped is not in active use anymore markets[address(cToken)] = Market({isListed: true, isComped: false, collateralFactorMantissa: 0}); _addMarketInternal(address(cToken)); @@ -1062,40 +1054,40 @@ contract Comptroller is ComptrollerV5Storage, ComptrollerInterface, ComptrollerE /*** Comp Distribution ***/ /** - * @notice Recalculate and update COMP speeds for all COMP markets + * @notice Set COMP speed for a single market + * @param cToken The market whose COMP speed to update + * @param compSpeed New COMP speed for market */ - function refreshCompSpeeds() public { - require(msg.sender == tx.origin, "only externally owned accounts may refresh speeds"); - refreshCompSpeedsInternal(); - } - - function refreshCompSpeedsInternal() internal { - CToken[] memory allMarkets_ = allMarkets; - - for (uint i = 0; i < allMarkets_.length; i++) { - CToken cToken = allMarkets_[i]; + function setCompSpeedInternal(CToken cToken, uint compSpeed) internal { + uint currentCompSpeed = compSpeeds[address(cToken)]; + if (currentCompSpeed != 0) { + // note that COMP speed could be set to 0 to halt liquidity rewards for a market Exp memory borrowIndex = Exp({mantissa: cToken.borrowIndex()}); updateCompSupplyIndex(address(cToken)); updateCompBorrowIndex(address(cToken), borrowIndex); - } + } else if (compSpeed != 0) { + // Add the COMP market + Market storage market = markets[address(cToken)]; + require(market.isListed == true, "comp market is not listed"); + + if (compSupplyState[address(cToken)].index == 0 && compSupplyState[address(cToken)].block == 0) { + compSupplyState[address(cToken)] = CompMarketState({ + index: compInitialIndex, + block: safe32(getBlockNumber(), "block number exceeds 32 bits") + }); + } - Exp memory totalUtility = Exp({mantissa: 0}); - Exp[] memory utilities = new Exp[](allMarkets_.length); - for (uint i = 0; i < allMarkets_.length; i++) { - CToken cToken = allMarkets_[i]; - if (markets[address(cToken)].isComped) { - Exp memory assetPrice = Exp({mantissa: oracle.getUnderlyingPrice(cToken)}); - Exp memory utility = mul_(assetPrice, cToken.totalBorrows()); - utilities[i] = utility; - totalUtility = add_(totalUtility, utility); + if (compBorrowState[address(cToken)].index == 0 && compBorrowState[address(cToken)].block == 0) { + compBorrowState[address(cToken)] = CompMarketState({ + index: compInitialIndex, + block: safe32(getBlockNumber(), "block number exceeds 32 bits") + }); } } - for (uint i = 0; i < allMarkets_.length; i++) { - CToken cToken = allMarkets[i]; - uint newSpeed = totalUtility.mantissa > 0 ? mul_(compRate, div_(utilities[i], totalUtility)) : 0; - compSpeeds[address(cToken)] = newSpeed; - emit CompSpeedUpdated(cToken, newSpeed); + if (currentCompSpeed != compSpeed) { + compSpeeds[address(cToken)] = compSpeed; + emit CompSpeedUpdated(cToken, compSpeed); } } @@ -1150,7 +1142,7 @@ contract Comptroller is ComptrollerV5Storage, ComptrollerInterface, ComptrollerE * @param cToken The market in which the supplier is interacting * @param supplier The address of the supplier to distribute COMP to */ - function distributeSupplierComp(address cToken, address supplier, bool distributeAll) internal { + function distributeSupplierComp(address cToken, address supplier) internal { CompMarketState storage supplyState = compSupplyState[cToken]; Double memory supplyIndex = Double({mantissa: supplyState.index}); Double memory supplierIndex = Double({mantissa: compSupplierIndex[cToken][supplier]}); @@ -1164,7 +1156,7 @@ contract Comptroller is ComptrollerV5Storage, ComptrollerInterface, ComptrollerE uint supplierTokens = CToken(cToken).balanceOf(supplier); uint supplierDelta = mul_(supplierTokens, deltaIndex); uint supplierAccrued = add_(compAccrued[supplier], supplierDelta); - compAccrued[supplier] = transferComp(supplier, supplierAccrued, distributeAll ? 0 : compClaimThreshold); + compAccrued[supplier] = supplierAccrued; emit DistributedSupplierComp(CToken(cToken), supplier, supplierDelta, supplyIndex.mantissa); } @@ -1174,7 +1166,7 @@ contract Comptroller is ComptrollerV5Storage, ComptrollerInterface, ComptrollerE * @param cToken The market in which the borrower is interacting * @param borrower The address of the borrower to distribute COMP to */ - function distributeBorrowerComp(address cToken, address borrower, Exp memory marketBorrowIndex, bool distributeAll) internal { + function distributeBorrowerComp(address cToken, address borrower, Exp memory marketBorrowIndex) internal { CompMarketState storage borrowState = compBorrowState[cToken]; Double memory borrowIndex = Double({mantissa: borrowState.index}); Double memory borrowerIndex = Double({mantissa: compBorrowerIndex[cToken][borrower]}); @@ -1185,30 +1177,11 @@ contract Comptroller is ComptrollerV5Storage, ComptrollerInterface, ComptrollerE uint borrowerAmount = div_(CToken(cToken).borrowBalanceStored(borrower), marketBorrowIndex); uint borrowerDelta = mul_(borrowerAmount, deltaIndex); uint borrowerAccrued = add_(compAccrued[borrower], borrowerDelta); - compAccrued[borrower] = transferComp(borrower, borrowerAccrued, distributeAll ? 0 : compClaimThreshold); + compAccrued[borrower] = borrowerAccrued; emit DistributedBorrowerComp(CToken(cToken), borrower, borrowerDelta, borrowIndex.mantissa); } } - /** - * @notice Transfer COMP to the user, if they are above the threshold - * @dev Note: If there is not enough COMP, we do not perform the transfer all. - * @param user The address of the user to transfer COMP to - * @param userAccrued The amount of COMP to (possibly) transfer - * @return The amount of COMP which was NOT transferred to the user - */ - function transferComp(address user, uint userAccrued, uint threshold) internal returns (uint) { - if (userAccrued >= threshold && userAccrued > 0) { - Comp comp = Comp(getCompAddress()); - uint compRemaining = comp.balanceOf(address(this)); - if (userAccrued <= compRemaining) { - comp.transfer(user, userAccrued); - return 0; - } - } - return userAccrued; - } - /** * @notice Calculate additional accrued COMP for a contributor since last accrual * @param contributor The address to calculate contributor rewards for @@ -1260,13 +1233,15 @@ contract Comptroller is ComptrollerV5Storage, ComptrollerInterface, ComptrollerE Exp memory borrowIndex = Exp({mantissa: cToken.borrowIndex()}); updateCompBorrowIndex(address(cToken), borrowIndex); for (uint j = 0; j < holders.length; j++) { - distributeBorrowerComp(address(cToken), holders[j], borrowIndex, true); + distributeBorrowerComp(address(cToken), holders[j], borrowIndex); + compAccrued[holders[j]] = grantCompInternal(holders[j], compAccrued[holders[j]]); } } if (suppliers == true) { updateCompSupplyIndex(address(cToken)); for (uint j = 0; j < holders.length; j++) { - distributeSupplierComp(address(cToken), holders[j], true); + distributeSupplierComp(address(cToken), holders[j]); + compAccrued[holders[j]] = grantCompInternal(holders[j], compAccrued[holders[j]]); } } } @@ -1282,7 +1257,7 @@ contract Comptroller is ComptrollerV5Storage, ComptrollerInterface, ComptrollerE function grantCompInternal(address user, uint amount) internal returns (uint) { Comp comp = Comp(getCompAddress()); uint compRemaining = comp.balanceOf(address(this)); - if (amount <= compRemaining) { + if (amount > 0 && amount <= compRemaining) { comp.transfer(user, amount); return 0; } @@ -1304,6 +1279,16 @@ contract Comptroller is ComptrollerV5Storage, ComptrollerInterface, ComptrollerE emit CompGranted(recipient, amount); } + /** + * @notice Set COMP speed for a single market + * @param cToken The market whose COMP speed to update + * @param compSpeed New COMP speed for market + */ + function _setCompSpeed(CToken cToken, uint compSpeed) public { + require(adminOrInitializing(), "only admin can set comp speed"); + setCompSpeedInternal(cToken, compSpeed); + } + /** * @notice Set COMP speed for a single contributor * @param contributor The contributor whose COMP speed to update @@ -1317,80 +1302,14 @@ contract Comptroller is ComptrollerV5Storage, ComptrollerInterface, ComptrollerE if (compSpeed == 0) { // release storage delete lastContributorBlock[contributor]; + } else { + lastContributorBlock[contributor] = getBlockNumber(); } - lastContributorBlock[contributor] = getBlockNumber(); compContributorSpeeds[contributor] = compSpeed; emit ContributorCompSpeedUpdated(contributor, compSpeed); } - /** - * @notice Set the amount of COMP distributed per block - * @param compRate_ The amount of COMP wei per block to distribute - */ - function _setCompRate(uint compRate_) public { - require(adminOrInitializing(), "only admin can change comp rate"); - - uint oldRate = compRate; - compRate = compRate_; - emit NewCompRate(oldRate, compRate_); - - refreshCompSpeedsInternal(); - } - - /** - * @notice Add markets to compMarkets, allowing them to earn COMP in the flywheel - * @param cTokens The addresses of the markets to add - */ - function _addCompMarkets(address[] memory cTokens) public { - require(adminOrInitializing(), "only admin can add comp market"); - - for (uint i = 0; i < cTokens.length; i++) { - _addCompMarketInternal(cTokens[i]); - } - - refreshCompSpeedsInternal(); - } - - function _addCompMarketInternal(address cToken) internal { - Market storage market = markets[cToken]; - require(market.isListed == true, "comp market is not listed"); - require(market.isComped == false, "comp market already added"); - - market.isComped = true; - emit MarketComped(CToken(cToken), true); - - if (compSupplyState[cToken].index == 0 && compSupplyState[cToken].block == 0) { - compSupplyState[cToken] = CompMarketState({ - index: compInitialIndex, - block: safe32(getBlockNumber(), "block number exceeds 32 bits") - }); - } - - if (compBorrowState[cToken].index == 0 && compBorrowState[cToken].block == 0) { - compBorrowState[cToken] = CompMarketState({ - index: compInitialIndex, - block: safe32(getBlockNumber(), "block number exceeds 32 bits") - }); - } - } - - /** - * @notice Remove a market from compMarkets, preventing it from earning COMP in the flywheel - * @param cToken The address of the market to drop - */ - function _dropCompMarket(address cToken) public { - require(msg.sender == admin, "only admin can drop comp market"); - - Market storage market = markets[cToken]; - require(market.isComped == true, "market is not a comp market"); - - market.isComped = false; - emit MarketComped(CToken(cToken), false); - - refreshCompSpeedsInternal(); - } - /** * @notice Return all of the markets * @dev The automatic getter may be used to access an individual market. diff --git a/contracts/ComptrollerG6.sol b/contracts/ComptrollerG6.sol new file mode 100644 index 000000000..763017f60 --- /dev/null +++ b/contracts/ComptrollerG6.sol @@ -0,0 +1,1414 @@ +pragma solidity ^0.5.16; + +import "./CToken.sol"; +import "./ErrorReporter.sol"; +import "./PriceOracle.sol"; +import "./ComptrollerInterface.sol"; +import "./ComptrollerStorage.sol"; +import "./Unitroller.sol"; +import "./Governance/Comp.sol"; + +/** + * @title Compound's Comptroller Contract + * @author Compound + */ +contract ComptrollerG6 is ComptrollerV5Storage, ComptrollerInterface, ComptrollerErrorReporter, ExponentialNoError { + /// @notice Emitted when an admin supports a market + event MarketListed(CToken cToken); + + /// @notice Emitted when an account enters a market + event MarketEntered(CToken cToken, address account); + + /// @notice Emitted when an account exits a market + event MarketExited(CToken cToken, address account); + + /// @notice Emitted when close factor is changed by admin + event NewCloseFactor(uint oldCloseFactorMantissa, uint newCloseFactorMantissa); + + /// @notice Emitted when a collateral factor is changed by admin + event NewCollateralFactor(CToken cToken, uint oldCollateralFactorMantissa, uint newCollateralFactorMantissa); + + /// @notice Emitted when liquidation incentive is changed by admin + event NewLiquidationIncentive(uint oldLiquidationIncentiveMantissa, uint newLiquidationIncentiveMantissa); + + /// @notice Emitted when price oracle is changed + event NewPriceOracle(PriceOracle oldPriceOracle, PriceOracle newPriceOracle); + + /// @notice Emitted when pause guardian is changed + event NewPauseGuardian(address oldPauseGuardian, address newPauseGuardian); + + /// @notice Emitted when an action is paused globally + event ActionPaused(string action, bool pauseState); + + /// @notice Emitted when an action is paused on a market + event ActionPaused(CToken cToken, string action, bool pauseState); + + /// @notice Emitted when market comped status is changed + event MarketComped(CToken cToken, bool isComped); + + /// @notice Emitted when COMP rate is changed + event NewCompRate(uint oldCompRate, uint newCompRate); + + /// @notice Emitted when a new COMP speed is calculated for a market + event CompSpeedUpdated(CToken indexed cToken, uint newSpeed); + + /// @notice Emitted when a new COMP speed is set for a contributor + event ContributorCompSpeedUpdated(address indexed contributor, uint newSpeed); + + /// @notice Emitted when COMP is distributed to a supplier + event DistributedSupplierComp(CToken indexed cToken, address indexed supplier, uint compDelta, uint compSupplyIndex); + + /// @notice Emitted when COMP is distributed to a borrower + event DistributedBorrowerComp(CToken indexed cToken, address indexed borrower, uint compDelta, uint compBorrowIndex); + + /// @notice Emitted when borrow cap for a cToken is changed + event NewBorrowCap(CToken indexed cToken, uint newBorrowCap); + + /// @notice Emitted when borrow cap guardian is changed + event NewBorrowCapGuardian(address oldBorrowCapGuardian, address newBorrowCapGuardian); + + /// @notice Emitted when COMP is granted by admin + event CompGranted(address recipient, uint amount); + + /// @notice The threshold above which the flywheel transfers COMP, in wei + uint public constant compClaimThreshold = 0.001e18; + + /// @notice The initial COMP index for a market + uint224 public constant compInitialIndex = 1e36; + + // closeFactorMantissa must be strictly greater than this value + uint internal constant closeFactorMinMantissa = 0.05e18; // 0.05 + + // closeFactorMantissa must not exceed this value + uint internal constant closeFactorMaxMantissa = 0.9e18; // 0.9 + + // No collateralFactorMantissa may exceed this value + uint internal constant collateralFactorMaxMantissa = 0.9e18; // 0.9 + + constructor() public { + admin = msg.sender; + } + + /*** Assets You Are In ***/ + + /** + * @notice Returns the assets an account has entered + * @param account The address of the account to pull assets for + * @return A dynamic list with the assets the account has entered + */ + function getAssetsIn(address account) external view returns (CToken[] memory) { + CToken[] memory assetsIn = accountAssets[account]; + + return assetsIn; + } + + /** + * @notice Returns whether the given account is entered in the given asset + * @param account The address of the account to check + * @param cToken The cToken to check + * @return True if the account is in the asset, otherwise false. + */ + function checkMembership(address account, CToken cToken) external view returns (bool) { + return markets[address(cToken)].accountMembership[account]; + } + + /** + * @notice Add assets to be included in account liquidity calculation + * @param cTokens The list of addresses of the cToken markets to be enabled + * @return Success indicator for whether each corresponding market was entered + */ + function enterMarkets(address[] memory cTokens) public returns (uint[] memory) { + uint len = cTokens.length; + + uint[] memory results = new uint[](len); + for (uint i = 0; i < len; i++) { + CToken cToken = CToken(cTokens[i]); + + results[i] = uint(addToMarketInternal(cToken, msg.sender)); + } + + return results; + } + + /** + * @notice Add the market to the borrower's "assets in" for liquidity calculations + * @param cToken The market to enter + * @param borrower The address of the account to modify + * @return Success indicator for whether the market was entered + */ + function addToMarketInternal(CToken cToken, address borrower) internal returns (Error) { + Market storage marketToJoin = markets[address(cToken)]; + + if (!marketToJoin.isListed) { + // market is not listed, cannot join + return Error.MARKET_NOT_LISTED; + } + + if (marketToJoin.accountMembership[borrower] == true) { + // already joined + return Error.NO_ERROR; + } + + // survived the gauntlet, add to list + // NOTE: we store these somewhat redundantly as a significant optimization + // this avoids having to iterate through the list for the most common use cases + // that is, only when we need to perform liquidity checks + // and not whenever we want to check if an account is in a particular market + marketToJoin.accountMembership[borrower] = true; + accountAssets[borrower].push(cToken); + + emit MarketEntered(cToken, borrower); + + return Error.NO_ERROR; + } + + /** + * @notice Removes asset from sender's account liquidity calculation + * @dev Sender must not have an outstanding borrow balance in the asset, + * or be providing necessary collateral for an outstanding borrow. + * @param cTokenAddress The address of the asset to be removed + * @return Whether or not the account successfully exited the market + */ + function exitMarket(address cTokenAddress) external returns (uint) { + CToken cToken = CToken(cTokenAddress); + /* Get sender tokensHeld and amountOwed underlying from the cToken */ + (uint oErr, uint tokensHeld, uint amountOwed, ) = cToken.getAccountSnapshot(msg.sender); + require(oErr == 0, "exitMarket: getAccountSnapshot failed"); // semi-opaque error code + + /* Fail if the sender has a borrow balance */ + if (amountOwed != 0) { + return fail(Error.NONZERO_BORROW_BALANCE, FailureInfo.EXIT_MARKET_BALANCE_OWED); + } + + /* Fail if the sender is not permitted to redeem all of their tokens */ + uint allowed = redeemAllowedInternal(cTokenAddress, msg.sender, tokensHeld); + if (allowed != 0) { + return failOpaque(Error.REJECTION, FailureInfo.EXIT_MARKET_REJECTION, allowed); + } + + Market storage marketToExit = markets[address(cToken)]; + + /* Return true if the sender is not already ‘in’ the market */ + if (!marketToExit.accountMembership[msg.sender]) { + return uint(Error.NO_ERROR); + } + + /* Set cToken account membership to false */ + delete marketToExit.accountMembership[msg.sender]; + + /* Delete cToken from the account’s list of assets */ + // load into memory for faster iteration + CToken[] memory userAssetList = accountAssets[msg.sender]; + uint len = userAssetList.length; + uint assetIndex = len; + for (uint i = 0; i < len; i++) { + if (userAssetList[i] == cToken) { + assetIndex = i; + break; + } + } + + // We *must* have found the asset in the list or our redundant data structure is broken + assert(assetIndex < len); + + // copy last item in list to location of item to be removed, reduce length by 1 + CToken[] storage storedList = accountAssets[msg.sender]; + storedList[assetIndex] = storedList[storedList.length - 1]; + storedList.length--; + + emit MarketExited(cToken, msg.sender); + + return uint(Error.NO_ERROR); + } + + /*** Policy Hooks ***/ + + /** + * @notice Checks if the account should be allowed to mint tokens in the given market + * @param cToken The market to verify the mint against + * @param minter The account which would get the minted tokens + * @param mintAmount The amount of underlying being supplied to the market in exchange for tokens + * @return 0 if the mint is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) + */ + function mintAllowed(address cToken, address minter, uint mintAmount) external returns (uint) { + // Pausing is a very serious situation - we revert to sound the alarms + require(!mintGuardianPaused[cToken], "mint is paused"); + + // Shh - currently unused + minter; + mintAmount; + + if (!markets[cToken].isListed) { + return uint(Error.MARKET_NOT_LISTED); + } + + // Keep the flywheel moving + updateCompSupplyIndex(cToken); + distributeSupplierComp(cToken, minter, false); + + return uint(Error.NO_ERROR); + } + + /** + * @notice Validates mint and reverts on rejection. May emit logs. + * @param cToken Asset being minted + * @param minter The address minting the tokens + * @param actualMintAmount The amount of the underlying asset being minted + * @param mintTokens The number of tokens being minted + */ + function mintVerify(address cToken, address minter, uint actualMintAmount, uint mintTokens) external { + // Shh - currently unused + cToken; + minter; + actualMintAmount; + mintTokens; + + // Shh - we don't ever want this hook to be marked pure + if (false) { + maxAssets = maxAssets; + } + } + + /** + * @notice Checks if the account should be allowed to redeem tokens in the given market + * @param cToken The market to verify the redeem against + * @param redeemer The account which would redeem the tokens + * @param redeemTokens The number of cTokens to exchange for the underlying asset in the market + * @return 0 if the redeem is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) + */ + function redeemAllowed(address cToken, address redeemer, uint redeemTokens) external returns (uint) { + uint allowed = redeemAllowedInternal(cToken, redeemer, redeemTokens); + if (allowed != uint(Error.NO_ERROR)) { + return allowed; + } + + // Keep the flywheel moving + updateCompSupplyIndex(cToken); + distributeSupplierComp(cToken, redeemer, false); + + return uint(Error.NO_ERROR); + } + + function redeemAllowedInternal(address cToken, address redeemer, uint redeemTokens) internal view returns (uint) { + if (!markets[cToken].isListed) { + return uint(Error.MARKET_NOT_LISTED); + } + + /* If the redeemer is not 'in' the market, then we can bypass the liquidity check */ + if (!markets[cToken].accountMembership[redeemer]) { + return uint(Error.NO_ERROR); + } + + /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */ + (Error err, , uint shortfall) = getHypotheticalAccountLiquidityInternal(redeemer, CToken(cToken), redeemTokens, 0); + if (err != Error.NO_ERROR) { + return uint(err); + } + if (shortfall > 0) { + return uint(Error.INSUFFICIENT_LIQUIDITY); + } + + return uint(Error.NO_ERROR); + } + + /** + * @notice Validates redeem and reverts on rejection. May emit logs. + * @param cToken Asset being redeemed + * @param redeemer The address redeeming the tokens + * @param redeemAmount The amount of the underlying asset being redeemed + * @param redeemTokens The number of tokens being redeemed + */ + function redeemVerify(address cToken, address redeemer, uint redeemAmount, uint redeemTokens) external { + // Shh - currently unused + cToken; + redeemer; + + // Require tokens is zero or amount is also zero + if (redeemTokens == 0 && redeemAmount > 0) { + revert("redeemTokens zero"); + } + } + + /** + * @notice Checks if the account should be allowed to borrow the underlying asset of the given market + * @param cToken The market to verify the borrow against + * @param borrower The account which would borrow the asset + * @param borrowAmount The amount of underlying the account would borrow + * @return 0 if the borrow is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) + */ + function borrowAllowed(address cToken, address borrower, uint borrowAmount) external returns (uint) { + // Pausing is a very serious situation - we revert to sound the alarms + require(!borrowGuardianPaused[cToken], "borrow is paused"); + + if (!markets[cToken].isListed) { + return uint(Error.MARKET_NOT_LISTED); + } + + if (!markets[cToken].accountMembership[borrower]) { + // only cTokens may call borrowAllowed if borrower not in market + require(msg.sender == cToken, "sender must be cToken"); + + // attempt to add borrower to the market + Error err = addToMarketInternal(CToken(msg.sender), borrower); + if (err != Error.NO_ERROR) { + return uint(err); + } + + // it should be impossible to break the important invariant + assert(markets[cToken].accountMembership[borrower]); + } + + if (oracle.getUnderlyingPrice(CToken(cToken)) == 0) { + return uint(Error.PRICE_ERROR); + } + + + uint borrowCap = borrowCaps[cToken]; + // Borrow cap of 0 corresponds to unlimited borrowing + if (borrowCap != 0) { + uint totalBorrows = CToken(cToken).totalBorrows(); + uint nextTotalBorrows = add_(totalBorrows, borrowAmount); + require(nextTotalBorrows < borrowCap, "market borrow cap reached"); + } + + (Error err, , uint shortfall) = getHypotheticalAccountLiquidityInternal(borrower, CToken(cToken), 0, borrowAmount); + if (err != Error.NO_ERROR) { + return uint(err); + } + if (shortfall > 0) { + return uint(Error.INSUFFICIENT_LIQUIDITY); + } + + // Keep the flywheel moving + Exp memory borrowIndex = Exp({mantissa: CToken(cToken).borrowIndex()}); + updateCompBorrowIndex(cToken, borrowIndex); + distributeBorrowerComp(cToken, borrower, borrowIndex, false); + + return uint(Error.NO_ERROR); + } + + /** + * @notice Validates borrow and reverts on rejection. May emit logs. + * @param cToken Asset whose underlying is being borrowed + * @param borrower The address borrowing the underlying + * @param borrowAmount The amount of the underlying asset requested to borrow + */ + function borrowVerify(address cToken, address borrower, uint borrowAmount) external { + // Shh - currently unused + cToken; + borrower; + borrowAmount; + + // Shh - we don't ever want this hook to be marked pure + if (false) { + maxAssets = maxAssets; + } + } + + /** + * @notice Checks if the account should be allowed to repay a borrow in the given market + * @param cToken The market to verify the repay against + * @param payer The account which would repay the asset + * @param borrower The account which would borrowed the asset + * @param repayAmount The amount of the underlying asset the account would repay + * @return 0 if the repay is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) + */ + function repayBorrowAllowed( + address cToken, + address payer, + address borrower, + uint repayAmount) external returns (uint) { + // Shh - currently unused + payer; + borrower; + repayAmount; + + if (!markets[cToken].isListed) { + return uint(Error.MARKET_NOT_LISTED); + } + + // Keep the flywheel moving + Exp memory borrowIndex = Exp({mantissa: CToken(cToken).borrowIndex()}); + updateCompBorrowIndex(cToken, borrowIndex); + distributeBorrowerComp(cToken, borrower, borrowIndex, false); + + return uint(Error.NO_ERROR); + } + + /** + * @notice Validates repayBorrow and reverts on rejection. May emit logs. + * @param cToken Asset being repaid + * @param payer The address repaying the borrow + * @param borrower The address of the borrower + * @param actualRepayAmount The amount of underlying being repaid + */ + function repayBorrowVerify( + address cToken, + address payer, + address borrower, + uint actualRepayAmount, + uint borrowerIndex) external { + // Shh - currently unused + cToken; + payer; + borrower; + actualRepayAmount; + borrowerIndex; + + // Shh - we don't ever want this hook to be marked pure + if (false) { + maxAssets = maxAssets; + } + } + + /** + * @notice Checks if the liquidation should be allowed to occur + * @param cTokenBorrowed Asset which was borrowed by the borrower + * @param cTokenCollateral Asset which was used as collateral and will be seized + * @param liquidator The address repaying the borrow and seizing the collateral + * @param borrower The address of the borrower + * @param repayAmount The amount of underlying being repaid + */ + function liquidateBorrowAllowed( + address cTokenBorrowed, + address cTokenCollateral, + address liquidator, + address borrower, + uint repayAmount) external returns (uint) { + // Shh - currently unused + liquidator; + + if (!markets[cTokenBorrowed].isListed || !markets[cTokenCollateral].isListed) { + return uint(Error.MARKET_NOT_LISTED); + } + + /* The borrower must have shortfall in order to be liquidatable */ + (Error err, , uint shortfall) = getAccountLiquidityInternal(borrower); + if (err != Error.NO_ERROR) { + return uint(err); + } + if (shortfall == 0) { + return uint(Error.INSUFFICIENT_SHORTFALL); + } + + /* The liquidator may not repay more than what is allowed by the closeFactor */ + uint borrowBalance = CToken(cTokenBorrowed).borrowBalanceStored(borrower); + uint maxClose = mul_ScalarTruncate(Exp({mantissa: closeFactorMantissa}), borrowBalance); + if (repayAmount > maxClose) { + return uint(Error.TOO_MUCH_REPAY); + } + + return uint(Error.NO_ERROR); + } + + /** + * @notice Validates liquidateBorrow and reverts on rejection. May emit logs. + * @param cTokenBorrowed Asset which was borrowed by the borrower + * @param cTokenCollateral Asset which was used as collateral and will be seized + * @param liquidator The address repaying the borrow and seizing the collateral + * @param borrower The address of the borrower + * @param actualRepayAmount The amount of underlying being repaid + */ + function liquidateBorrowVerify( + address cTokenBorrowed, + address cTokenCollateral, + address liquidator, + address borrower, + uint actualRepayAmount, + uint seizeTokens) external { + // Shh - currently unused + cTokenBorrowed; + cTokenCollateral; + liquidator; + borrower; + actualRepayAmount; + seizeTokens; + + // Shh - we don't ever want this hook to be marked pure + if (false) { + maxAssets = maxAssets; + } + } + + /** + * @notice Checks if the seizing of assets should be allowed to occur + * @param cTokenCollateral Asset which was used as collateral and will be seized + * @param cTokenBorrowed Asset which was borrowed by the borrower + * @param liquidator The address repaying the borrow and seizing the collateral + * @param borrower The address of the borrower + * @param seizeTokens The number of collateral tokens to seize + */ + function seizeAllowed( + address cTokenCollateral, + address cTokenBorrowed, + address liquidator, + address borrower, + uint seizeTokens) external returns (uint) { + // Pausing is a very serious situation - we revert to sound the alarms + require(!seizeGuardianPaused, "seize is paused"); + + // Shh - currently unused + seizeTokens; + + if (!markets[cTokenCollateral].isListed || !markets[cTokenBorrowed].isListed) { + return uint(Error.MARKET_NOT_LISTED); + } + + if (CToken(cTokenCollateral).comptroller() != CToken(cTokenBorrowed).comptroller()) { + return uint(Error.COMPTROLLER_MISMATCH); + } + + // Keep the flywheel moving + updateCompSupplyIndex(cTokenCollateral); + distributeSupplierComp(cTokenCollateral, borrower, false); + distributeSupplierComp(cTokenCollateral, liquidator, false); + + return uint(Error.NO_ERROR); + } + + /** + * @notice Validates seize and reverts on rejection. May emit logs. + * @param cTokenCollateral Asset which was used as collateral and will be seized + * @param cTokenBorrowed Asset which was borrowed by the borrower + * @param liquidator The address repaying the borrow and seizing the collateral + * @param borrower The address of the borrower + * @param seizeTokens The number of collateral tokens to seize + */ + function seizeVerify( + address cTokenCollateral, + address cTokenBorrowed, + address liquidator, + address borrower, + uint seizeTokens) external { + // Shh - currently unused + cTokenCollateral; + cTokenBorrowed; + liquidator; + borrower; + seizeTokens; + + // Shh - we don't ever want this hook to be marked pure + if (false) { + maxAssets = maxAssets; + } + } + + /** + * @notice Checks if the account should be allowed to transfer tokens in the given market + * @param cToken The market to verify the transfer against + * @param src The account which sources the tokens + * @param dst The account which receives the tokens + * @param transferTokens The number of cTokens to transfer + * @return 0 if the transfer is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) + */ + function transferAllowed(address cToken, address src, address dst, uint transferTokens) external returns (uint) { + // Pausing is a very serious situation - we revert to sound the alarms + require(!transferGuardianPaused, "transfer is paused"); + + // Currently the only consideration is whether or not + // the src is allowed to redeem this many tokens + uint allowed = redeemAllowedInternal(cToken, src, transferTokens); + if (allowed != uint(Error.NO_ERROR)) { + return allowed; + } + + // Keep the flywheel moving + updateCompSupplyIndex(cToken); + distributeSupplierComp(cToken, src, false); + distributeSupplierComp(cToken, dst, false); + + return uint(Error.NO_ERROR); + } + + /** + * @notice Validates transfer and reverts on rejection. May emit logs. + * @param cToken Asset being transferred + * @param src The account which sources the tokens + * @param dst The account which receives the tokens + * @param transferTokens The number of cTokens to transfer + */ + function transferVerify(address cToken, address src, address dst, uint transferTokens) external { + // Shh - currently unused + cToken; + src; + dst; + transferTokens; + + // Shh - we don't ever want this hook to be marked pure + if (false) { + maxAssets = maxAssets; + } + } + + /*** Liquidity/Liquidation Calculations ***/ + + /** + * @dev Local vars for avoiding stack-depth limits in calculating account liquidity. + * Note that `cTokenBalance` is the number of cTokens the account owns in the market, + * whereas `borrowBalance` is the amount of underlying that the account has borrowed. + */ + struct AccountLiquidityLocalVars { + uint sumCollateral; + uint sumBorrowPlusEffects; + uint cTokenBalance; + uint borrowBalance; + uint exchangeRateMantissa; + uint oraclePriceMantissa; + Exp collateralFactor; + Exp exchangeRate; + Exp oraclePrice; + Exp tokensToDenom; + } + + /** + * @notice Determine the current account liquidity wrt collateral requirements + * @return (possible error code (semi-opaque), + account liquidity in excess of collateral requirements, + * account shortfall below collateral requirements) + */ + function getAccountLiquidity(address account) public view returns (uint, uint, uint) { + (Error err, uint liquidity, uint shortfall) = getHypotheticalAccountLiquidityInternal(account, CToken(0), 0, 0); + + return (uint(err), liquidity, shortfall); + } + + /** + * @notice Determine the current account liquidity wrt collateral requirements + * @return (possible error code, + account liquidity in excess of collateral requirements, + * account shortfall below collateral requirements) + */ + function getAccountLiquidityInternal(address account) internal view returns (Error, uint, uint) { + return getHypotheticalAccountLiquidityInternal(account, CToken(0), 0, 0); + } + + /** + * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed + * @param cTokenModify The market to hypothetically redeem/borrow in + * @param account The account to determine liquidity for + * @param redeemTokens The number of tokens to hypothetically redeem + * @param borrowAmount The amount of underlying to hypothetically borrow + * @return (possible error code (semi-opaque), + hypothetical account liquidity in excess of collateral requirements, + * hypothetical account shortfall below collateral requirements) + */ + function getHypotheticalAccountLiquidity( + address account, + address cTokenModify, + uint redeemTokens, + uint borrowAmount) public view returns (uint, uint, uint) { + (Error err, uint liquidity, uint shortfall) = getHypotheticalAccountLiquidityInternal(account, CToken(cTokenModify), redeemTokens, borrowAmount); + return (uint(err), liquidity, shortfall); + } + + /** + * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed + * @param cTokenModify The market to hypothetically redeem/borrow in + * @param account The account to determine liquidity for + * @param redeemTokens The number of tokens to hypothetically redeem + * @param borrowAmount The amount of underlying to hypothetically borrow + * @dev Note that we calculate the exchangeRateStored for each collateral cToken using stored data, + * without calculating accumulated interest. + * @return (possible error code, + hypothetical account liquidity in excess of collateral requirements, + * hypothetical account shortfall below collateral requirements) + */ + function getHypotheticalAccountLiquidityInternal( + address account, + CToken cTokenModify, + uint redeemTokens, + uint borrowAmount) internal view returns (Error, uint, uint) { + + AccountLiquidityLocalVars memory vars; // Holds all our calculation results + uint oErr; + + // For each asset the account is in + CToken[] memory assets = accountAssets[account]; + for (uint i = 0; i < assets.length; i++) { + CToken asset = assets[i]; + + // Read the balances and exchange rate from the cToken + (oErr, vars.cTokenBalance, vars.borrowBalance, vars.exchangeRateMantissa) = asset.getAccountSnapshot(account); + if (oErr != 0) { // semi-opaque error code, we assume NO_ERROR == 0 is invariant between upgrades + return (Error.SNAPSHOT_ERROR, 0, 0); + } + vars.collateralFactor = Exp({mantissa: markets[address(asset)].collateralFactorMantissa}); + vars.exchangeRate = Exp({mantissa: vars.exchangeRateMantissa}); + + // Get the normalized price of the asset + vars.oraclePriceMantissa = oracle.getUnderlyingPrice(asset); + if (vars.oraclePriceMantissa == 0) { + return (Error.PRICE_ERROR, 0, 0); + } + vars.oraclePrice = Exp({mantissa: vars.oraclePriceMantissa}); + + // Pre-compute a conversion factor from tokens -> ether (normalized price value) + vars.tokensToDenom = mul_(mul_(vars.collateralFactor, vars.exchangeRate), vars.oraclePrice); + + // sumCollateral += tokensToDenom * cTokenBalance + vars.sumCollateral = mul_ScalarTruncateAddUInt(vars.tokensToDenom, vars.cTokenBalance, vars.sumCollateral); + + // sumBorrowPlusEffects += oraclePrice * borrowBalance + vars.sumBorrowPlusEffects = mul_ScalarTruncateAddUInt(vars.oraclePrice, vars.borrowBalance, vars.sumBorrowPlusEffects); + + // Calculate effects of interacting with cTokenModify + if (asset == cTokenModify) { + // redeem effect + // sumBorrowPlusEffects += tokensToDenom * redeemTokens + vars.sumBorrowPlusEffects = mul_ScalarTruncateAddUInt(vars.tokensToDenom, redeemTokens, vars.sumBorrowPlusEffects); + + // borrow effect + // sumBorrowPlusEffects += oraclePrice * borrowAmount + vars.sumBorrowPlusEffects = mul_ScalarTruncateAddUInt(vars.oraclePrice, borrowAmount, vars.sumBorrowPlusEffects); + } + } + + // These are safe, as the underflow condition is checked first + if (vars.sumCollateral > vars.sumBorrowPlusEffects) { + return (Error.NO_ERROR, vars.sumCollateral - vars.sumBorrowPlusEffects, 0); + } else { + return (Error.NO_ERROR, 0, vars.sumBorrowPlusEffects - vars.sumCollateral); + } + } + + /** + * @notice Calculate number of tokens of collateral asset to seize given an underlying amount + * @dev Used in liquidation (called in cToken.liquidateBorrowFresh) + * @param cTokenBorrowed The address of the borrowed cToken + * @param cTokenCollateral The address of the collateral cToken + * @param actualRepayAmount The amount of cTokenBorrowed underlying to convert into cTokenCollateral tokens + * @return (errorCode, number of cTokenCollateral tokens to be seized in a liquidation) + */ + function liquidateCalculateSeizeTokens(address cTokenBorrowed, address cTokenCollateral, uint actualRepayAmount) external view returns (uint, uint) { + /* Read oracle prices for borrowed and collateral markets */ + uint priceBorrowedMantissa = oracle.getUnderlyingPrice(CToken(cTokenBorrowed)); + uint priceCollateralMantissa = oracle.getUnderlyingPrice(CToken(cTokenCollateral)); + if (priceBorrowedMantissa == 0 || priceCollateralMantissa == 0) { + return (uint(Error.PRICE_ERROR), 0); + } + + /* + * Get the exchange rate and calculate the number of collateral tokens to seize: + * seizeAmount = actualRepayAmount * liquidationIncentive * priceBorrowed / priceCollateral + * seizeTokens = seizeAmount / exchangeRate + * = actualRepayAmount * (liquidationIncentive * priceBorrowed) / (priceCollateral * exchangeRate) + */ + uint exchangeRateMantissa = CToken(cTokenCollateral).exchangeRateStored(); // Note: reverts on error + uint seizeTokens; + Exp memory numerator; + Exp memory denominator; + Exp memory ratio; + + numerator = mul_(Exp({mantissa: liquidationIncentiveMantissa}), Exp({mantissa: priceBorrowedMantissa})); + denominator = mul_(Exp({mantissa: priceCollateralMantissa}), Exp({mantissa: exchangeRateMantissa})); + ratio = div_(numerator, denominator); + + seizeTokens = mul_ScalarTruncate(ratio, actualRepayAmount); + + return (uint(Error.NO_ERROR), seizeTokens); + } + + /*** Admin Functions ***/ + + /** + * @notice Sets a new price oracle for the comptroller + * @dev Admin function to set a new price oracle + * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) + */ + function _setPriceOracle(PriceOracle newOracle) public returns (uint) { + // Check caller is admin + if (msg.sender != admin) { + return fail(Error.UNAUTHORIZED, FailureInfo.SET_PRICE_ORACLE_OWNER_CHECK); + } + + // Track the old oracle for the comptroller + PriceOracle oldOracle = oracle; + + // Set comptroller's oracle to newOracle + oracle = newOracle; + + // Emit NewPriceOracle(oldOracle, newOracle) + emit NewPriceOracle(oldOracle, newOracle); + + return uint(Error.NO_ERROR); + } + + /** + * @notice Sets the closeFactor used when liquidating borrows + * @dev Admin function to set closeFactor + * @param newCloseFactorMantissa New close factor, scaled by 1e18 + * @return uint 0=success, otherwise a failure + */ + function _setCloseFactor(uint newCloseFactorMantissa) external returns (uint) { + // Check caller is admin + require(msg.sender == admin, "only admin can set close factor"); + + uint oldCloseFactorMantissa = closeFactorMantissa; + closeFactorMantissa = newCloseFactorMantissa; + emit NewCloseFactor(oldCloseFactorMantissa, closeFactorMantissa); + + return uint(Error.NO_ERROR); + } + + /** + * @notice Sets the collateralFactor for a market + * @dev Admin function to set per-market collateralFactor + * @param cToken The market to set the factor on + * @param newCollateralFactorMantissa The new collateral factor, scaled by 1e18 + * @return uint 0=success, otherwise a failure. (See ErrorReporter for details) + */ + function _setCollateralFactor(CToken cToken, uint newCollateralFactorMantissa) external returns (uint) { + // Check caller is admin + if (msg.sender != admin) { + return fail(Error.UNAUTHORIZED, FailureInfo.SET_COLLATERAL_FACTOR_OWNER_CHECK); + } + + // Verify market is listed + Market storage market = markets[address(cToken)]; + if (!market.isListed) { + return fail(Error.MARKET_NOT_LISTED, FailureInfo.SET_COLLATERAL_FACTOR_NO_EXISTS); + } + + Exp memory newCollateralFactorExp = Exp({mantissa: newCollateralFactorMantissa}); + + // Check collateral factor <= 0.9 + Exp memory highLimit = Exp({mantissa: collateralFactorMaxMantissa}); + if (lessThanExp(highLimit, newCollateralFactorExp)) { + return fail(Error.INVALID_COLLATERAL_FACTOR, FailureInfo.SET_COLLATERAL_FACTOR_VALIDATION); + } + + // If collateral factor != 0, fail if price == 0 + if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(cToken) == 0) { + return fail(Error.PRICE_ERROR, FailureInfo.SET_COLLATERAL_FACTOR_WITHOUT_PRICE); + } + + // Set market's collateral factor to new collateral factor, remember old value + uint oldCollateralFactorMantissa = market.collateralFactorMantissa; + market.collateralFactorMantissa = newCollateralFactorMantissa; + + // Emit event with asset, old collateral factor, and new collateral factor + emit NewCollateralFactor(cToken, oldCollateralFactorMantissa, newCollateralFactorMantissa); + + return uint(Error.NO_ERROR); + } + + /** + * @notice Sets liquidationIncentive + * @dev Admin function to set liquidationIncentive + * @param newLiquidationIncentiveMantissa New liquidationIncentive scaled by 1e18 + * @return uint 0=success, otherwise a failure. (See ErrorReporter for details) + */ + function _setLiquidationIncentive(uint newLiquidationIncentiveMantissa) external returns (uint) { + // Check caller is admin + if (msg.sender != admin) { + return fail(Error.UNAUTHORIZED, FailureInfo.SET_LIQUIDATION_INCENTIVE_OWNER_CHECK); + } + + // Save current value for use in log + uint oldLiquidationIncentiveMantissa = liquidationIncentiveMantissa; + + // Set liquidation incentive to new incentive + liquidationIncentiveMantissa = newLiquidationIncentiveMantissa; + + // Emit event with old incentive, new incentive + emit NewLiquidationIncentive(oldLiquidationIncentiveMantissa, newLiquidationIncentiveMantissa); + + return uint(Error.NO_ERROR); + } + + /** + * @notice Add the market to the markets mapping and set it as listed + * @dev Admin function to set isListed and add support for the market + * @param cToken The address of the market (token) to list + * @return uint 0=success, otherwise a failure. (See enum Error for details) + */ + function _supportMarket(CToken cToken) external returns (uint) { + if (msg.sender != admin) { + return fail(Error.UNAUTHORIZED, FailureInfo.SUPPORT_MARKET_OWNER_CHECK); + } + + if (markets[address(cToken)].isListed) { + return fail(Error.MARKET_ALREADY_LISTED, FailureInfo.SUPPORT_MARKET_EXISTS); + } + + cToken.isCToken(); // Sanity check to make sure its really a CToken + + markets[address(cToken)] = Market({isListed: true, isComped: false, collateralFactorMantissa: 0}); + + _addMarketInternal(address(cToken)); + + emit MarketListed(cToken); + + return uint(Error.NO_ERROR); + } + + function _addMarketInternal(address cToken) internal { + for (uint i = 0; i < allMarkets.length; i ++) { + require(allMarkets[i] != CToken(cToken), "market already added"); + } + allMarkets.push(CToken(cToken)); + } + + + /** + * @notice Set the given borrow caps for the given cToken markets. Borrowing that brings total borrows to or above borrow cap will revert. + * @dev Admin or borrowCapGuardian function to set the borrow caps. A borrow cap of 0 corresponds to unlimited borrowing. + * @param cTokens The addresses of the markets (tokens) to change the borrow caps for + * @param newBorrowCaps The new borrow cap values in underlying to be set. A value of 0 corresponds to unlimited borrowing. + */ + function _setMarketBorrowCaps(CToken[] calldata cTokens, uint[] calldata newBorrowCaps) external { + require(msg.sender == admin || msg.sender == borrowCapGuardian, "only admin or borrow cap guardian can set borrow caps"); + + uint numMarkets = cTokens.length; + uint numBorrowCaps = newBorrowCaps.length; + + require(numMarkets != 0 && numMarkets == numBorrowCaps, "invalid input"); + + for(uint i = 0; i < numMarkets; i++) { + borrowCaps[address(cTokens[i])] = newBorrowCaps[i]; + emit NewBorrowCap(cTokens[i], newBorrowCaps[i]); + } + } + + /** + * @notice Admin function to change the Borrow Cap Guardian + * @param newBorrowCapGuardian The address of the new Borrow Cap Guardian + */ + function _setBorrowCapGuardian(address newBorrowCapGuardian) external { + require(msg.sender == admin, "only admin can set borrow cap guardian"); + + // Save current value for inclusion in log + address oldBorrowCapGuardian = borrowCapGuardian; + + // Store borrowCapGuardian with value newBorrowCapGuardian + borrowCapGuardian = newBorrowCapGuardian; + + // Emit NewBorrowCapGuardian(OldBorrowCapGuardian, NewBorrowCapGuardian) + emit NewBorrowCapGuardian(oldBorrowCapGuardian, newBorrowCapGuardian); + } + + /** + * @notice Admin function to change the Pause Guardian + * @param newPauseGuardian The address of the new Pause Guardian + * @return uint 0=success, otherwise a failure. (See enum Error for details) + */ + function _setPauseGuardian(address newPauseGuardian) public returns (uint) { + if (msg.sender != admin) { + return fail(Error.UNAUTHORIZED, FailureInfo.SET_PAUSE_GUARDIAN_OWNER_CHECK); + } + + // Save current value for inclusion in log + address oldPauseGuardian = pauseGuardian; + + // Store pauseGuardian with value newPauseGuardian + pauseGuardian = newPauseGuardian; + + // Emit NewPauseGuardian(OldPauseGuardian, NewPauseGuardian) + emit NewPauseGuardian(oldPauseGuardian, pauseGuardian); + + return uint(Error.NO_ERROR); + } + + function _setMintPaused(CToken cToken, bool state) public returns (bool) { + require(markets[address(cToken)].isListed, "cannot pause a market that is not listed"); + require(msg.sender == pauseGuardian || msg.sender == admin, "only pause guardian and admin can pause"); + require(msg.sender == admin || state == true, "only admin can unpause"); + + mintGuardianPaused[address(cToken)] = state; + emit ActionPaused(cToken, "Mint", state); + return state; + } + + function _setBorrowPaused(CToken cToken, bool state) public returns (bool) { + require(markets[address(cToken)].isListed, "cannot pause a market that is not listed"); + require(msg.sender == pauseGuardian || msg.sender == admin, "only pause guardian and admin can pause"); + require(msg.sender == admin || state == true, "only admin can unpause"); + + borrowGuardianPaused[address(cToken)] = state; + emit ActionPaused(cToken, "Borrow", state); + return state; + } + + function _setTransferPaused(bool state) public returns (bool) { + require(msg.sender == pauseGuardian || msg.sender == admin, "only pause guardian and admin can pause"); + require(msg.sender == admin || state == true, "only admin can unpause"); + + transferGuardianPaused = state; + emit ActionPaused("Transfer", state); + return state; + } + + function _setSeizePaused(bool state) public returns (bool) { + require(msg.sender == pauseGuardian || msg.sender == admin, "only pause guardian and admin can pause"); + require(msg.sender == admin || state == true, "only admin can unpause"); + + seizeGuardianPaused = state; + emit ActionPaused("Seize", state); + return state; + } + + function _become(Unitroller unitroller) public { + require(msg.sender == unitroller.admin(), "only unitroller admin can change brains"); + require(unitroller._acceptImplementation() == 0, "change not authorized"); + } + + /** + * @notice Checks caller is admin, or this contract is becoming the new implementation + */ + function adminOrInitializing() internal view returns (bool) { + return msg.sender == admin || msg.sender == comptrollerImplementation; + } + + /*** Comp Distribution ***/ + + /** + * @notice Recalculate and update COMP speeds for all COMP markets + */ + function refreshCompSpeeds() public { + require(msg.sender == tx.origin, "only externally owned accounts may refresh speeds"); + refreshCompSpeedsInternal(); + } + + function refreshCompSpeedsInternal() internal { + CToken[] memory allMarkets_ = allMarkets; + + for (uint i = 0; i < allMarkets_.length; i++) { + CToken cToken = allMarkets_[i]; + Exp memory borrowIndex = Exp({mantissa: cToken.borrowIndex()}); + updateCompSupplyIndex(address(cToken)); + updateCompBorrowIndex(address(cToken), borrowIndex); + } + + Exp memory totalUtility = Exp({mantissa: 0}); + Exp[] memory utilities = new Exp[](allMarkets_.length); + for (uint i = 0; i < allMarkets_.length; i++) { + CToken cToken = allMarkets_[i]; + if (markets[address(cToken)].isComped) { + Exp memory assetPrice = Exp({mantissa: oracle.getUnderlyingPrice(cToken)}); + Exp memory utility = mul_(assetPrice, cToken.totalBorrows()); + utilities[i] = utility; + totalUtility = add_(totalUtility, utility); + } + } + + for (uint i = 0; i < allMarkets_.length; i++) { + CToken cToken = allMarkets[i]; + uint newSpeed = totalUtility.mantissa > 0 ? mul_(compRate, div_(utilities[i], totalUtility)) : 0; + compSpeeds[address(cToken)] = newSpeed; + emit CompSpeedUpdated(cToken, newSpeed); + } + } + + /** + * @notice Accrue COMP to the market by updating the supply index + * @param cToken The market whose supply index to update + */ + function updateCompSupplyIndex(address cToken) internal { + CompMarketState storage supplyState = compSupplyState[cToken]; + uint supplySpeed = compSpeeds[cToken]; + uint blockNumber = getBlockNumber(); + uint deltaBlocks = sub_(blockNumber, uint(supplyState.block)); + if (deltaBlocks > 0 && supplySpeed > 0) { + uint supplyTokens = CToken(cToken).totalSupply(); + uint compAccrued = mul_(deltaBlocks, supplySpeed); + Double memory ratio = supplyTokens > 0 ? fraction(compAccrued, supplyTokens) : Double({mantissa: 0}); + Double memory index = add_(Double({mantissa: supplyState.index}), ratio); + compSupplyState[cToken] = CompMarketState({ + index: safe224(index.mantissa, "new index exceeds 224 bits"), + block: safe32(blockNumber, "block number exceeds 32 bits") + }); + } else if (deltaBlocks > 0) { + supplyState.block = safe32(blockNumber, "block number exceeds 32 bits"); + } + } + + /** + * @notice Accrue COMP to the market by updating the borrow index + * @param cToken The market whose borrow index to update + */ + function updateCompBorrowIndex(address cToken, Exp memory marketBorrowIndex) internal { + CompMarketState storage borrowState = compBorrowState[cToken]; + uint borrowSpeed = compSpeeds[cToken]; + uint blockNumber = getBlockNumber(); + uint deltaBlocks = sub_(blockNumber, uint(borrowState.block)); + if (deltaBlocks > 0 && borrowSpeed > 0) { + uint borrowAmount = div_(CToken(cToken).totalBorrows(), marketBorrowIndex); + uint compAccrued = mul_(deltaBlocks, borrowSpeed); + Double memory ratio = borrowAmount > 0 ? fraction(compAccrued, borrowAmount) : Double({mantissa: 0}); + Double memory index = add_(Double({mantissa: borrowState.index}), ratio); + compBorrowState[cToken] = CompMarketState({ + index: safe224(index.mantissa, "new index exceeds 224 bits"), + block: safe32(blockNumber, "block number exceeds 32 bits") + }); + } else if (deltaBlocks > 0) { + borrowState.block = safe32(blockNumber, "block number exceeds 32 bits"); + } + } + + /** + * @notice Calculate COMP accrued by a supplier and possibly transfer it to them + * @param cToken The market in which the supplier is interacting + * @param supplier The address of the supplier to distribute COMP to + */ + function distributeSupplierComp(address cToken, address supplier, bool distributeAll) internal { + CompMarketState storage supplyState = compSupplyState[cToken]; + Double memory supplyIndex = Double({mantissa: supplyState.index}); + Double memory supplierIndex = Double({mantissa: compSupplierIndex[cToken][supplier]}); + compSupplierIndex[cToken][supplier] = supplyIndex.mantissa; + + if (supplierIndex.mantissa == 0 && supplyIndex.mantissa > 0) { + supplierIndex.mantissa = compInitialIndex; + } + + Double memory deltaIndex = sub_(supplyIndex, supplierIndex); + uint supplierTokens = CToken(cToken).balanceOf(supplier); + uint supplierDelta = mul_(supplierTokens, deltaIndex); + uint supplierAccrued = add_(compAccrued[supplier], supplierDelta); + compAccrued[supplier] = transferComp(supplier, supplierAccrued, distributeAll ? 0 : compClaimThreshold); + emit DistributedSupplierComp(CToken(cToken), supplier, supplierDelta, supplyIndex.mantissa); + } + + /** + * @notice Calculate COMP accrued by a borrower and possibly transfer it to them + * @dev Borrowers will not begin to accrue until after the first interaction with the protocol. + * @param cToken The market in which the borrower is interacting + * @param borrower The address of the borrower to distribute COMP to + */ + function distributeBorrowerComp(address cToken, address borrower, Exp memory marketBorrowIndex, bool distributeAll) internal { + CompMarketState storage borrowState = compBorrowState[cToken]; + Double memory borrowIndex = Double({mantissa: borrowState.index}); + Double memory borrowerIndex = Double({mantissa: compBorrowerIndex[cToken][borrower]}); + compBorrowerIndex[cToken][borrower] = borrowIndex.mantissa; + + if (borrowerIndex.mantissa > 0) { + Double memory deltaIndex = sub_(borrowIndex, borrowerIndex); + uint borrowerAmount = div_(CToken(cToken).borrowBalanceStored(borrower), marketBorrowIndex); + uint borrowerDelta = mul_(borrowerAmount, deltaIndex); + uint borrowerAccrued = add_(compAccrued[borrower], borrowerDelta); + compAccrued[borrower] = transferComp(borrower, borrowerAccrued, distributeAll ? 0 : compClaimThreshold); + emit DistributedBorrowerComp(CToken(cToken), borrower, borrowerDelta, borrowIndex.mantissa); + } + } + + /** + * @notice Transfer COMP to the user, if they are above the threshold + * @dev Note: If there is not enough COMP, we do not perform the transfer all. + * @param user The address of the user to transfer COMP to + * @param userAccrued The amount of COMP to (possibly) transfer + * @return The amount of COMP which was NOT transferred to the user + */ + function transferComp(address user, uint userAccrued, uint threshold) internal returns (uint) { + if (userAccrued >= threshold && userAccrued > 0) { + Comp comp = Comp(getCompAddress()); + uint compRemaining = comp.balanceOf(address(this)); + if (userAccrued <= compRemaining) { + comp.transfer(user, userAccrued); + return 0; + } + } + return userAccrued; + } + + /** + * @notice Calculate additional accrued COMP for a contributor since last accrual + * @param contributor The address to calculate contributor rewards for + */ + function updateContributorRewards(address contributor) public { + uint compSpeed = compContributorSpeeds[contributor]; + uint blockNumber = getBlockNumber(); + uint deltaBlocks = sub_(blockNumber, lastContributorBlock[contributor]); + if (deltaBlocks > 0 && compSpeed > 0) { + uint newAccrued = mul_(deltaBlocks, compSpeed); + uint contributorAccrued = add_(compAccrued[contributor], newAccrued); + + compAccrued[contributor] = contributorAccrued; + lastContributorBlock[contributor] = blockNumber; + } + } + + /** + * @notice Claim all the comp accrued by holder in all markets + * @param holder The address to claim COMP for + */ + function claimComp(address holder) public { + return claimComp(holder, allMarkets); + } + + /** + * @notice Claim all the comp accrued by holder in the specified markets + * @param holder The address to claim COMP for + * @param cTokens The list of markets to claim COMP in + */ + function claimComp(address holder, CToken[] memory cTokens) public { + address[] memory holders = new address[](1); + holders[0] = holder; + claimComp(holders, cTokens, true, true); + } + + /** + * @notice Claim all comp accrued by the holders + * @param holders The addresses to claim COMP for + * @param cTokens The list of markets to claim COMP in + * @param borrowers Whether or not to claim COMP earned by borrowing + * @param suppliers Whether or not to claim COMP earned by supplying + */ + function claimComp(address[] memory holders, CToken[] memory cTokens, bool borrowers, bool suppliers) public { + for (uint i = 0; i < cTokens.length; i++) { + CToken cToken = cTokens[i]; + require(markets[address(cToken)].isListed, "market must be listed"); + if (borrowers == true) { + Exp memory borrowIndex = Exp({mantissa: cToken.borrowIndex()}); + updateCompBorrowIndex(address(cToken), borrowIndex); + for (uint j = 0; j < holders.length; j++) { + distributeBorrowerComp(address(cToken), holders[j], borrowIndex, true); + } + } + if (suppliers == true) { + updateCompSupplyIndex(address(cToken)); + for (uint j = 0; j < holders.length; j++) { + distributeSupplierComp(address(cToken), holders[j], true); + } + } + } + } + + /** + * @notice Transfer COMP to the user + * @dev Note: If there is not enough COMP, we do not perform the transfer all. + * @param user The address of the user to transfer COMP to + * @param amount The amount of COMP to (possibly) transfer + * @return The amount of COMP which was NOT transferred to the user + */ + function grantCompInternal(address user, uint amount) internal returns (uint) { + Comp comp = Comp(getCompAddress()); + uint compRemaining = comp.balanceOf(address(this)); + if (amount <= compRemaining) { + comp.transfer(user, amount); + return 0; + } + return amount; + } + + /*** Comp Distribution Admin ***/ + + /** + * @notice Transfer COMP to the recipient + * @dev Note: If there is not enough COMP, we do not perform the transfer all. + * @param recipient The address of the recipient to transfer COMP to + * @param amount The amount of COMP to (possibly) transfer + */ + function _grantComp(address recipient, uint amount) public { + require(adminOrInitializing(), "only admin can grant comp"); + uint amountLeft = grantCompInternal(recipient, amount); + require(amountLeft == 0, "insufficient comp for grant"); + emit CompGranted(recipient, amount); + } + + /** + * @notice Set COMP speed for a single contributor + * @param contributor The contributor whose COMP speed to update + * @param compSpeed New COMP speed for contributor + */ + function _setContributorCompSpeed(address contributor, uint compSpeed) public { + require(adminOrInitializing(), "only admin can set comp speed"); + + // note that COMP speed could be set to 0 to halt liquidity rewards for a contributor + updateContributorRewards(contributor); + if (compSpeed == 0) { + // release storage + delete lastContributorBlock[contributor]; + } + lastContributorBlock[contributor] = getBlockNumber(); + compContributorSpeeds[contributor] = compSpeed; + + emit ContributorCompSpeedUpdated(contributor, compSpeed); + } + + /** + * @notice Set the amount of COMP distributed per block + * @param compRate_ The amount of COMP wei per block to distribute + */ + function _setCompRate(uint compRate_) public { + require(adminOrInitializing(), "only admin can change comp rate"); + + uint oldRate = compRate; + compRate = compRate_; + emit NewCompRate(oldRate, compRate_); + + refreshCompSpeedsInternal(); + } + + /** + * @notice Add markets to compMarkets, allowing them to earn COMP in the flywheel + * @param cTokens The addresses of the markets to add + */ + function _addCompMarkets(address[] memory cTokens) public { + require(adminOrInitializing(), "only admin can add comp market"); + + for (uint i = 0; i < cTokens.length; i++) { + _addCompMarketInternal(cTokens[i]); + } + + refreshCompSpeedsInternal(); + } + + function _addCompMarketInternal(address cToken) internal { + Market storage market = markets[cToken]; + require(market.isListed == true, "comp market is not listed"); + require(market.isComped == false, "comp market already added"); + + market.isComped = true; + emit MarketComped(CToken(cToken), true); + + if (compSupplyState[cToken].index == 0 && compSupplyState[cToken].block == 0) { + compSupplyState[cToken] = CompMarketState({ + index: compInitialIndex, + block: safe32(getBlockNumber(), "block number exceeds 32 bits") + }); + } + + if (compBorrowState[cToken].index == 0 && compBorrowState[cToken].block == 0) { + compBorrowState[cToken] = CompMarketState({ + index: compInitialIndex, + block: safe32(getBlockNumber(), "block number exceeds 32 bits") + }); + } + } + + /** + * @notice Remove a market from compMarkets, preventing it from earning COMP in the flywheel + * @param cToken The address of the market to drop + */ + function _dropCompMarket(address cToken) public { + require(msg.sender == admin, "only admin can drop comp market"); + + Market storage market = markets[cToken]; + require(market.isComped == true, "market is not a comp market"); + + market.isComped = false; + emit MarketComped(CToken(cToken), false); + + refreshCompSpeedsInternal(); + } + + /** + * @notice Return all of the markets + * @dev The automatic getter may be used to access an individual market. + * @return The list of market addresses + */ + function getAllMarkets() public view returns (CToken[] memory) { + return allMarkets; + } + + function getBlockNumber() public view returns (uint) { + return block.number; + } + + /** + * @notice Return the address of the COMP token + * @return The address of COMP + */ + function getCompAddress() public view returns (address) { + return 0xc00e94Cb662C3520282E6f5717214004A7f26888; + } +} diff --git a/gasCosts.json b/gasCosts.json index b38bf66e8..7afbee4aa 100644 --- a/gasCosts.json +++ b/gasCosts.json @@ -1,89 +1,222 @@ { + "first mint": { + "fee": 129978, + "opcodes": {} + }, "second mint": { - "fee": 86450, + "fee": 90506, "opcodes": { - "PUSH1 @ 3": 589, - "MSTORE @ 12": 9, - "CALLDATASIZE @ 2": 19, - "LT @ 3": 34, - "PUSH2 @ 3": 322, - "JUMPI @ 10": 182, - "CALLDATALOAD @ 3": 24, - "SHR @ 3": 9, - "DUP1 @ 3": 196, - "PUSH4 @ 3": 73, - "GT @ 3": 46, - "JUMPDEST @ 1": 273, - "EQ @ 3": 48, - "CALLVALUE @ 2": 9, + "PUSH1 @ 3": 371, + "MSTORE @ 3": 165, + "PUSH1 @ 12": 1, + "CALLDATASIZE @ 3": 20, + "LT @ 2": 10, + "PUSH2 @ 3": 338, + "JUMPI @ 3": 212, + "PUSH1 @ 10": 18, + "CALLDATALOAD @ 3": 23, + "SHR @ 3": 10, + "DUP1 @ 3": 179, + "PUSH4 @ 3": 70, + "GT @ 3": 63, + "DUP1 @ 10": 24, + "JUMPDEST @ 10": 162, + "DUP1 @ 1": 14, + "EQ @ 3": 28, + "CALLVALUE @ 1": 1, + "DUP1 @ 2": 21, "ISZERO @ 3": 91, - "POP @ 2": 308, - "SUB @ 3": 62, - "DUP2 @ 3": 183, - "JUMP @ 8": 128, - "SLOAD @ 800": 38, - "MLOAD @ 3": 93, - "SWAP2 @ 3": 108, - "SHL @ 3": 35, - "SWAP1 @ 3": 231, - "AND @ 3": 51, - "DUP3 @ 3": 77, - "DUP4 @ 3": 75, - "DUP5 @ 3": 22, - "CALLDATACOPY @ 18": 1, - "SWAP3 @ 3": 77, - "ADD @ 3": 130, - "SWAP5 @ 3": 10, - "SWAP4 @ 3": 35, - "DUP6 @ 3": 24, + "POP @ 1": 52, + "PUSH2 @ 2": 14, + "SUB @ 2": 10, + "DUP2 @ 3": 206, + "LT @ 3": 28, + "CALLDATALOAD @ 2": 6, + "JUMP @ 3": 127, + "JUMPDEST @ 8": 175, + "PUSH1 @ 1": 136, + "MLOAD @ 3": 100, + "DUP3 @ 3": 91, + "ADD @ 3": 145, + "DUP5 @ 3": 26, + "SWAP1 @ 3": 208, + "DUP3 @ 15": 1, + "DUP4 @ 3": 83, + "SUB @ 3": 55, + "SWAP2 @ 3": 106, + "SHL @ 3": 39, + "AND @ 3": 49, + "OR @ 3": 3, + "SLOAD @ 3": 29, + "PUSH1 @ 800": 23, + "JUMPDEST @ 3": 2, + "PUSH1 @ 6": 14, + "NOT @ 3": 5, + "SWAP3 @ 3": 64, + "EXP @ 3": 1, + "SUB @ 60": 1, + "AND @ 6": 1, + "DUP6 @ 3": 23, + "POP @ 3": 211, + "POP @ 2": 125, + "SWAP1 @ 2": 48, + "ADD @ 2": 2, + "PUSH1 @ 2": 75, + "GAS @ 3": 1, + "DELEGATECALL @ 2": 1, + "PUSH1 @ 312830": 1, + "CALLVALUE @ 12": 9, + "PUSH2 @ 1": 30, + "DUP2 @ 800": 6, + "SSTORE @ 3": 11, + "PUSH2 @ 5000": 1, + "SWAP1 @ 800": 4, + "ADDRESS @ 9": 1, + "SWAP1 @ 6": 6, + "DUP7 @ 3": 32, + "EXTCODESIZE @ 3": 8, + "ISZERO @ 700": 8, "GAS @ 2": 8, - "DELEGATECALL @ 700": 1, - "NOT @ 3": 4, - "SSTORE @ 5000": 7, - "MSTORE @ 3": 91, - "MSTORE @ 9": 8, - "MSTORE @ 6": 30, - "MSTORE @ 24": 1, - "ADDRESS @ 2": 7, - "DUP7 @ 3": 19, - "EXTCODESIZE @ 700": 7, - "STATICCALL @ 700": 5, - "SHA3 @ 42": 14, - "RETURN @ 0": 9, - "RETURNDATASIZE @ 2": 13, - "DUP8 @ 3": 12, - "SWAP6 @ 3": 7, - "SWAP7 @ 3": 2, + "STATICCALL @ 2": 5, + "PUSH1 @ 307780": 1, + "SHA3 @ 3": 15, + "SLOAD @ 42": 9, + "MLOAD @ 9": 5, + "RETURN @ 3": 9, + "ISZERO @ -307080": 1, + "RETURNDATASIZE @ 3": 10, + "MLOAD @ 2": 8, + "DUP8 @ 3": 19, + "SWAP6 @ 3": 8, + "SWAP7 @ 3": 5, + "SWAP4 @ 2": 17, + "SWAP5 @ 3": 8, + "SWAP4 @ 3": 14, + "PUSH1 @ 307685": 1, + "POP @ 10": 8, + "SWAP4 @ 1": 13, + "JUMP @ 2": 48, + "SWAP1 @ 1": 34, + "PUSH2 @ 800": 5, "PUSH8 @ 3": 8, - "PUSH32 @ 3": 5, - "DIV @ 5": 11, - "PUSH6 @ 3": 1, - "DUP9 @ 3": 11, - "CODECOPY @ 12": 1, - "CODECOPY @ 16": 2, - "CODECOPY @ 15": 4, - "DUP13 @ 3": 1, - "DUP12 @ 3": 1, + "DUP7 @ 800": 1, + "SWAP3 @ 1": 24, + "PUSH1 @ 9": 1, + "PUSH32 @ 3": 4, + "POP @ 6": 9, + "DIV @ 1": 6, + "SWAP6 @ 5": 1, + "JUMPDEST @ 2": 13, + "SWAP2 @ 1": 4, + "MLOAD @ 6": 4, + "ISZERO @ -306985": 1, + "PUSH6 @ 2": 1, + "DUP10 @ 3": 2, + "DUP2 @ 2": 6, + "SWAP3 @ 2": 26, + "EQ @ 1": 26, + "DUP11 @ 3": 2, + "DUP8 @ 2": 1, + "SWAP8 @ 3": 7, + "SWAP5 @ 2": 2, + "DUP13 @ 3": 3, + "MLOAD @ 1": 4, + "DIV @ 3": 5, + "SWAP1 @ 5": 4, + "DUP6 @ 2": 2, + "DUP7 @ 1": 2, + "SWAP2 @ 2": 8, + "DUP12 @ 3": 2, "DUP15 @ 3": 1, - "SSTORE @ 800": 4, + "PUSH1 @ 5000": 3, "DUP14 @ 3": 1, - "MSTORE @ 7": 4, - "LOG1 @ 1774": 1, + "DUP1 @ 6": 1, + "LOG1 @ 3": 2, + "PUSH1 @ 1774": 1, "SWAP15 @ 3": 1, - "CALLER @ 2": 3, - "CALL @ 700": 2, - "MUL @ 5": 3, + "CALLER @ 3": 1, + "ADDRESS @ 3": 5, + "CALL @ 2": 3, + "PUSH1 @ 307403": 1, + "JUMPDEST @ 800": 1, + "SWAP5 @ 1": 2, + "ISZERO @ -306703": 1, + "EQ @ 800": 1, + "PUSH1 @ 7": 1, + "ADDRESS @ 6": 2, + "PUSH1 @ 307277": 1, + "ISZERO @ -306577": 1, + "DUP4 @ 1": 3, + "MUL @ 3": 3, + "DUP4 @ 5": 3, + "EQ @ 5": 3, + "DUP9 @ 3": 7, + "SWAP2 @ 5": 2, "SWAP9 @ 3": 2, - "SWAP8 @ 3": 2, - "LOG3 @ 1756": 2, - "RETURNDATACOPY @ 6": 2, - "LOG1 @ 1518": 1, - "CODECOPY @ 6": 1, - "OR @ 3": 1, - "RETURNDATACOPY @ 9": 1 + "SWAP6 @ 2": 2, + "PUSH1 @ 307175": 1, + "ISZERO @ -306475": 1, + "SWAP2 @ 7": 1, + "PUSH1 @ 307130": 1, + "PUSH22 @ 9": 1, + "CALLER @ 42": 2, + "DUP3 @ 2": 3, + "DUP5 @ 2": 1, + "SWAP5 @ 42": 2, + "DUP4 @ 5000": 1, + "PUSH20 @ 6": 1, + "SWAP3 @ 6": 1, + "SWAP6 @ 42": 1, + "DUP5 @ 5000": 1, + "PUSH16 @ 6": 1, + "SWAP4 @ 6": 1, + "DUP1 @ 5000": 1, + "LOG3 @ 3": 2, + "POP @ 1756": 1, + "ISZERO @ -306430": 1, + "RETURNDATACOPY @ 3": 2, + "PUSH1 @ 306754": 1, + "ISZERO @ -306054": 1, + "DUP3 @ 800": 1, + "SWAP4 @ 42": 1, + "SWAP5 @ 6": 1, + "DUP3 @ 6": 1, + "PUSH1 @ 1518": 1, + "CODECOPY @ 3": 1, + "DUP2 @ 6": 1, + "PUSH1 @ 1756": 1, + "PUSH1 @ 306426": 1, + "PUSH1 @ 5": 1, + "STOP @ 1": 1, + "ISZERO @ -305726": 1, + "DUP2 @ 1": 1, + "SWAP2 @ -312130": 1, + "RETURNDATASIZE @ 2": 1, + "PUSH2 @ 6": 1 } }, - "redeem": 94077, - "first mint": 134954, - "second mint, no interest accrued": 70851 + "second mint, no interest accrued": { + "fee": 66475, + "opcodes": {} + }, + "redeem": { + "fee": 96782, + "opcodes": {} + }, + "unitroller-g6 second mint with comp accrued": { + "fee": 145034, + "opcodes": {} + }, + "unitroller-g6 claim comp": { + "fee": 142390, + "opcodes": {} + }, + "unitroller second mint with comp accrued": { + "fee": 124317, + "opcodes": {} + }, + "unitroller claim comp": { + "fee": 150385, + "opcodes": {} + } } \ No newline at end of file diff --git a/networks/kovan-abi.json b/networks/kovan-abi.json index c1fcd58bb..4acec4e57 100644 --- a/networks/kovan-abi.json +++ b/networks/kovan-abi.json @@ -35219,6 +35219,2204 @@ "type": "function" } ], + "StdComptrollerG7": [ + { + "inputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor", + "signature": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "action", + "type": "string" + }, + { + "indexed": false, + "internalType": "bool", + "name": "pauseState", + "type": "bool" + } + ], + "name": "ActionPaused", + "type": "event", + "signature": "0xef159d9a32b2472e32b098f954f3ce62d232939f1c207070b584df1814de2de0" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "action", + "type": "string" + }, + { + "indexed": false, + "internalType": "bool", + "name": "pauseState", + "type": "bool" + } + ], + "name": "ActionPaused", + "type": "event", + "signature": "0x71aec636243f9709bb0007ae15e9afb8150ab01716d75fd7573be5cc096e03b0" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "CompGranted", + "type": "event", + "signature": "0x98b2f82a3a07f223a0be64b3d0f47711c64dccd1feafb94aa28156b38cd9695c" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "CompSpeedUpdated", + "type": "event", + "signature": "0x2ab93f65628379309f36cb125e90d7c902454a545c4f8b8cb0794af75c24b807" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "ContributorCompSpeedUpdated", + "type": "event", + "signature": "0x386537fa92edc3319af95f1f904dcf1900021e4f3f4e08169a577a09076e66b3" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "compDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "compBorrowIndex", + "type": "uint256" + } + ], + "name": "DistributedBorrowerComp", + "type": "event", + "signature": "0x1fc3ecc087d8d2d15e23d0032af5a47059c3892d003d8e139fdcb6bb327c99a6" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "supplier", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "compDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "compSupplyIndex", + "type": "uint256" + } + ], + "name": "DistributedSupplierComp", + "type": "event", + "signature": "0x2caecd17d02f56fa897705dcc740da2d237c373f70686f4e0d9bd3bf0400ea7a" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "error", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "info", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "detail", + "type": "uint256" + } + ], + "name": "Failure", + "type": "event", + "signature": "0x45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "MarketEntered", + "type": "event", + "signature": "0x3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a5" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "MarketExited", + "type": "event", + "signature": "0xe699a64c18b07ac5b7301aa273f36a2287239eb9501d81950672794afba29a0d" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + } + ], + "name": "MarketListed", + "type": "event", + "signature": "0xcf583bb0c569eb967f806b11601c4cb93c10310485c67add5f8362c2f212321f" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newBorrowCap", + "type": "uint256" + } + ], + "name": "NewBorrowCap", + "type": "event", + "signature": "0x6f1951b2aad10f3fc81b86d91105b413a5b3f847a34bbc5ce1904201b14438f6" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldBorrowCapGuardian", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newBorrowCapGuardian", + "type": "address" + } + ], + "name": "NewBorrowCapGuardian", + "type": "event", + "signature": "0xeda98690e518e9a05f8ec6837663e188211b2da8f4906648b323f2c1d4434e29" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldCloseFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newCloseFactorMantissa", + "type": "uint256" + } + ], + "name": "NewCloseFactor", + "type": "event", + "signature": "0x3b9670cf975d26958e754b57098eaa2ac914d8d2a31b83257997b9f346110fd9" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldCollateralFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newCollateralFactorMantissa", + "type": "uint256" + } + ], + "name": "NewCollateralFactor", + "type": "event", + "signature": "0x70483e6592cd5182d45ac970e05bc62cdcc90e9d8ef2c2dbe686cf383bcd7fc5" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldLiquidationIncentiveMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newLiquidationIncentiveMantissa", + "type": "uint256" + } + ], + "name": "NewLiquidationIncentive", + "type": "event", + "signature": "0xaeba5a6c40a8ac138134bff1aaa65debf25971188a58804bad717f82f0ec1316" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldPauseGuardian", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newPauseGuardian", + "type": "address" + } + ], + "name": "NewPauseGuardian", + "type": "event", + "signature": "0x0613b6ee6a04f0d09f390e4d9318894b9f6ac7fd83897cd8d18896ba579c401e" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract PriceOracle", + "name": "oldPriceOracle", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract PriceOracle", + "name": "newPriceOracle", + "type": "address" + } + ], + "name": "NewPriceOracle", + "type": "event", + "signature": "0xd52b2b9b7e9ee655fcb95d2e5b9e0c9f69e7ef2b8e9d2d0ea78402d576d22e22" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract Unitroller", + "name": "unitroller", + "type": "address" + } + ], + "name": "_become", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x1d504dc6" + }, + { + "constant": true, + "inputs": [], + "name": "_borrowGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xe6653f3d" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "_grantComp", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x27efe3cb" + }, + { + "constant": true, + "inputs": [], + "name": "_mintGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x3c94786f" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "newBorrowCapGuardian", + "type": "address" + } + ], + "name": "_setBorrowCapGuardian", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x391957d7" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "state", + "type": "bool" + } + ], + "name": "_setBorrowPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x18c882a5" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "newCloseFactorMantissa", + "type": "uint256" + } + ], + "name": "_setCloseFactor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x317b0b77" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "newCollateralFactorMantissa", + "type": "uint256" + } + ], + "name": "_setCollateralFactor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xe4028eee" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "compSpeed", + "type": "uint256" + } + ], + "name": "_setCompSpeed", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x434caf25" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "internalType": "uint256", + "name": "compSpeed", + "type": "uint256" + } + ], + "name": "_setContributorCompSpeed", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x598ee1cb" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "newLiquidationIncentiveMantissa", + "type": "uint256" + } + ], + "name": "_setLiquidationIncentive", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x4fd42e17" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract CToken[]", + "name": "cTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "newBorrowCaps", + "type": "uint256[]" + } + ], + "name": "_setMarketBorrowCaps", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x607ef6c1" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "state", + "type": "bool" + } + ], + "name": "_setMintPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x3bcf7ec1" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "newPauseGuardian", + "type": "address" + } + ], + "name": "_setPauseGuardian", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x5f5af1aa" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract PriceOracle", + "name": "newOracle", + "type": "address" + } + ], + "name": "_setPriceOracle", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x55ee1fe1" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "bool", + "name": "state", + "type": "bool" + } + ], + "name": "_setSeizePaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x2d70db78" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "bool", + "name": "state", + "type": "bool" + } + ], + "name": "_setTransferPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x8ebf6364" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + } + ], + "name": "_supportMarket", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xa76b3fda" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "accountAssets", + "outputs": [ + { + "internalType": "contract CToken", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xdce15449" + }, + { + "constant": true, + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xf851a440" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "allMarkets", + "outputs": [ + { + "internalType": "contract CToken", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x52d84d1e" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + } + ], + "name": "borrowAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xda3d454c" + }, + { + "constant": true, + "inputs": [], + "name": "borrowCapGuardian", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x21af4569" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "borrowCaps", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x4a584432" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "borrowGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x6d154ea5" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + } + ], + "name": "borrowVerify", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x5c778605" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + } + ], + "name": "checkMembership", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x929fe9a1" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + }, + { + "internalType": "contract CToken[]", + "name": "cTokens", + "type": "address[]" + } + ], + "name": "claimComp", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x1c3db2e0" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address[]", + "name": "holders", + "type": "address[]" + }, + { + "internalType": "contract CToken[]", + "name": "cTokens", + "type": "address[]" + }, + { + "internalType": "bool", + "name": "borrowers", + "type": "bool" + }, + { + "internalType": "bool", + "name": "suppliers", + "type": "bool" + } + ], + "name": "claimComp", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x6810dfa6" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + } + ], + "name": "claimComp", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xe9af0292" + }, + { + "constant": true, + "inputs": [], + "name": "closeFactorMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xe8755446" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compAccrued", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xcc7ebdc4" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compBorrowState", + "outputs": [ + { + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x8c57804e" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compBorrowerIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xca0af043" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compContributorSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x986ab838" + }, + { + "constant": true, + "inputs": [], + "name": "compInitialIndex", + "outputs": [ + { + "internalType": "uint224", + "name": "", + "type": "uint224" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xa7f0e231" + }, + { + "constant": true, + "inputs": [], + "name": "compRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xaa900754" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x1d7b33d7" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compSupplierIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xb21be7fd" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compSupplyState", + "outputs": [ + { + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x6b79c38d" + }, + { + "constant": true, + "inputs": [], + "name": "comptrollerImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xbb82aa5e" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address[]", + "name": "cTokens", + "type": "address[]" + } + ], + "name": "enterMarkets", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xc2998238" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cTokenAddress", + "type": "address" + } + ], + "name": "exitMarket", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xede4edd0" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getAccountLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x5ec88c79" + }, + { + "constant": true, + "inputs": [], + "name": "getAllMarkets", + "outputs": [ + { + "internalType": "contract CToken[]", + "name": "", + "type": "address[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xb0772d0b" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getAssetsIn", + "outputs": [ + { + "internalType": "contract CToken[]", + "name": "", + "type": "address[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xabfceffc" + }, + { + "constant": true, + "inputs": [], + "name": "getBlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x42cbb15c" + }, + { + "constant": true, + "inputs": [], + "name": "getCompAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x9d1b5a0a" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenModify", + "type": "address" + }, + { + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + } + ], + "name": "getHypotheticalAccountLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x4e79238f" + }, + { + "constant": true, + "inputs": [], + "name": "isComptroller", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x007e3dd2" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "lastContributorBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xbea6b8b8" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "liquidateBorrowAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x5fc7e71e" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "actualRepayAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "liquidateBorrowVerify", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x47ef3b3b" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "internalType": "uint256", + "name": "actualRepayAmount", + "type": "uint256" + } + ], + "name": "liquidateCalculateSeizeTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xc488847b" + }, + { + "constant": true, + "inputs": [], + "name": "liquidationIncentiveMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x4ada90af" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "markets", + "outputs": [ + { + "internalType": "bool", + "name": "isListed", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "collateralFactorMantissa", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isComped", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x8e8f294b" + }, + { + "constant": true, + "inputs": [], + "name": "maxAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x94b2294b" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "internalType": "uint256", + "name": "mintAmount", + "type": "uint256" + } + ], + "name": "mintAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x4ef4c3e1" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "mintGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x731f0c2b" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "internalType": "uint256", + "name": "actualMintAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "mintTokens", + "type": "uint256" + } + ], + "name": "mintVerify", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x41c728b9" + }, + { + "constant": true, + "inputs": [], + "name": "oracle", + "outputs": [ + { + "internalType": "contract PriceOracle", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x7dc0d1d0" + }, + { + "constant": true, + "inputs": [], + "name": "pauseGuardian", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x24a3d622" + }, + { + "constant": true, + "inputs": [], + "name": "pendingAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x26782247" + }, + { + "constant": true, + "inputs": [], + "name": "pendingComptrollerImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xdcfbc0c7" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "redeemer", + "type": "address" + }, + { + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + } + ], + "name": "redeemAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xeabe7d91" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "redeemer", + "type": "address" + }, + { + "internalType": "uint256", + "name": "redeemAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + } + ], + "name": "redeemVerify", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x51dff989" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "payer", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "repayBorrowAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x24008a62" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "payer", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "actualRepayAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowerIndex", + "type": "uint256" + } + ], + "name": "repayBorrowVerify", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x1ededc91" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "seizeAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xd02f7351" + }, + { + "constant": true, + "inputs": [], + "name": "seizeGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xac0b0bb7" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "seizeVerify", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x6d35bf91" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "transferTokens", + "type": "uint256" + } + ], + "name": "transferAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xbdcdc258" + }, + { + "constant": true, + "inputs": [], + "name": "transferGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x87f76303" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "transferTokens", + "type": "uint256" + } + ], + "name": "transferVerify", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x6a56947e" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "contributor", + "type": "address" + } + ], + "name": "updateContributorRewards", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x741b2525" + } + ], "REP": [ { "inputs": [ diff --git a/networks/kovan.json b/networks/kovan.json index a0b1cc3c3..12a69723b 100644 --- a/networks/kovan.json +++ b/networks/kovan.json @@ -54,10 +54,12 @@ "StdComptrollerG6": "0x758C37bF284F769e2F4c75ac5932F4365C25e783", "SAI": "0xD1308F63823221518Ec88EB209CBaa1ac182105f", "Jug": "0xcbB7718c9F39d05aEEDE1c472ca8Bf804b2f1EaD", + "StdComptrollerG7": "0x8ABad9bA5bD99d353E1b13467BaBebd908a917Af", "REP": "0x50DD65531676F718B018De3dc48F92B53D756996", "cZRX": "0xAf45ae737514C8427D373D50Cd979a242eC59e5a", "cWBTC": "0xa1fAA15655B0e7b6B6470ED3d096390e6aD93Abb", - "USDC": "0xb7a4F3E9097C08dA09517b5aB877F7a917224ede" + "USDC": "0xb7a4F3E9097C08dA09517b5aB877F7a917224ede", + "ComptrollerKovan": "0x9211aaf5b7a68ECD30D905dd24071e5139B3A172" }, "Blocks": { "ZRX": 18751052, @@ -107,6 +109,7 @@ "LINK": 19400422, "StdComptrollerG6": 22428388, "SAI": 18751064, + "StdComptrollerG7": 22618153, "REP": 18751069, "cZRX": 18751114, "cWBTC": 18751119, @@ -151,6 +154,11 @@ "address": "0x758C37bF284F769e2F4c75ac5932F4365C25e783", "contract": "Comptroller", "description": "Standard Comptroller Impl" + }, + "StdComptrollerG7": { + "address": "0x8ABad9bA5bD99d353E1b13467BaBebd908a917Af", + "contract": "Comptroller", + "description": "Standard Comptroller Impl" } }, "Timelock": { @@ -208,6 +216,7 @@ "LINK": "0x", "StdComptrollerG6": "0x", "SAI": "0x00000000000000000000000000000000000000000006dd649e6ae76d5bf800000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000003536169000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035341490000000000000000000000000000000000000000000000000000000000", + "StdComptrollerG7": "0x", "REP": "0x00000000000000000000000000000000000000000009195731e2ce35eb0000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000005417567757200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035245500000000000000000000000000000000000000000000000000000000000", "cZRX": "0x000000000000000000000000162c44e53097e7b5aae939b297fffd6bf90d1ee30000000000000000000000005eae89dc1c671724a672ff0630122ee8340986570000000000000000000000007bdf14574c844cd9b75073f91bb1aeab44ab0529000000000000000000000000000000000000000000a56fa5b99019a5c8000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000008000000000000000000000000a776184fd6f545dae5f51361dbcc9018549a9749000000000000000000000000000000000000000000000000000000000000000c436f6d706f756e64205a525800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004635a525800000000000000000000000000000000000000000000000000000000", "cWBTC": "0x000000000000000000000000d3a691c852cdb01e281545a27064741f0b7f68250000000000000000000000005eae89dc1c671724a672ff0630122ee8340986570000000000000000000000007bdf14574c844cd9b75073f91bb1aeab44ab052900000000000000000000000000000000000000000000000000470de4df820000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000008000000000000000000000000a776184fd6f545dae5f51361dbcc9018549a9749000000000000000000000000000000000000000000000000000000000000000d436f6d706f756e6420574254430000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000056357425443000000000000000000000000000000000000000000000000000000", diff --git a/networks/mainnet-abi.json b/networks/mainnet-abi.json index 0909327d7..5025fd614 100644 --- a/networks/mainnet-abi.json +++ b/networks/mainnet-abi.json @@ -11823,6 +11823,7 @@ "name": "pendingAdmin", "outputs": [ { + "internalType": "address", "name": "", "type": "address" } @@ -11858,6 +11859,7 @@ "name": "comptrollerImplementation", "outputs": [ { + "internalType": "address", "name": "", "type": "address" } @@ -11888,6 +11890,7 @@ "name": "pendingComptrollerImplementation", "outputs": [ { + "internalType": "address", "name": "", "type": "address" } @@ -11938,6 +11941,7 @@ "name": "admin", "outputs": [ { + "internalType": "address", "name": "", "type": "address" } @@ -12036,16 +12040,19 @@ "inputs": [ { "indexed": false, + "internalType": "uint256", "name": "error", "type": "uint256" }, { "indexed": false, + "internalType": "uint256", "name": "info", "type": "uint256" }, { "indexed": false, + "internalType": "uint256", "name": "detail", "type": "uint256" } @@ -12054,13 +12061,6 @@ "type": "event", "signature": "0x45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0" }, - { - "inputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "constructor", - "signature": "constructor" - }, { "anonymous": false, "inputs": [ @@ -12191,32 +12191,6 @@ "type": "event", "signature": "0x2caecd17d02f56fa897705dcc740da2d237c373f70686f4e0d9bd3bf0400ea7a" }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "error", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "info", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "detail", - "type": "uint256" - } - ], - "name": "Failure", - "type": "event", - "signature": "0x45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0" - }, { "anonymous": false, "inputs": [ @@ -12894,22 +12868,6 @@ "type": "function", "signature": "0xdce15449" }, - { - "constant": true, - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function", - "signature": "0xf851a440" - }, { "constant": true, "inputs": [ @@ -13361,22 +13319,6 @@ "type": "function", "signature": "0x6b79c38d" }, - { - "constant": true, - "inputs": [], - "name": "comptrollerImplementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function", - "signature": "0xbb82aa5e" - }, { "constant": false, "inputs": [ @@ -13887,38 +13829,6 @@ "type": "function", "signature": "0x24a3d622" }, - { - "constant": true, - "inputs": [], - "name": "pendingAdmin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function", - "signature": "0x26782247" - }, - { - "constant": true, - "inputs": [], - "name": "pendingComptrollerImplementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function", - "signature": "0xdcfbc0c7" - }, { "constant": false, "inputs": [ @@ -14242,35 +14152,14 @@ "stateMutability": "nonpayable", "type": "function", "signature": "0x6a56947e" - } - ], - "Comp": [ - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "constructor", - "signature": "constructor" }, { "anonymous": false, "inputs": [ { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, + "indexed": false, "internalType": "address", - "name": "spender", + "name": "recipient", "type": "address" }, { @@ -14280,9 +14169,9 @@ "type": "uint256" } ], - "name": "Approval", + "name": "CompGranted", "type": "event", - "signature": "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925" + "signature": "0x98b2f82a3a07f223a0be64b3d0f47711c64dccd1feafb94aa28156b38cd9695c" }, { "anonymous": false, @@ -14290,125 +14179,115 @@ { "indexed": true, "internalType": "address", - "name": "delegator", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "fromDelegate", + "name": "contributor", "type": "address" }, { - "indexed": true, - "internalType": "address", - "name": "toDelegate", - "type": "address" + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" } ], - "name": "DelegateChanged", + "name": "ContributorCompSpeedUpdated", "type": "event", - "signature": "0x3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f" + "signature": "0x386537fa92edc3319af95f1f904dcf1900021e4f3f4e08169a577a09076e66b3" }, { - "anonymous": false, + "constant": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "delegate", + "name": "recipient", "type": "address" }, { - "indexed": false, "internalType": "uint256", - "name": "previousBalance", + "name": "amount", "type": "uint256" + } + ], + "name": "_grantComp", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x27efe3cb" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" }, { - "indexed": false, "internalType": "uint256", - "name": "newBalance", + "name": "compSpeed", "type": "uint256" } ], - "name": "DelegateVotesChanged", - "type": "event", - "signature": "0xdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724" + "name": "_setCompSpeed", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x434caf25" }, { - "anonymous": false, + "constant": false, "inputs": [ { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, "internalType": "address", - "name": "to", + "name": "contributor", "type": "address" }, { - "indexed": false, "internalType": "uint256", - "name": "amount", + "name": "compSpeed", "type": "uint256" } ], - "name": "Transfer", - "type": "event", - "signature": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" + "name": "_setContributorCompSpeed", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x598ee1cb" }, { "constant": true, - "inputs": [], - "name": "DELEGATION_TYPEHASH", - "outputs": [ + "inputs": [ { - "internalType": "bytes32", + "internalType": "address", "name": "", - "type": "bytes32" + "type": "address" } ], - "payable": false, - "stateMutability": "view", - "type": "function", - "signature": "0xe7a324dc" - }, - { - "constant": true, - "inputs": [], - "name": "DOMAIN_TYPEHASH", + "name": "compContributorSpeeds", "outputs": [ { - "internalType": "bytes32", + "internalType": "uint256", "name": "", - "type": "bytes32" + "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function", - "signature": "0x20606b70" + "signature": "0x986ab838" }, { "constant": true, "inputs": [ { "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "address", - "name": "spender", + "name": "", "type": "address" } ], - "name": "allowance", + "name": "lastContributorBlock", "outputs": [ { "internalType": "uint256", @@ -14419,26 +14298,220 @@ "payable": false, "stateMutability": "view", "type": "function", - "signature": "0xdd62ed3e" + "signature": "0xbea6b8b8" }, { "constant": false, "inputs": [ { "internalType": "address", - "name": "spender", + "name": "contributor", "type": "address" - }, - { - "internalType": "uint256", - "name": "rawAmount", - "type": "uint256" } ], - "name": "approve", - "outputs": [ - { - "internalType": "bool", + "name": "updateContributorRewards", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x741b2525" + } + ], + "Comp": [ + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor", + "signature": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event", + "signature": "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "delegator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "fromDelegate", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "toDelegate", + "type": "address" + } + ], + "name": "DelegateChanged", + "type": "event", + "signature": "0x3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "delegate", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "previousBalance", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newBalance", + "type": "uint256" + } + ], + "name": "DelegateVotesChanged", + "type": "event", + "signature": "0xdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event", + "signature": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" + }, + { + "constant": true, + "inputs": [], + "name": "DELEGATION_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xe7a324dc" + }, + { + "constant": true, + "inputs": [], + "name": "DOMAIN_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x20606b70" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xdd62ed3e" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "rawAmount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", "name": "", "type": "bool" } @@ -38399,259 +38472,535 @@ "type": "function" } ], - "cZRX": [ + "StdComptrollerG7": [ { - "constant": true, "inputs": [], - "name": "name", - "outputs": [ + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor", + "signature": "constructor" + }, + { + "anonymous": false, + "inputs": [ { - "name": "", + "indexed": false, + "internalType": "string", + "name": "action", "type": "string" + }, + { + "indexed": false, + "internalType": "bool", + "name": "pauseState", + "type": "bool" } ], - "payable": false, - "stateMutability": "view", - "type": "function", - "signature": "0x06fdde03" + "name": "ActionPaused", + "type": "event", + "signature": "0xef159d9a32b2472e32b098f954f3ce62d232939f1c207070b584df1814de2de0" }, { - "constant": false, + "anonymous": false, "inputs": [ { - "name": "spender", + "indexed": false, + "internalType": "contract CToken", + "name": "cToken", "type": "address" }, { - "name": "amount", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [ + "indexed": false, + "internalType": "string", + "name": "action", + "type": "string" + }, { - "name": "", + "indexed": false, + "internalType": "bool", + "name": "pauseState", "type": "bool" } ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function", - "signature": "0x095ea7b3" + "name": "ActionPaused", + "type": "event", + "signature": "0x71aec636243f9709bb0007ae15e9afb8150ab01716d75fd7573be5cc096e03b0" }, { - "constant": false, + "anonymous": false, "inputs": [ { - "name": "repayAmount", - "type": "uint256" - } - ], - "name": "repayBorrow", - "outputs": [ + "indexed": false, + "internalType": "address", + "name": "recipient", + "type": "address" + }, { - "name": "", + "indexed": false, + "internalType": "uint256", + "name": "amount", "type": "uint256" } ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function", - "signature": "0x0e752702" + "name": "CompGranted", + "type": "event", + "signature": "0x98b2f82a3a07f223a0be64b3d0f47711c64dccd1feafb94aa28156b38cd9695c" }, { - "constant": true, - "inputs": [], - "name": "reserveFactorMantissa", - "outputs": [ + "anonymous": false, + "inputs": [ { - "name": "", + "indexed": true, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", "type": "uint256" } ], - "payable": false, - "stateMutability": "view", - "type": "function", - "signature": "0x173b9904" + "name": "CompSpeedUpdated", + "type": "event", + "signature": "0x2ab93f65628379309f36cb125e90d7c902454a545c4f8b8cb0794af75c24b807" }, { - "constant": false, + "anonymous": false, "inputs": [ { - "name": "account", + "indexed": true, + "internalType": "address", + "name": "contributor", "type": "address" - } - ], - "name": "borrowBalanceCurrent", - "outputs": [ + }, { - "name": "", + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", "type": "uint256" } ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function", - "signature": "0x17bfdfbc" + "name": "ContributorCompSpeedUpdated", + "type": "event", + "signature": "0x386537fa92edc3319af95f1f904dcf1900021e4f3f4e08169a577a09076e66b3" }, { - "constant": true, - "inputs": [], - "name": "totalSupply", - "outputs": [ + "anonymous": false, + "inputs": [ { - "name": "", + "indexed": true, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "compDelta", "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function", - "signature": "0x18160ddd" - }, - { - "constant": true, - "inputs": [], - "name": "exchangeRateStored", - "outputs": [ + }, { - "name": "", + "indexed": false, + "internalType": "uint256", + "name": "compBorrowIndex", "type": "uint256" } ], - "payable": false, - "stateMutability": "view", - "type": "function", - "signature": "0x182df0f5" + "name": "DistributedBorrowerComp", + "type": "event", + "signature": "0x1fc3ecc087d8d2d15e23d0032af5a47059c3892d003d8e139fdcb6bb327c99a6" }, { - "constant": false, + "anonymous": false, "inputs": [ { - "name": "src", + "indexed": true, + "internalType": "contract CToken", + "name": "cToken", "type": "address" }, { - "name": "dst", + "indexed": true, + "internalType": "address", + "name": "supplier", "type": "address" }, { - "name": "amount", + "indexed": false, + "internalType": "uint256", + "name": "compDelta", "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [ + }, { - "name": "", - "type": "bool" + "indexed": false, + "internalType": "uint256", + "name": "compSupplyIndex", + "type": "uint256" } ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function", - "signature": "0x23b872dd" + "name": "DistributedSupplierComp", + "type": "event", + "signature": "0x2caecd17d02f56fa897705dcc740da2d237c373f70686f4e0d9bd3bf0400ea7a" }, { - "constant": false, + "anonymous": false, "inputs": [ { - "name": "borrower", - "type": "address" + "indexed": false, + "internalType": "uint256", + "name": "error", + "type": "uint256" }, { - "name": "repayAmount", + "indexed": false, + "internalType": "uint256", + "name": "info", "type": "uint256" - } - ], - "name": "repayBorrowBehalf", - "outputs": [ + }, { - "name": "", + "indexed": false, + "internalType": "uint256", + "name": "detail", "type": "uint256" } ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function", - "signature": "0x2608f818" + "name": "Failure", + "type": "event", + "signature": "0x45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0" }, { - "constant": true, - "inputs": [], - "name": "pendingAdmin", - "outputs": [ + "anonymous": false, + "inputs": [ { - "name": "", + "indexed": false, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "account", "type": "address" } ], - "payable": false, - "stateMutability": "view", - "type": "function", - "signature": "0x26782247" + "name": "MarketEntered", + "type": "event", + "signature": "0x3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a5" }, { - "constant": true, - "inputs": [], - "name": "decimals", - "outputs": [ + "anonymous": false, + "inputs": [ { - "name": "", - "type": "uint256" + "indexed": false, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" } ], - "payable": false, - "stateMutability": "view", - "type": "function", - "signature": "0x313ce567" + "name": "MarketExited", + "type": "event", + "signature": "0xe699a64c18b07ac5b7301aa273f36a2287239eb9501d81950672794afba29a0d" }, { - "constant": false, + "anonymous": false, "inputs": [ { - "name": "owner", + "indexed": false, + "internalType": "contract CToken", + "name": "cToken", "type": "address" } ], - "name": "balanceOfUnderlying", - "outputs": [ + "name": "MarketListed", + "type": "event", + "signature": "0xcf583bb0c569eb967f806b11601c4cb93c10310485c67add5f8362c2f212321f" + }, + { + "anonymous": false, + "inputs": [ { - "name": "", + "indexed": true, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newBorrowCap", "type": "uint256" } ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function", - "signature": "0x3af9e669" + "name": "NewBorrowCap", + "type": "event", + "signature": "0x6f1951b2aad10f3fc81b86d91105b413a5b3f847a34bbc5ce1904201b14438f6" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldBorrowCapGuardian", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newBorrowCapGuardian", + "type": "address" + } + ], + "name": "NewBorrowCapGuardian", + "type": "event", + "signature": "0xeda98690e518e9a05f8ec6837663e188211b2da8f4906648b323f2c1d4434e29" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldCloseFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newCloseFactorMantissa", + "type": "uint256" + } + ], + "name": "NewCloseFactor", + "type": "event", + "signature": "0x3b9670cf975d26958e754b57098eaa2ac914d8d2a31b83257997b9f346110fd9" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldCollateralFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newCollateralFactorMantissa", + "type": "uint256" + } + ], + "name": "NewCollateralFactor", + "type": "event", + "signature": "0x70483e6592cd5182d45ac970e05bc62cdcc90e9d8ef2c2dbe686cf383bcd7fc5" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldLiquidationIncentiveMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newLiquidationIncentiveMantissa", + "type": "uint256" + } + ], + "name": "NewLiquidationIncentive", + "type": "event", + "signature": "0xaeba5a6c40a8ac138134bff1aaa65debf25971188a58804bad717f82f0ec1316" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldPauseGuardian", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newPauseGuardian", + "type": "address" + } + ], + "name": "NewPauseGuardian", + "type": "event", + "signature": "0x0613b6ee6a04f0d09f390e4d9318894b9f6ac7fd83897cd8d18896ba579c401e" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract PriceOracle", + "name": "oldPriceOracle", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract PriceOracle", + "name": "newPriceOracle", + "type": "address" + } + ], + "name": "NewPriceOracle", + "type": "event", + "signature": "0xd52b2b9b7e9ee655fcb95d2e5b9e0c9f69e7ef2b8e9d2d0ea78402d576d22e22" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract Unitroller", + "name": "unitroller", + "type": "address" + } + ], + "name": "_become", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x1d504dc6" }, { "constant": true, "inputs": [], - "name": "getCash", + "name": "_borrowGuardianPaused", "outputs": [ { + "internalType": "bool", "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xe6653f3d" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", "type": "uint256" } ], + "name": "_grantComp", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x27efe3cb" + }, + { + "constant": true, + "inputs": [], + "name": "_mintGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], "payable": false, "stateMutability": "view", "type": "function", - "signature": "0x3b1d21a2" + "signature": "0x3c94786f" }, { "constant": false, "inputs": [ { - "name": "newComptroller", + "internalType": "address", + "name": "newBorrowCapGuardian", "type": "address" } ], - "name": "_setComptroller", + "name": "_setBorrowCapGuardian", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x391957d7" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "state", + "type": "bool" + } + ], + "name": "_setBorrowPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x18c882a5" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "newCloseFactorMantissa", + "type": "uint256" + } + ], + "name": "_setCloseFactor", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } @@ -38659,107 +39008,4250 @@ "payable": false, "stateMutability": "nonpayable", "type": "function", - "signature": "0x4576b5db" + "signature": "0x317b0b77" }, { - "constant": true, - "inputs": [], - "name": "totalBorrows", + "constant": false, + "inputs": [ + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "newCollateralFactorMantissa", + "type": "uint256" + } + ], + "name": "_setCollateralFactor", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], - "payable": false, - "stateMutability": "view", - "type": "function", - "signature": "0x47bd3718" + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xe4028eee" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "compSpeed", + "type": "uint256" + } + ], + "name": "_setCompSpeed", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x434caf25" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "internalType": "uint256", + "name": "compSpeed", + "type": "uint256" + } + ], + "name": "_setContributorCompSpeed", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x598ee1cb" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "newLiquidationIncentiveMantissa", + "type": "uint256" + } + ], + "name": "_setLiquidationIncentive", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x4fd42e17" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract CToken[]", + "name": "cTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "newBorrowCaps", + "type": "uint256[]" + } + ], + "name": "_setMarketBorrowCaps", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x607ef6c1" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "state", + "type": "bool" + } + ], + "name": "_setMintPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x3bcf7ec1" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "newPauseGuardian", + "type": "address" + } + ], + "name": "_setPauseGuardian", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x5f5af1aa" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract PriceOracle", + "name": "newOracle", + "type": "address" + } + ], + "name": "_setPriceOracle", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x55ee1fe1" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "bool", + "name": "state", + "type": "bool" + } + ], + "name": "_setSeizePaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x2d70db78" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "bool", + "name": "state", + "type": "bool" + } + ], + "name": "_setTransferPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x8ebf6364" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + } + ], + "name": "_supportMarket", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xa76b3fda" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "accountAssets", + "outputs": [ + { + "internalType": "contract CToken", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xdce15449" + }, + { + "constant": true, + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xf851a440" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "allMarkets", + "outputs": [ + { + "internalType": "contract CToken", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x52d84d1e" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + } + ], + "name": "borrowAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xda3d454c" + }, + { + "constant": true, + "inputs": [], + "name": "borrowCapGuardian", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x21af4569" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "borrowCaps", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x4a584432" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "borrowGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x6d154ea5" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + } + ], + "name": "borrowVerify", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x5c778605" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + } + ], + "name": "checkMembership", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x929fe9a1" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + }, + { + "internalType": "contract CToken[]", + "name": "cTokens", + "type": "address[]" + } + ], + "name": "claimComp", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x1c3db2e0" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address[]", + "name": "holders", + "type": "address[]" + }, + { + "internalType": "contract CToken[]", + "name": "cTokens", + "type": "address[]" + }, + { + "internalType": "bool", + "name": "borrowers", + "type": "bool" + }, + { + "internalType": "bool", + "name": "suppliers", + "type": "bool" + } + ], + "name": "claimComp", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x6810dfa6" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + } + ], + "name": "claimComp", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xe9af0292" + }, + { + "constant": true, + "inputs": [], + "name": "closeFactorMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xe8755446" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compAccrued", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xcc7ebdc4" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compBorrowState", + "outputs": [ + { + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x8c57804e" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compBorrowerIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xca0af043" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compContributorSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x986ab838" + }, + { + "constant": true, + "inputs": [], + "name": "compInitialIndex", + "outputs": [ + { + "internalType": "uint224", + "name": "", + "type": "uint224" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xa7f0e231" + }, + { + "constant": true, + "inputs": [], + "name": "compRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xaa900754" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x1d7b33d7" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compSupplierIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xb21be7fd" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compSupplyState", + "outputs": [ + { + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x6b79c38d" + }, + { + "constant": true, + "inputs": [], + "name": "comptrollerImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xbb82aa5e" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address[]", + "name": "cTokens", + "type": "address[]" + } + ], + "name": "enterMarkets", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xc2998238" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cTokenAddress", + "type": "address" + } + ], + "name": "exitMarket", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xede4edd0" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getAccountLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x5ec88c79" + }, + { + "constant": true, + "inputs": [], + "name": "getAllMarkets", + "outputs": [ + { + "internalType": "contract CToken[]", + "name": "", + "type": "address[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xb0772d0b" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getAssetsIn", + "outputs": [ + { + "internalType": "contract CToken[]", + "name": "", + "type": "address[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xabfceffc" + }, + { + "constant": true, + "inputs": [], + "name": "getBlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x42cbb15c" + }, + { + "constant": true, + "inputs": [], + "name": "getCompAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x9d1b5a0a" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenModify", + "type": "address" + }, + { + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + } + ], + "name": "getHypotheticalAccountLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x4e79238f" + }, + { + "constant": true, + "inputs": [], + "name": "isComptroller", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x007e3dd2" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "lastContributorBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xbea6b8b8" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "liquidateBorrowAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x5fc7e71e" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "actualRepayAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "liquidateBorrowVerify", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x47ef3b3b" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "internalType": "uint256", + "name": "actualRepayAmount", + "type": "uint256" + } + ], + "name": "liquidateCalculateSeizeTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xc488847b" + }, + { + "constant": true, + "inputs": [], + "name": "liquidationIncentiveMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x4ada90af" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "markets", + "outputs": [ + { + "internalType": "bool", + "name": "isListed", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "collateralFactorMantissa", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isComped", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x8e8f294b" + }, + { + "constant": true, + "inputs": [], + "name": "maxAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x94b2294b" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "internalType": "uint256", + "name": "mintAmount", + "type": "uint256" + } + ], + "name": "mintAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x4ef4c3e1" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "mintGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x731f0c2b" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "internalType": "uint256", + "name": "actualMintAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "mintTokens", + "type": "uint256" + } + ], + "name": "mintVerify", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x41c728b9" + }, + { + "constant": true, + "inputs": [], + "name": "oracle", + "outputs": [ + { + "internalType": "contract PriceOracle", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x7dc0d1d0" + }, + { + "constant": true, + "inputs": [], + "name": "pauseGuardian", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x24a3d622" + }, + { + "constant": true, + "inputs": [], + "name": "pendingAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x26782247" + }, + { + "constant": true, + "inputs": [], + "name": "pendingComptrollerImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xdcfbc0c7" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "redeemer", + "type": "address" + }, + { + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + } + ], + "name": "redeemAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xeabe7d91" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "redeemer", + "type": "address" + }, + { + "internalType": "uint256", + "name": "redeemAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + } + ], + "name": "redeemVerify", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x51dff989" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "payer", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "repayBorrowAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x24008a62" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "payer", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "actualRepayAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowerIndex", + "type": "uint256" + } + ], + "name": "repayBorrowVerify", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x1ededc91" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "seizeAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xd02f7351" + }, + { + "constant": true, + "inputs": [], + "name": "seizeGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xac0b0bb7" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "seizeVerify", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x6d35bf91" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "transferTokens", + "type": "uint256" + } + ], + "name": "transferAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xbdcdc258" + }, + { + "constant": true, + "inputs": [], + "name": "transferGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x87f76303" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "transferTokens", + "type": "uint256" + } + ], + "name": "transferVerify", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x6a56947e" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "contributor", + "type": "address" + } + ], + "name": "updateContributorRewards", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x741b2525" + } + ], + "cZRX": [ + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x06fdde03" + }, + { + "constant": false, + "inputs": [ + { + "name": "spender", + "type": "address" + }, + { + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x095ea7b3" + }, + { + "constant": false, + "inputs": [ + { + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "repayBorrow", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x0e752702" + }, + { + "constant": true, + "inputs": [], + "name": "reserveFactorMantissa", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x173b9904" + }, + { + "constant": false, + "inputs": [ + { + "name": "account", + "type": "address" + } + ], + "name": "borrowBalanceCurrent", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x17bfdfbc" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x18160ddd" + }, + { + "constant": true, + "inputs": [], + "name": "exchangeRateStored", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x182df0f5" + }, + { + "constant": false, + "inputs": [ + { + "name": "src", + "type": "address" + }, + { + "name": "dst", + "type": "address" + }, + { + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x23b872dd" + }, + { + "constant": false, + "inputs": [ + { + "name": "borrower", + "type": "address" + }, + { + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "repayBorrowBehalf", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x2608f818" + }, + { + "constant": true, + "inputs": [], + "name": "pendingAdmin", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x26782247" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x313ce567" + }, + { + "constant": false, + "inputs": [ + { + "name": "owner", + "type": "address" + } + ], + "name": "balanceOfUnderlying", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x3af9e669" + }, + { + "constant": true, + "inputs": [], + "name": "getCash", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x3b1d21a2" + }, + { + "constant": false, + "inputs": [ + { + "name": "newComptroller", + "type": "address" + } + ], + "name": "_setComptroller", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x4576b5db" + }, + { + "constant": true, + "inputs": [], + "name": "totalBorrows", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x47bd3718" + }, + { + "constant": true, + "inputs": [], + "name": "comptroller", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x5fe3b567" + }, + { + "constant": false, + "inputs": [ + { + "name": "reduceAmount", + "type": "uint256" + } + ], + "name": "_reduceReserves", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x601a0bf1" + }, + { + "constant": true, + "inputs": [], + "name": "initialExchangeRateMantissa", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x675d972c" + }, + { + "constant": true, + "inputs": [], + "name": "accrualBlockNumber", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x6c540baf" + }, + { + "constant": true, + "inputs": [], + "name": "underlying", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x6f307dc3" + }, + { + "constant": true, + "inputs": [ + { + "name": "owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x70a08231" + }, + { + "constant": false, + "inputs": [], + "name": "totalBorrowsCurrent", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x73acee98" + }, + { + "constant": false, + "inputs": [ + { + "name": "redeemAmount", + "type": "uint256" + } + ], + "name": "redeemUnderlying", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x852a12e3" + }, + { + "constant": true, + "inputs": [], + "name": "totalReserves", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x8f840ddd" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x95d89b41" + }, + { + "constant": true, + "inputs": [ + { + "name": "account", + "type": "address" + } + ], + "name": "borrowBalanceStored", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x95dd9193" + }, + { + "constant": false, + "inputs": [ + { + "name": "mintAmount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xa0712d68" + }, + { + "constant": false, + "inputs": [], + "name": "accrueInterest", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xa6afed95" + }, + { + "constant": false, + "inputs": [ + { + "name": "dst", + "type": "address" + }, + { + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xa9059cbb" + }, + { + "constant": true, + "inputs": [], + "name": "borrowIndex", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xaa5af0fd" + }, + { + "constant": true, + "inputs": [], + "name": "supplyRatePerBlock", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xae9d70b0" + }, + { + "constant": false, + "inputs": [ + { + "name": "liquidator", + "type": "address" + }, + { + "name": "borrower", + "type": "address" + }, + { + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "seize", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xb2a02ff1" + }, + { + "constant": false, + "inputs": [ + { + "name": "newPendingAdmin", + "type": "address" + } + ], + "name": "_setPendingAdmin", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xb71d1a0c" + }, + { + "constant": false, + "inputs": [], + "name": "exchangeRateCurrent", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xbd6d894d" + }, + { + "constant": true, + "inputs": [ + { + "name": "account", + "type": "address" + } + ], + "name": "getAccountSnapshot", + "outputs": [ + { + "name": "", + "type": "uint256" + }, + { + "name": "", + "type": "uint256" + }, + { + "name": "", + "type": "uint256" + }, + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xc37f68e2" + }, + { + "constant": false, + "inputs": [ + { + "name": "borrowAmount", + "type": "uint256" + } + ], + "name": "borrow", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xc5ebeaec" + }, + { + "constant": false, + "inputs": [ + { + "name": "redeemTokens", + "type": "uint256" + } + ], + "name": "redeem", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xdb006a75" + }, + { + "constant": true, + "inputs": [ + { + "name": "owner", + "type": "address" + }, + { + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xdd62ed3e" + }, + { + "constant": false, + "inputs": [], + "name": "_acceptAdmin", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xe9c714f2" + }, + { + "constant": false, + "inputs": [ + { + "name": "newInterestRateModel", + "type": "address" + } + ], + "name": "_setInterestRateModel", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xf2b3abbd" + }, + { + "constant": true, + "inputs": [], + "name": "interestRateModel", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xf3fdb15a" + }, + { + "constant": false, + "inputs": [ + { + "name": "borrower", + "type": "address" + }, + { + "name": "repayAmount", + "type": "uint256" + }, + { + "name": "cTokenCollateral", + "type": "address" + } + ], + "name": "liquidateBorrow", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xf5e3c462" + }, + { + "constant": true, + "inputs": [], + "name": "admin", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xf851a440" + }, + { + "constant": true, + "inputs": [], + "name": "borrowRatePerBlock", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xf8f9da28" + }, + { + "constant": false, + "inputs": [ + { + "name": "newReserveFactorMantissa", + "type": "uint256" + } + ], + "name": "_setReserveFactor", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xfca7820b" + }, + { + "constant": true, + "inputs": [], + "name": "isCToken", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xfe9c44ae" + }, + { + "inputs": [ + { + "name": "underlying_", + "type": "address" + }, + { + "name": "comptroller_", + "type": "address" + }, + { + "name": "interestRateModel_", + "type": "address" + }, + { + "name": "initialExchangeRateMantissa_", + "type": "uint256" + }, + { + "name": "name_", + "type": "string" + }, + { + "name": "symbol_", + "type": "string" + }, + { + "name": "decimals_", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor", + "signature": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "interestAccumulated", + "type": "uint256" + }, + { + "indexed": false, + "name": "borrowIndex", + "type": "uint256" + }, + { + "indexed": false, + "name": "totalBorrows", + "type": "uint256" + } + ], + "name": "AccrueInterest", + "type": "event", + "signature": "0x875352fb3fadeb8c0be7cbbe8ff761b308fa7033470cd0287f02f3436fd76cb9" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "minter", + "type": "address" + }, + { + "indexed": false, + "name": "mintAmount", + "type": "uint256" + }, + { + "indexed": false, + "name": "mintTokens", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event", + "signature": "0x4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "redeemer", + "type": "address" + }, + { + "indexed": false, + "name": "redeemAmount", + "type": "uint256" + }, + { + "indexed": false, + "name": "redeemTokens", + "type": "uint256" + } + ], + "name": "Redeem", + "type": "event", + "signature": "0xe5b754fb1abb7f01b499791d0b820ae3b6af3424ac1c59768edb53f4ec31a929" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "name": "borrowAmount", + "type": "uint256" + }, + { + "indexed": false, + "name": "accountBorrows", + "type": "uint256" + }, + { + "indexed": false, + "name": "totalBorrows", + "type": "uint256" + } + ], + "name": "Borrow", + "type": "event", + "signature": "0x13ed6866d4e1ee6da46f845c46d7e54120883d75c5ea9a2dacc1c4ca8984ab80" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "payer", + "type": "address" + }, + { + "indexed": false, + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "name": "repayAmount", + "type": "uint256" + }, + { + "indexed": false, + "name": "accountBorrows", + "type": "uint256" + }, + { + "indexed": false, + "name": "totalBorrows", + "type": "uint256" + } + ], + "name": "RepayBorrow", + "type": "event", + "signature": "0x1a2a22cb034d26d1854bdc6666a5b91fe25efbbb5dcad3b0355478d6f5c362a1" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "liquidator", + "type": "address" + }, + { + "indexed": false, + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "name": "repayAmount", + "type": "uint256" + }, + { + "indexed": false, + "name": "cTokenCollateral", + "type": "address" + }, + { + "indexed": false, + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "LiquidateBorrow", + "type": "event", + "signature": "0x298637f684da70674f26509b10f07ec2fbc77a335ab1e7d6215a4b2484d8bb52" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "oldPendingAdmin", + "type": "address" + }, + { + "indexed": false, + "name": "newPendingAdmin", + "type": "address" + } + ], + "name": "NewPendingAdmin", + "type": "event", + "signature": "0xca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a9" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "oldAdmin", + "type": "address" + }, + { + "indexed": false, + "name": "newAdmin", + "type": "address" + } + ], + "name": "NewAdmin", + "type": "event", + "signature": "0xf9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "oldComptroller", + "type": "address" + }, + { + "indexed": false, + "name": "newComptroller", + "type": "address" + } + ], + "name": "NewComptroller", + "type": "event", + "signature": "0x7ac369dbd14fa5ea3f473ed67cc9d598964a77501540ba6751eb0b3decf5870d" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "oldInterestRateModel", + "type": "address" + }, + { + "indexed": false, + "name": "newInterestRateModel", + "type": "address" + } + ], + "name": "NewMarketInterestRateModel", + "type": "event", + "signature": "0xedffc32e068c7c95dfd4bdfd5c4d939a084d6b11c4199eac8436ed234d72f926" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "oldReserveFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "name": "newReserveFactorMantissa", + "type": "uint256" + } + ], + "name": "NewReserveFactor", + "type": "event", + "signature": "0xaaa68312e2ea9d50e16af5068410ab56e1a1fd06037b1a35664812c30f821460" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "admin", + "type": "address" + }, + { + "indexed": false, + "name": "reduceAmount", + "type": "uint256" + }, + { + "indexed": false, + "name": "newTotalReserves", + "type": "uint256" + } + ], + "name": "ReservesReduced", + "type": "event", + "signature": "0x3bad0c59cf2f06e7314077049f48a93578cd16f5ef92329f1dab1420a99c177e" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "error", + "type": "uint256" + }, + { + "indexed": false, + "name": "info", + "type": "uint256" + }, + { + "indexed": false, + "name": "detail", + "type": "uint256" + } + ], + "name": "Failure", + "type": "event", + "signature": "0x45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "from", + "type": "address" + }, + { + "indexed": true, + "name": "to", + "type": "address" + }, + { + "indexed": false, + "name": "amount", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event", + "signature": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event", + "signature": "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925" + } + ], + "cWBTC": [ + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x06fdde03" + }, + { + "constant": false, + "inputs": [ + { + "name": "spender", + "type": "address" + }, + { + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x095ea7b3" + }, + { + "constant": false, + "inputs": [ + { + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "repayBorrow", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x0e752702" + }, + { + "constant": true, + "inputs": [], + "name": "reserveFactorMantissa", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x173b9904" + }, + { + "constant": false, + "inputs": [ + { + "name": "account", + "type": "address" + } + ], + "name": "borrowBalanceCurrent", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x17bfdfbc" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x18160ddd" + }, + { + "constant": true, + "inputs": [], + "name": "exchangeRateStored", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x182df0f5" + }, + { + "constant": false, + "inputs": [ + { + "name": "src", + "type": "address" + }, + { + "name": "dst", + "type": "address" + }, + { + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x23b872dd" + }, + { + "constant": false, + "inputs": [ + { + "name": "borrower", + "type": "address" + }, + { + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "repayBorrowBehalf", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x2608f818" + }, + { + "constant": true, + "inputs": [], + "name": "pendingAdmin", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x26782247" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x313ce567" + }, + { + "constant": false, + "inputs": [ + { + "name": "owner", + "type": "address" + } + ], + "name": "balanceOfUnderlying", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x3af9e669" + }, + { + "constant": true, + "inputs": [], + "name": "getCash", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x3b1d21a2" + }, + { + "constant": false, + "inputs": [ + { + "name": "newComptroller", + "type": "address" + } + ], + "name": "_setComptroller", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x4576b5db" + }, + { + "constant": true, + "inputs": [], + "name": "totalBorrows", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x47bd3718" + }, + { + "constant": true, + "inputs": [], + "name": "comptroller", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x5fe3b567" + }, + { + "constant": false, + "inputs": [ + { + "name": "reduceAmount", + "type": "uint256" + } + ], + "name": "_reduceReserves", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x601a0bf1" + }, + { + "constant": true, + "inputs": [], + "name": "initialExchangeRateMantissa", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x675d972c" + }, + { + "constant": true, + "inputs": [], + "name": "accrualBlockNumber", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x6c540baf" + }, + { + "constant": true, + "inputs": [], + "name": "underlying", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x6f307dc3" + }, + { + "constant": true, + "inputs": [ + { + "name": "owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x70a08231" + }, + { + "constant": false, + "inputs": [], + "name": "totalBorrowsCurrent", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x73acee98" + }, + { + "constant": false, + "inputs": [ + { + "name": "redeemAmount", + "type": "uint256" + } + ], + "name": "redeemUnderlying", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x852a12e3" + }, + { + "constant": true, + "inputs": [], + "name": "totalReserves", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x8f840ddd" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x95d89b41" + }, + { + "constant": true, + "inputs": [ + { + "name": "account", + "type": "address" + } + ], + "name": "borrowBalanceStored", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x95dd9193" + }, + { + "constant": false, + "inputs": [ + { + "name": "mintAmount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xa0712d68" + }, + { + "constant": false, + "inputs": [], + "name": "accrueInterest", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xa6afed95" + }, + { + "constant": false, + "inputs": [ + { + "name": "dst", + "type": "address" + }, + { + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xa9059cbb" + }, + { + "constant": true, + "inputs": [], + "name": "borrowIndex", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xaa5af0fd" + }, + { + "constant": true, + "inputs": [], + "name": "supplyRatePerBlock", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xae9d70b0" + }, + { + "constant": false, + "inputs": [ + { + "name": "liquidator", + "type": "address" + }, + { + "name": "borrower", + "type": "address" + }, + { + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "seize", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xb2a02ff1" + }, + { + "constant": false, + "inputs": [ + { + "name": "newPendingAdmin", + "type": "address" + } + ], + "name": "_setPendingAdmin", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xb71d1a0c" + }, + { + "constant": false, + "inputs": [], + "name": "exchangeRateCurrent", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xbd6d894d" + }, + { + "constant": true, + "inputs": [ + { + "name": "account", + "type": "address" + } + ], + "name": "getAccountSnapshot", + "outputs": [ + { + "name": "", + "type": "uint256" + }, + { + "name": "", + "type": "uint256" + }, + { + "name": "", + "type": "uint256" + }, + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xc37f68e2" + }, + { + "constant": false, + "inputs": [ + { + "name": "borrowAmount", + "type": "uint256" + } + ], + "name": "borrow", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xc5ebeaec" + }, + { + "constant": false, + "inputs": [ + { + "name": "redeemTokens", + "type": "uint256" + } + ], + "name": "redeem", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xdb006a75" + }, + { + "constant": true, + "inputs": [ + { + "name": "owner", + "type": "address" + }, + { + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xdd62ed3e" + }, + { + "constant": false, + "inputs": [], + "name": "_acceptAdmin", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xe9c714f2" + }, + { + "constant": false, + "inputs": [ + { + "name": "newInterestRateModel", + "type": "address" + } + ], + "name": "_setInterestRateModel", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xf2b3abbd" + }, + { + "constant": true, + "inputs": [], + "name": "interestRateModel", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xf3fdb15a" + }, + { + "constant": false, + "inputs": [ + { + "name": "borrower", + "type": "address" + }, + { + "name": "repayAmount", + "type": "uint256" + }, + { + "name": "cTokenCollateral", + "type": "address" + } + ], + "name": "liquidateBorrow", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xf5e3c462" + }, + { + "constant": true, + "inputs": [], + "name": "admin", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xf851a440" + }, + { + "constant": true, + "inputs": [], + "name": "borrowRatePerBlock", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xf8f9da28" + }, + { + "constant": false, + "inputs": [ + { + "name": "newReserveFactorMantissa", + "type": "uint256" + } + ], + "name": "_setReserveFactor", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xfca7820b" + }, + { + "constant": true, + "inputs": [], + "name": "isCToken", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xfe9c44ae" + }, + { + "inputs": [ + { + "name": "underlying_", + "type": "address" + }, + { + "name": "comptroller_", + "type": "address" + }, + { + "name": "interestRateModel_", + "type": "address" + }, + { + "name": "initialExchangeRateMantissa_", + "type": "uint256" + }, + { + "name": "name_", + "type": "string" + }, + { + "name": "symbol_", + "type": "string" + }, + { + "name": "decimals_", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor", + "signature": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "interestAccumulated", + "type": "uint256" + }, + { + "indexed": false, + "name": "borrowIndex", + "type": "uint256" + }, + { + "indexed": false, + "name": "totalBorrows", + "type": "uint256" + } + ], + "name": "AccrueInterest", + "type": "event", + "signature": "0x875352fb3fadeb8c0be7cbbe8ff761b308fa7033470cd0287f02f3436fd76cb9" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "minter", + "type": "address" + }, + { + "indexed": false, + "name": "mintAmount", + "type": "uint256" + }, + { + "indexed": false, + "name": "mintTokens", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event", + "signature": "0x4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "redeemer", + "type": "address" + }, + { + "indexed": false, + "name": "redeemAmount", + "type": "uint256" + }, + { + "indexed": false, + "name": "redeemTokens", + "type": "uint256" + } + ], + "name": "Redeem", + "type": "event", + "signature": "0xe5b754fb1abb7f01b499791d0b820ae3b6af3424ac1c59768edb53f4ec31a929" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "name": "borrowAmount", + "type": "uint256" + }, + { + "indexed": false, + "name": "accountBorrows", + "type": "uint256" + }, + { + "indexed": false, + "name": "totalBorrows", + "type": "uint256" + } + ], + "name": "Borrow", + "type": "event", + "signature": "0x13ed6866d4e1ee6da46f845c46d7e54120883d75c5ea9a2dacc1c4ca8984ab80" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "payer", + "type": "address" + }, + { + "indexed": false, + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "name": "repayAmount", + "type": "uint256" + }, + { + "indexed": false, + "name": "accountBorrows", + "type": "uint256" + }, + { + "indexed": false, + "name": "totalBorrows", + "type": "uint256" + } + ], + "name": "RepayBorrow", + "type": "event", + "signature": "0x1a2a22cb034d26d1854bdc6666a5b91fe25efbbb5dcad3b0355478d6f5c362a1" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "liquidator", + "type": "address" + }, + { + "indexed": false, + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "name": "repayAmount", + "type": "uint256" + }, + { + "indexed": false, + "name": "cTokenCollateral", + "type": "address" + }, + { + "indexed": false, + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "LiquidateBorrow", + "type": "event", + "signature": "0x298637f684da70674f26509b10f07ec2fbc77a335ab1e7d6215a4b2484d8bb52" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "oldPendingAdmin", + "type": "address" + }, + { + "indexed": false, + "name": "newPendingAdmin", + "type": "address" + } + ], + "name": "NewPendingAdmin", + "type": "event", + "signature": "0xca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a9" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "oldAdmin", + "type": "address" + }, + { + "indexed": false, + "name": "newAdmin", + "type": "address" + } + ], + "name": "NewAdmin", + "type": "event", + "signature": "0xf9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "oldComptroller", + "type": "address" + }, + { + "indexed": false, + "name": "newComptroller", + "type": "address" + } + ], + "name": "NewComptroller", + "type": "event", + "signature": "0x7ac369dbd14fa5ea3f473ed67cc9d598964a77501540ba6751eb0b3decf5870d" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "oldInterestRateModel", + "type": "address" + }, + { + "indexed": false, + "name": "newInterestRateModel", + "type": "address" + } + ], + "name": "NewMarketInterestRateModel", + "type": "event", + "signature": "0xedffc32e068c7c95dfd4bdfd5c4d939a084d6b11c4199eac8436ed234d72f926" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "oldReserveFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "name": "newReserveFactorMantissa", + "type": "uint256" + } + ], + "name": "NewReserveFactor", + "type": "event", + "signature": "0xaaa68312e2ea9d50e16af5068410ab56e1a1fd06037b1a35664812c30f821460" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "admin", + "type": "address" + }, + { + "indexed": false, + "name": "reduceAmount", + "type": "uint256" + }, + { + "indexed": false, + "name": "newTotalReserves", + "type": "uint256" + } + ], + "name": "ReservesReduced", + "type": "event", + "signature": "0x3bad0c59cf2f06e7314077049f48a93578cd16f5ef92329f1dab1420a99c177e" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "error", + "type": "uint256" + }, + { + "indexed": false, + "name": "info", + "type": "uint256" + }, + { + "indexed": false, + "name": "detail", + "type": "uint256" + } + ], + "name": "Failure", + "type": "event", + "signature": "0x45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "from", + "type": "address" + }, + { + "indexed": true, + "name": "to", + "type": "address" + }, + { + "indexed": false, + "name": "amount", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event", + "signature": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event", + "signature": "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925" + } + ], + "USDC": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event", + "signature": "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925" }, { - "constant": true, - "inputs": [], - "name": "comptroller", - "outputs": [ + "anonymous": false, + "inputs": [ { - "name": "", + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" } ], - "payable": false, - "stateMutability": "view", - "type": "function", - "signature": "0x5fe3b567" + "name": "Transfer", + "type": "event", + "signature": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" }, { - "constant": false, + "constant": true, "inputs": [ { - "name": "reduceAmount", - "type": "uint256" - } - ], - "name": "_reduceReserves", - "outputs": [ + "internalType": "address", + "name": "owner", + "type": "address" + }, { - "name": "", - "type": "uint256" + "internalType": "address", + "name": "spender", + "type": "address" } ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function", - "signature": "0x601a0bf1" - }, - { - "constant": true, - "inputs": [], - "name": "initialExchangeRateMantissa", + "name": "allowance", "outputs": [ { - "name": "", + "internalType": "uint256", + "name": "remaining", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function", - "signature": "0x675d972c" + "signature": "0xdd62ed3e" }, { - "constant": true, - "inputs": [], - "name": "accrualBlockNumber", - "outputs": [ + "constant": false, + "inputs": [ { - "name": "", + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", "type": "uint256" } ], - "payable": false, - "stateMutability": "view", - "type": "function", - "signature": "0x6c540baf" - }, - { - "constant": true, - "inputs": [], - "name": "underlying", + "name": "approve", "outputs": [ { - "name": "", - "type": "address" + "internalType": "bool", + "name": "success", + "type": "bool" } ], "payable": false, - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function", - "signature": "0x6f307dc3" + "signature": "0x095ea7b3" }, { "constant": true, "inputs": [ { + "internalType": "address", "name": "owner", "type": "address" } @@ -38767,7 +43259,8 @@ "name": "balanceOf", "outputs": [ { - "name": "", + "internalType": "uint256", + "name": "balance", "type": "uint256" } ], @@ -38777,54 +43270,36 @@ "signature": "0x70a08231" }, { - "constant": false, + "constant": true, "inputs": [], - "name": "totalBorrowsCurrent", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function", - "signature": "0x73acee98" - }, - { - "constant": false, - "inputs": [ - { - "name": "redeemAmount", - "type": "uint256" - } - ], - "name": "redeemUnderlying", + "name": "decimals", "outputs": [ { + "internalType": "uint8", "name": "", - "type": "uint256" + "type": "uint8" } ], "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function", - "signature": "0x852a12e3" + "signature": "0x313ce567" }, { "constant": true, "inputs": [], - "name": "totalReserves", + "name": "name", "outputs": [ { + "internalType": "string", "name": "", - "type": "uint256" + "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function", - "signature": "0x8f840ddd" + "signature": "0x06fdde03" }, { "constant": true, @@ -38832,6 +43307,7 @@ "name": "symbol", "outputs": [ { + "internalType": "string", "name": "", "type": "string" } @@ -38843,67 +43319,30 @@ }, { "constant": true, - "inputs": [ - { - "name": "account", - "type": "address" - } - ], - "name": "borrowBalanceStored", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function", - "signature": "0x95dd9193" - }, - { - "constant": false, - "inputs": [ - { - "name": "mintAmount", - "type": "uint256" - } - ], - "name": "mint", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function", - "signature": "0xa0712d68" - }, - { - "constant": false, "inputs": [], - "name": "accrueInterest", + "name": "totalSupply", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function", - "signature": "0xa6afed95" + "signature": "0x18160ddd" }, { "constant": false, "inputs": [ { + "internalType": "address", "name": "dst", "type": "address" }, { + "internalType": "uint256", "name": "amount", "type": "uint256" } @@ -38911,7 +43350,8 @@ "name": "transfer", "outputs": [ { - "name": "", + "internalType": "bool", + "name": "success", "type": "bool" } ], @@ -38920,186 +43360,139 @@ "type": "function", "signature": "0xa9059cbb" }, - { - "constant": true, - "inputs": [], - "name": "borrowIndex", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function", - "signature": "0xaa5af0fd" - }, - { - "constant": true, - "inputs": [], - "name": "supplyRatePerBlock", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function", - "signature": "0xae9d70b0" - }, { "constant": false, "inputs": [ { - "name": "liquidator", + "internalType": "address", + "name": "src", "type": "address" }, { - "name": "borrower", + "internalType": "address", + "name": "dst", "type": "address" }, { - "name": "seizeTokens", - "type": "uint256" - } - ], - "name": "seize", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function", - "signature": "0xb2a02ff1" - }, - { - "constant": false, - "inputs": [ - { - "name": "newPendingAdmin", - "type": "address" + "internalType": "uint256", + "name": "amount", + "type": "uint256" } ], - "name": "_setPendingAdmin", + "name": "transferFrom", "outputs": [ { - "name": "", - "type": "uint256" + "internalType": "bool", + "name": "success", + "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function", - "signature": "0xb71d1a0c" - }, + "signature": "0x23b872dd" + } + ], + "DSR_Updateable": [ { - "constant": false, - "inputs": [], - "name": "exchangeRateCurrent", - "outputs": [ + "inputs": [ { - "name": "", + "internalType": "uint256", + "name": "jumpMultiplierPerYear", "type": "uint256" + }, + { + "internalType": "uint256", + "name": "kink_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "pot_", + "type": "address" + }, + { + "internalType": "address", + "name": "jug_", + "type": "address" } ], "payable": false, "stateMutability": "nonpayable", - "type": "function", - "signature": "0xbd6d894d" + "type": "constructor", + "signature": "constructor" }, { - "constant": true, + "anonymous": false, "inputs": [ { - "name": "account", - "type": "address" - } - ], - "name": "getAccountSnapshot", - "outputs": [ - { - "name": "", + "indexed": false, + "internalType": "uint256", + "name": "baseRatePerBlock", "type": "uint256" }, { - "name": "", + "indexed": false, + "internalType": "uint256", + "name": "multiplierPerBlock", "type": "uint256" }, { - "name": "", + "indexed": false, + "internalType": "uint256", + "name": "jumpMultiplierPerBlock", "type": "uint256" }, { - "name": "", + "indexed": false, + "internalType": "uint256", + "name": "kink", "type": "uint256" } ], - "payable": false, - "stateMutability": "view", - "type": "function", - "signature": "0xc37f68e2" + "name": "NewInterestParams", + "type": "event", + "signature": "0x6960ab234c7ef4b0c9197100f5393cfcde7c453ac910a27bd2000aa1dd4c068d" }, { - "constant": false, - "inputs": [ - { - "name": "borrowAmount", - "type": "uint256" - } - ], - "name": "borrow", + "constant": true, + "inputs": [], + "name": "assumedOneMinusReserveFactorMantissa", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function", - "signature": "0xc5ebeaec" + "signature": "0x6dac7cd5" }, { - "constant": false, - "inputs": [ - { - "name": "redeemTokens", - "type": "uint256" - } - ], - "name": "redeem", + "constant": true, + "inputs": [], + "name": "baseRatePerBlock", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function", - "signature": "0xdb006a75" + "signature": "0xf14039de" }, { "constant": true, - "inputs": [ - { - "name": "owner", - "type": "address" - }, - { - "name": "spender", - "type": "address" - } - ], - "name": "allowance", + "inputs": [], + "name": "blocksPerYear", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } @@ -39107,107 +43500,132 @@ "payable": false, "stateMutability": "view", "type": "function", - "signature": "0xdd62ed3e" + "signature": "0xa385fb96" }, { - "constant": false, + "constant": true, "inputs": [], - "name": "_acceptAdmin", + "name": "dsrPerBlock", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function", - "signature": "0xe9c714f2" + "signature": "0x96456c5c" }, { - "constant": false, - "inputs": [ - { - "name": "newInterestRateModel", - "type": "address" - } - ], - "name": "_setInterestRateModel", + "constant": true, + "inputs": [], + "name": "gapPerBlock", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function", - "signature": "0xf2b3abbd" + "signature": "0xf52d21f3" }, { "constant": true, - "inputs": [], - "name": "interestRateModel", + "inputs": [ + { + "internalType": "uint256", + "name": "cash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrows", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserves", + "type": "uint256" + } + ], + "name": "getBorrowRate", "outputs": [ { + "internalType": "uint256", "name": "", - "type": "address" + "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function", - "signature": "0xf3fdb15a" + "signature": "0x15f24053" }, { - "constant": false, + "constant": true, "inputs": [ { - "name": "borrower", - "type": "address" + "internalType": "uint256", + "name": "cash", + "type": "uint256" }, { - "name": "repayAmount", + "internalType": "uint256", + "name": "borrows", "type": "uint256" }, { - "name": "cTokenCollateral", - "type": "address" + "internalType": "uint256", + "name": "reserves", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveFactorMantissa", + "type": "uint256" } ], - "name": "liquidateBorrow", + "name": "getSupplyRate", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function", - "signature": "0xf5e3c462" + "signature": "0xb8168816" }, { "constant": true, "inputs": [], - "name": "admin", + "name": "isInterestRateModel", "outputs": [ { + "internalType": "bool", "name": "", - "type": "address" + "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function", - "signature": "0xf851a440" + "signature": "0x2191f92a" }, { "constant": true, "inputs": [], - "name": "borrowRatePerBlock", + "name": "jumpMultiplierPerBlock", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } @@ -39215,75 +43633,87 @@ "payable": false, "stateMutability": "view", "type": "function", - "signature": "0xf8f9da28" + "signature": "0xb9f9850a" }, { - "constant": false, - "inputs": [ - { - "name": "newReserveFactorMantissa", - "type": "uint256" - } - ], - "name": "_setReserveFactor", + "constant": true, + "inputs": [], + "name": "kink", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function", - "signature": "0xfca7820b" + "signature": "0xfd2da339" }, { "constant": true, "inputs": [], - "name": "isCToken", + "name": "multiplierPerBlock", "outputs": [ { + "internalType": "uint256", "name": "", - "type": "bool" + "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function", - "signature": "0xfe9c44ae" + "signature": "0x8726bb89" }, { - "inputs": [ - { - "name": "underlying_", - "type": "address" - }, - { - "name": "comptroller_", - "type": "address" - }, - { - "name": "interestRateModel_", - "type": "address" - }, + "constant": false, + "inputs": [], + "name": "poke", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x18178358" + }, + { + "constant": true, + "inputs": [ { - "name": "initialExchangeRateMantissa_", + "internalType": "uint256", + "name": "cash", "type": "uint256" }, { - "name": "name_", - "type": "string" + "internalType": "uint256", + "name": "borrows", + "type": "uint256" }, { - "name": "symbol_", - "type": "string" - }, + "internalType": "uint256", + "name": "reserves", + "type": "uint256" + } + ], + "name": "utilizationRate", + "outputs": [ { - "name": "decimals_", + "internalType": "uint256", + "name": "", "type": "uint256" } ], "payable": false, + "stateMutability": "pure", + "type": "function", + "signature": "0x6e71e2d8" + } + ], + "ComptrollerG7": [ + { + "inputs": [], + "payable": false, "stateMutability": "nonpayable", "type": "constructor", "signature": "constructor" @@ -39293,600 +43723,549 @@ "inputs": [ { "indexed": false, - "name": "interestAccumulated", - "type": "uint256" - }, - { - "indexed": false, - "name": "borrowIndex", - "type": "uint256" + "internalType": "string", + "name": "action", + "type": "string" }, { "indexed": false, - "name": "totalBorrows", - "type": "uint256" + "internalType": "bool", + "name": "pauseState", + "type": "bool" } ], - "name": "AccrueInterest", + "name": "ActionPaused", "type": "event", - "signature": "0x875352fb3fadeb8c0be7cbbe8ff761b308fa7033470cd0287f02f3436fd76cb9" + "signature": "0xef159d9a32b2472e32b098f954f3ce62d232939f1c207070b584df1814de2de0" }, { "anonymous": false, "inputs": [ { "indexed": false, - "name": "minter", + "internalType": "contract CToken", + "name": "cToken", "type": "address" }, { "indexed": false, - "name": "mintAmount", - "type": "uint256" + "internalType": "string", + "name": "action", + "type": "string" }, { "indexed": false, - "name": "mintTokens", - "type": "uint256" + "internalType": "bool", + "name": "pauseState", + "type": "bool" } ], - "name": "Mint", + "name": "ActionPaused", "type": "event", - "signature": "0x4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f" + "signature": "0x71aec636243f9709bb0007ae15e9afb8150ab01716d75fd7573be5cc096e03b0" }, { "anonymous": false, "inputs": [ { "indexed": false, - "name": "redeemer", + "internalType": "address", + "name": "recipient", "type": "address" }, { "indexed": false, - "name": "redeemAmount", - "type": "uint256" - }, - { - "indexed": false, - "name": "redeemTokens", + "internalType": "uint256", + "name": "amount", "type": "uint256" } ], - "name": "Redeem", + "name": "CompGranted", "type": "event", - "signature": "0xe5b754fb1abb7f01b499791d0b820ae3b6af3424ac1c59768edb53f4ec31a929" + "signature": "0x98b2f82a3a07f223a0be64b3d0f47711c64dccd1feafb94aa28156b38cd9695c" }, { "anonymous": false, "inputs": [ { - "indexed": false, - "name": "borrower", + "indexed": true, + "internalType": "contract CToken", + "name": "cToken", "type": "address" }, { "indexed": false, - "name": "borrowAmount", + "internalType": "uint256", + "name": "newSpeed", "type": "uint256" - }, + } + ], + "name": "CompSpeedUpdated", + "type": "event", + "signature": "0x2ab93f65628379309f36cb125e90d7c902454a545c4f8b8cb0794af75c24b807" + }, + { + "anonymous": false, + "inputs": [ { - "indexed": false, - "name": "accountBorrows", - "type": "uint256" + "indexed": true, + "internalType": "address", + "name": "contributor", + "type": "address" }, { "indexed": false, - "name": "totalBorrows", + "internalType": "uint256", + "name": "newSpeed", "type": "uint256" } ], - "name": "Borrow", + "name": "ContributorCompSpeedUpdated", "type": "event", - "signature": "0x13ed6866d4e1ee6da46f845c46d7e54120883d75c5ea9a2dacc1c4ca8984ab80" + "signature": "0x386537fa92edc3319af95f1f904dcf1900021e4f3f4e08169a577a09076e66b3" }, { "anonymous": false, "inputs": [ { - "indexed": false, - "name": "payer", + "indexed": true, + "internalType": "contract CToken", + "name": "cToken", "type": "address" }, { - "indexed": false, + "indexed": true, + "internalType": "address", "name": "borrower", "type": "address" }, { "indexed": false, - "name": "repayAmount", - "type": "uint256" - }, - { - "indexed": false, - "name": "accountBorrows", + "internalType": "uint256", + "name": "compDelta", "type": "uint256" }, { "indexed": false, - "name": "totalBorrows", + "internalType": "uint256", + "name": "compBorrowIndex", "type": "uint256" } ], - "name": "RepayBorrow", + "name": "DistributedBorrowerComp", "type": "event", - "signature": "0x1a2a22cb034d26d1854bdc6666a5b91fe25efbbb5dcad3b0355478d6f5c362a1" + "signature": "0x1fc3ecc087d8d2d15e23d0032af5a47059c3892d003d8e139fdcb6bb327c99a6" }, { "anonymous": false, "inputs": [ { - "indexed": false, - "name": "liquidator", + "indexed": true, + "internalType": "contract CToken", + "name": "cToken", "type": "address" }, { - "indexed": false, - "name": "borrower", + "indexed": true, + "internalType": "address", + "name": "supplier", "type": "address" }, { "indexed": false, - "name": "repayAmount", + "internalType": "uint256", + "name": "compDelta", "type": "uint256" }, { "indexed": false, - "name": "cTokenCollateral", - "type": "address" - }, - { - "indexed": false, - "name": "seizeTokens", + "internalType": "uint256", + "name": "compSupplyIndex", "type": "uint256" } ], - "name": "LiquidateBorrow", + "name": "DistributedSupplierComp", "type": "event", - "signature": "0x298637f684da70674f26509b10f07ec2fbc77a335ab1e7d6215a4b2484d8bb52" + "signature": "0x2caecd17d02f56fa897705dcc740da2d237c373f70686f4e0d9bd3bf0400ea7a" }, { "anonymous": false, "inputs": [ { "indexed": false, - "name": "oldPendingAdmin", - "type": "address" + "internalType": "uint256", + "name": "error", + "type": "uint256" }, { "indexed": false, - "name": "newPendingAdmin", - "type": "address" + "internalType": "uint256", + "name": "info", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "detail", + "type": "uint256" } ], - "name": "NewPendingAdmin", + "name": "Failure", "type": "event", - "signature": "0xca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a9" + "signature": "0x45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0" }, { "anonymous": false, "inputs": [ { "indexed": false, - "name": "oldAdmin", + "internalType": "contract CToken", + "name": "cToken", "type": "address" }, { "indexed": false, - "name": "newAdmin", + "internalType": "address", + "name": "account", "type": "address" } ], - "name": "NewAdmin", + "name": "MarketEntered", "type": "event", - "signature": "0xf9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc" + "signature": "0x3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a5" }, { "anonymous": false, "inputs": [ { "indexed": false, - "name": "oldComptroller", + "internalType": "contract CToken", + "name": "cToken", "type": "address" }, { "indexed": false, - "name": "newComptroller", + "internalType": "address", + "name": "account", "type": "address" } ], - "name": "NewComptroller", + "name": "MarketExited", "type": "event", - "signature": "0x7ac369dbd14fa5ea3f473ed67cc9d598964a77501540ba6751eb0b3decf5870d" + "signature": "0xe699a64c18b07ac5b7301aa273f36a2287239eb9501d81950672794afba29a0d" }, { "anonymous": false, "inputs": [ { "indexed": false, - "name": "oldInterestRateModel", - "type": "address" - }, - { - "indexed": false, - "name": "newInterestRateModel", + "internalType": "contract CToken", + "name": "cToken", "type": "address" } ], - "name": "NewMarketInterestRateModel", + "name": "MarketListed", "type": "event", - "signature": "0xedffc32e068c7c95dfd4bdfd5c4d939a084d6b11c4199eac8436ed234d72f926" + "signature": "0xcf583bb0c569eb967f806b11601c4cb93c10310485c67add5f8362c2f212321f" }, { "anonymous": false, "inputs": [ { - "indexed": false, - "name": "oldReserveFactorMantissa", - "type": "uint256" + "indexed": true, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" }, { "indexed": false, - "name": "newReserveFactorMantissa", + "internalType": "uint256", + "name": "newBorrowCap", "type": "uint256" } ], - "name": "NewReserveFactor", + "name": "NewBorrowCap", "type": "event", - "signature": "0xaaa68312e2ea9d50e16af5068410ab56e1a1fd06037b1a35664812c30f821460" + "signature": "0x6f1951b2aad10f3fc81b86d91105b413a5b3f847a34bbc5ce1904201b14438f6" }, { "anonymous": false, "inputs": [ { "indexed": false, - "name": "admin", + "internalType": "address", + "name": "oldBorrowCapGuardian", "type": "address" }, { "indexed": false, - "name": "reduceAmount", + "internalType": "address", + "name": "newBorrowCapGuardian", + "type": "address" + } + ], + "name": "NewBorrowCapGuardian", + "type": "event", + "signature": "0xeda98690e518e9a05f8ec6837663e188211b2da8f4906648b323f2c1d4434e29" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldCloseFactorMantissa", "type": "uint256" }, { "indexed": false, - "name": "newTotalReserves", + "internalType": "uint256", + "name": "newCloseFactorMantissa", "type": "uint256" } ], - "name": "ReservesReduced", + "name": "NewCloseFactor", "type": "event", - "signature": "0x3bad0c59cf2f06e7314077049f48a93578cd16f5ef92329f1dab1420a99c177e" + "signature": "0x3b9670cf975d26958e754b57098eaa2ac914d8d2a31b83257997b9f346110fd9" }, { "anonymous": false, "inputs": [ { "indexed": false, - "name": "error", - "type": "uint256" + "internalType": "contract CToken", + "name": "cToken", + "type": "address" }, { "indexed": false, - "name": "info", + "internalType": "uint256", + "name": "oldCollateralFactorMantissa", "type": "uint256" }, { "indexed": false, - "name": "detail", + "internalType": "uint256", + "name": "newCollateralFactorMantissa", "type": "uint256" } ], - "name": "Failure", + "name": "NewCollateralFactor", "type": "event", - "signature": "0x45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0" + "signature": "0x70483e6592cd5182d45ac970e05bc62cdcc90e9d8ef2c2dbe686cf383bcd7fc5" }, { "anonymous": false, "inputs": [ { - "indexed": true, - "name": "from", - "type": "address" - }, - { - "indexed": true, - "name": "to", - "type": "address" + "indexed": false, + "internalType": "uint256", + "name": "oldLiquidationIncentiveMantissa", + "type": "uint256" }, { "indexed": false, - "name": "amount", + "internalType": "uint256", + "name": "newLiquidationIncentiveMantissa", "type": "uint256" } ], - "name": "Transfer", + "name": "NewLiquidationIncentive", "type": "event", - "signature": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" + "signature": "0xaeba5a6c40a8ac138134bff1aaa65debf25971188a58804bad717f82f0ec1316" }, { "anonymous": false, "inputs": [ { - "indexed": true, - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "name": "spender", + "indexed": false, + "internalType": "address", + "name": "oldPauseGuardian", "type": "address" }, { "indexed": false, - "name": "amount", - "type": "uint256" + "internalType": "address", + "name": "newPauseGuardian", + "type": "address" } ], - "name": "Approval", + "name": "NewPauseGuardian", "type": "event", - "signature": "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925" - } - ], - "cWBTC": [ - { - "constant": true, - "inputs": [], - "name": "name", - "outputs": [ - { - "name": "", - "type": "string" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function", - "signature": "0x06fdde03" + "signature": "0x0613b6ee6a04f0d09f390e4d9318894b9f6ac7fd83897cd8d18896ba579c401e" }, { - "constant": false, + "anonymous": false, "inputs": [ { - "name": "spender", + "indexed": false, + "internalType": "contract PriceOracle", + "name": "oldPriceOracle", "type": "address" }, { - "name": "amount", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [ - { - "name": "", - "type": "bool" + "indexed": false, + "internalType": "contract PriceOracle", + "name": "newPriceOracle", + "type": "address" } ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function", - "signature": "0x095ea7b3" + "name": "NewPriceOracle", + "type": "event", + "signature": "0xd52b2b9b7e9ee655fcb95d2e5b9e0c9f69e7ef2b8e9d2d0ea78402d576d22e22" }, { "constant": false, "inputs": [ { - "name": "repayAmount", - "type": "uint256" - } - ], - "name": "repayBorrow", - "outputs": [ - { - "name": "", - "type": "uint256" + "internalType": "contract Unitroller", + "name": "unitroller", + "type": "address" } ], + "name": "_become", + "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function", - "signature": "0x0e752702" + "signature": "0x1d504dc6" }, { "constant": true, "inputs": [], - "name": "reserveFactorMantissa", + "name": "_borrowGuardianPaused", "outputs": [ { + "internalType": "bool", "name": "", - "type": "uint256" + "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function", - "signature": "0x173b9904" + "signature": "0xe6653f3d" }, { "constant": false, "inputs": [ { - "name": "account", + "internalType": "address", + "name": "recipient", "type": "address" - } - ], - "name": "borrowBalanceCurrent", - "outputs": [ + }, { - "name": "", + "internalType": "uint256", + "name": "amount", "type": "uint256" } ], + "name": "_grantComp", + "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function", - "signature": "0x17bfdfbc" - }, - { - "constant": true, - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function", - "signature": "0x18160ddd" + "signature": "0x27efe3cb" }, { "constant": true, "inputs": [], - "name": "exchangeRateStored", + "name": "_mintGuardianPaused", "outputs": [ { + "internalType": "bool", "name": "", - "type": "uint256" + "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function", - "signature": "0x182df0f5" + "signature": "0x3c94786f" }, { "constant": false, "inputs": [ { - "name": "src", - "type": "address" - }, - { - "name": "dst", + "internalType": "address", + "name": "newBorrowCapGuardian", "type": "address" - }, - { - "name": "amount", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [ - { - "name": "", - "type": "bool" } ], + "name": "_setBorrowCapGuardian", + "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function", - "signature": "0x23b872dd" + "signature": "0x391957d7" }, { "constant": false, "inputs": [ { - "name": "borrower", + "internalType": "contract CToken", + "name": "cToken", "type": "address" }, { - "name": "repayAmount", - "type": "uint256" + "internalType": "bool", + "name": "state", + "type": "bool" } ], - "name": "repayBorrowBehalf", + "name": "_setBorrowPaused", "outputs": [ { + "internalType": "bool", "name": "", - "type": "uint256" + "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function", - "signature": "0x2608f818" - }, - { - "constant": true, - "inputs": [], - "name": "pendingAdmin", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function", - "signature": "0x26782247" - }, - { - "constant": true, - "inputs": [], - "name": "decimals", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function", - "signature": "0x313ce567" + "signature": "0x18c882a5" }, { "constant": false, "inputs": [ { - "name": "owner", - "type": "address" - } - ], - "name": "balanceOfUnderlying", - "outputs": [ - { - "name": "", + "internalType": "uint256", + "name": "newCloseFactorMantissa", "type": "uint256" } ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function", - "signature": "0x3af9e669" - }, - { - "constant": true, - "inputs": [], - "name": "getCash", + "name": "_setCloseFactor", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], "payable": false, - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function", - "signature": "0x3b1d21a2" + "signature": "0x317b0b77" }, { "constant": false, "inputs": [ { - "name": "newComptroller", + "internalType": "contract CToken", + "name": "cToken", "type": "address" + }, + { + "internalType": "uint256", + "name": "newCollateralFactorMantissa", + "type": "uint256" } ], - "name": "_setComptroller", + "name": "_setCollateralFactor", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } @@ -39894,49 +44273,63 @@ "payable": false, "stateMutability": "nonpayable", "type": "function", - "signature": "0x4576b5db" + "signature": "0xe4028eee" }, { - "constant": true, - "inputs": [], - "name": "totalBorrows", - "outputs": [ + "constant": false, + "inputs": [ { - "name": "", + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "compSpeed", "type": "uint256" } ], + "name": "_setCompSpeed", + "outputs": [], "payable": false, - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function", - "signature": "0x47bd3718" + "signature": "0x434caf25" }, { - "constant": true, - "inputs": [], - "name": "comptroller", - "outputs": [ + "constant": false, + "inputs": [ { - "name": "", + "internalType": "address", + "name": "contributor", "type": "address" + }, + { + "internalType": "uint256", + "name": "compSpeed", + "type": "uint256" } ], + "name": "_setContributorCompSpeed", + "outputs": [], "payable": false, - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function", - "signature": "0x5fe3b567" + "signature": "0x598ee1cb" }, { "constant": false, "inputs": [ { - "name": "reduceAmount", + "internalType": "uint256", + "name": "newLiquidationIncentiveMantissa", "type": "uint256" } ], - "name": "_reduceReserves", + "name": "_setLiquidationIncentive", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } @@ -39944,79 +44337,91 @@ "payable": false, "stateMutability": "nonpayable", "type": "function", - "signature": "0x601a0bf1" + "signature": "0x4fd42e17" }, { - "constant": true, - "inputs": [], - "name": "initialExchangeRateMantissa", - "outputs": [ + "constant": false, + "inputs": [ { - "name": "", - "type": "uint256" + "internalType": "contract CToken[]", + "name": "cTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "newBorrowCaps", + "type": "uint256[]" } ], + "name": "_setMarketBorrowCaps", + "outputs": [], "payable": false, - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function", - "signature": "0x675d972c" + "signature": "0x607ef6c1" }, { - "constant": true, - "inputs": [], - "name": "accrualBlockNumber", - "outputs": [ + "constant": false, + "inputs": [ { - "name": "", - "type": "uint256" + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "state", + "type": "bool" } ], - "payable": false, - "stateMutability": "view", - "type": "function", - "signature": "0x6c540baf" - }, - { - "constant": true, - "inputs": [], - "name": "underlying", + "name": "_setMintPaused", "outputs": [ { + "internalType": "bool", "name": "", - "type": "address" + "type": "bool" } ], "payable": false, - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function", - "signature": "0x6f307dc3" + "signature": "0x3bcf7ec1" }, { - "constant": true, + "constant": false, "inputs": [ { - "name": "owner", + "internalType": "address", + "name": "newPauseGuardian", "type": "address" } ], - "name": "balanceOf", + "name": "_setPauseGuardian", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], "payable": false, - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function", - "signature": "0x70a08231" + "signature": "0x5f5af1aa" }, { "constant": false, - "inputs": [], - "name": "totalBorrowsCurrent", + "inputs": [ + { + "internalType": "contract PriceOracle", + "name": "newOracle", + "type": "address" + } + ], + "name": "_setPriceOracle", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } @@ -40024,425 +44429,457 @@ "payable": false, "stateMutability": "nonpayable", "type": "function", - "signature": "0x73acee98" + "signature": "0x55ee1fe1" }, { "constant": false, "inputs": [ { - "name": "redeemAmount", - "type": "uint256" + "internalType": "bool", + "name": "state", + "type": "bool" } ], - "name": "redeemUnderlying", + "name": "_setSeizePaused", "outputs": [ { + "internalType": "bool", "name": "", - "type": "uint256" + "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function", - "signature": "0x852a12e3" + "signature": "0x2d70db78" }, { - "constant": true, - "inputs": [], - "name": "totalReserves", - "outputs": [ + "constant": false, + "inputs": [ { - "name": "", - "type": "uint256" + "internalType": "bool", + "name": "state", + "type": "bool" } ], - "payable": false, - "stateMutability": "view", - "type": "function", - "signature": "0x8f840ddd" - }, - { - "constant": true, - "inputs": [], - "name": "symbol", + "name": "_setTransferPaused", "outputs": [ { + "internalType": "bool", "name": "", - "type": "string" + "type": "bool" } ], "payable": false, - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function", - "signature": "0x95d89b41" + "signature": "0x8ebf6364" }, { - "constant": true, + "constant": false, "inputs": [ { - "name": "account", + "internalType": "contract CToken", + "name": "cToken", "type": "address" } ], - "name": "borrowBalanceStored", + "name": "_supportMarket", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], "payable": false, - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function", - "signature": "0x95dd9193" + "signature": "0xa76b3fda" }, { - "constant": false, + "constant": true, "inputs": [ { - "name": "mintAmount", + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", "type": "uint256" } ], - "name": "mint", + "name": "accountAssets", "outputs": [ { + "internalType": "contract CToken", "name": "", - "type": "uint256" + "type": "address" } ], "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function", - "signature": "0xa0712d68" + "signature": "0xdce15449" }, { - "constant": false, + "constant": true, "inputs": [], - "name": "accrueInterest", + "name": "admin", "outputs": [ { + "internalType": "address", "name": "", - "type": "uint256" + "type": "address" } ], "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function", - "signature": "0xa6afed95" + "signature": "0xf851a440" }, { - "constant": false, + "constant": true, "inputs": [ { - "name": "dst", - "type": "address" - }, - { - "name": "amount", + "internalType": "uint256", + "name": "", "type": "uint256" } ], - "name": "transfer", + "name": "allMarkets", "outputs": [ { + "internalType": "contract CToken", "name": "", - "type": "bool" + "type": "address" } ], "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function", - "signature": "0xa9059cbb" + "signature": "0x52d84d1e" }, { - "constant": true, - "inputs": [], - "name": "borrowIndex", + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + } + ], + "name": "borrowAllowed", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], "payable": false, - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function", - "signature": "0xaa5af0fd" + "signature": "0xda3d454c" }, { "constant": true, "inputs": [], - "name": "supplyRatePerBlock", + "name": "borrowCapGuardian", "outputs": [ { + "internalType": "address", "name": "", - "type": "uint256" + "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function", - "signature": "0xae9d70b0" + "signature": "0x21af4569" }, { - "constant": false, + "constant": true, "inputs": [ { - "name": "liquidator", - "type": "address" - }, - { - "name": "borrower", + "internalType": "address", + "name": "", "type": "address" - }, - { - "name": "seizeTokens", - "type": "uint256" } ], - "name": "seize", + "name": "borrowCaps", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function", - "signature": "0xb2a02ff1" + "signature": "0x4a584432" }, { - "constant": false, + "constant": true, "inputs": [ { - "name": "newPendingAdmin", + "internalType": "address", + "name": "", "type": "address" } ], - "name": "_setPendingAdmin", + "name": "borrowGuardianPaused", "outputs": [ { + "internalType": "bool", "name": "", - "type": "uint256" + "type": "bool" } ], "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function", - "signature": "0xb71d1a0c" + "signature": "0x6d154ea5" }, { "constant": false, - "inputs": [], - "name": "exchangeRateCurrent", - "outputs": [ + "inputs": [ { - "name": "", + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "borrowAmount", "type": "uint256" } ], + "name": "borrowVerify", + "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function", - "signature": "0xbd6d894d" + "signature": "0x5c778605" }, { "constant": true, "inputs": [ { + "internalType": "address", "name": "account", "type": "address" + }, + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" } ], - "name": "getAccountSnapshot", + "name": "checkMembership", "outputs": [ { + "internalType": "bool", "name": "", - "type": "uint256" - }, - { - "name": "", - "type": "uint256" - }, - { - "name": "", - "type": "uint256" - }, - { - "name": "", - "type": "uint256" + "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function", - "signature": "0xc37f68e2" + "signature": "0x929fe9a1" }, { "constant": false, "inputs": [ { - "name": "borrowAmount", - "type": "uint256" - } - ], - "name": "borrow", - "outputs": [ + "internalType": "address", + "name": "holder", + "type": "address" + }, { - "name": "", - "type": "uint256" + "internalType": "contract CToken[]", + "name": "cTokens", + "type": "address[]" } ], + "name": "claimComp", + "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function", - "signature": "0xc5ebeaec" + "signature": "0x1c3db2e0" }, { "constant": false, "inputs": [ { - "name": "redeemTokens", - "type": "uint256" - } - ], - "name": "redeem", - "outputs": [ + "internalType": "address[]", + "name": "holders", + "type": "address[]" + }, { - "name": "", - "type": "uint256" + "internalType": "contract CToken[]", + "name": "cTokens", + "type": "address[]" + }, + { + "internalType": "bool", + "name": "borrowers", + "type": "bool" + }, + { + "internalType": "bool", + "name": "suppliers", + "type": "bool" } ], + "name": "claimComp", + "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function", - "signature": "0xdb006a75" + "signature": "0x6810dfa6" }, { - "constant": true, + "constant": false, "inputs": [ { - "name": "owner", - "type": "address" - }, - { - "name": "spender", + "internalType": "address", + "name": "holder", "type": "address" } ], - "name": "allowance", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], + "name": "claimComp", + "outputs": [], "payable": false, - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function", - "signature": "0xdd62ed3e" + "signature": "0xe9af0292" }, { - "constant": false, + "constant": true, "inputs": [], - "name": "_acceptAdmin", + "name": "closeFactorMantissa", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function", - "signature": "0xe9c714f2" + "signature": "0xe8755446" }, { - "constant": false, + "constant": true, "inputs": [ { - "name": "newInterestRateModel", + "internalType": "address", + "name": "", "type": "address" } ], - "name": "_setInterestRateModel", + "name": "compAccrued", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function", - "signature": "0xf2b3abbd" + "signature": "0xcc7ebdc4" }, { "constant": true, - "inputs": [], - "name": "interestRateModel", - "outputs": [ + "inputs": [ { + "internalType": "address", "name": "", "type": "address" } ], + "name": "compBorrowState", + "outputs": [ + { + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + } + ], "payable": false, "stateMutability": "view", "type": "function", - "signature": "0xf3fdb15a" + "signature": "0x8c57804e" }, { - "constant": false, + "constant": true, "inputs": [ { - "name": "borrower", + "internalType": "address", + "name": "", "type": "address" }, { - "name": "repayAmount", - "type": "uint256" - }, - { - "name": "cTokenCollateral", + "internalType": "address", + "name": "", "type": "address" } ], - "name": "liquidateBorrow", + "name": "compBorrowerIndex", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } ], "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function", - "signature": "0xf5e3c462" + "signature": "0xca0af043" }, { "constant": true, - "inputs": [], - "name": "admin", - "outputs": [ + "inputs": [ { + "internalType": "address", "name": "", "type": "address" } ], - "payable": false, - "stateMutability": "view", - "type": "function", - "signature": "0xf851a440" - }, - { - "constant": true, - "inputs": [], - "name": "borrowRatePerBlock", + "name": "compContributorSpeeds", "outputs": [ { + "internalType": "uint256", "name": "", "type": "uint256" } @@ -40450,606 +44887,535 @@ "payable": false, "stateMutability": "view", "type": "function", - "signature": "0xf8f9da28" + "signature": "0x986ab838" }, { - "constant": false, - "inputs": [ - { - "name": "newReserveFactorMantissa", - "type": "uint256" - } - ], - "name": "_setReserveFactor", + "constant": true, + "inputs": [], + "name": "compInitialIndex", "outputs": [ { + "internalType": "uint224", "name": "", - "type": "uint256" + "type": "uint224" } ], "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function", - "signature": "0xfca7820b" + "signature": "0xa7f0e231" }, { "constant": true, "inputs": [], - "name": "isCToken", + "name": "compRate", "outputs": [ { + "internalType": "uint256", "name": "", - "type": "bool" + "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function", - "signature": "0xfe9c44ae" + "signature": "0xaa900754" }, { + "constant": true, "inputs": [ { - "name": "underlying_", - "type": "address" - }, - { - "name": "comptroller_", - "type": "address" - }, - { - "name": "interestRateModel_", + "internalType": "address", + "name": "", "type": "address" - }, - { - "name": "initialExchangeRateMantissa_", - "type": "uint256" - }, - { - "name": "name_", - "type": "string" - }, - { - "name": "symbol_", - "type": "string" - }, + } + ], + "name": "compSpeeds", + "outputs": [ { - "name": "decimals_", + "internalType": "uint256", + "name": "", "type": "uint256" } ], "payable": false, - "stateMutability": "nonpayable", - "type": "constructor", - "signature": "constructor" + "stateMutability": "view", + "type": "function", + "signature": "0x1d7b33d7" }, { - "anonymous": false, + "constant": true, "inputs": [ { - "indexed": false, - "name": "interestAccumulated", - "type": "uint256" + "internalType": "address", + "name": "", + "type": "address" }, { - "indexed": false, - "name": "borrowIndex", - "type": "uint256" - }, + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compSupplierIndex", + "outputs": [ { - "indexed": false, - "name": "totalBorrows", + "internalType": "uint256", + "name": "", "type": "uint256" } ], - "name": "AccrueInterest", - "type": "event", - "signature": "0x875352fb3fadeb8c0be7cbbe8ff761b308fa7033470cd0287f02f3436fd76cb9" + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xb21be7fd" }, { - "anonymous": false, + "constant": true, "inputs": [ { - "indexed": false, - "name": "minter", + "internalType": "address", + "name": "", "type": "address" - }, + } + ], + "name": "compSupplyState", + "outputs": [ { - "indexed": false, - "name": "mintAmount", - "type": "uint256" + "internalType": "uint224", + "name": "index", + "type": "uint224" }, { - "indexed": false, - "name": "mintTokens", - "type": "uint256" + "internalType": "uint32", + "name": "block", + "type": "uint32" } ], - "name": "Mint", - "type": "event", - "signature": "0x4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f" + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x6b79c38d" }, { - "anonymous": false, - "inputs": [ + "constant": true, + "inputs": [], + "name": "comptrollerImplementation", + "outputs": [ { - "indexed": false, - "name": "redeemer", + "internalType": "address", + "name": "", "type": "address" - }, - { - "indexed": false, - "name": "redeemAmount", - "type": "uint256" - }, - { - "indexed": false, - "name": "redeemTokens", - "type": "uint256" } ], - "name": "Redeem", - "type": "event", - "signature": "0xe5b754fb1abb7f01b499791d0b820ae3b6af3424ac1c59768edb53f4ec31a929" + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xbb82aa5e" }, { - "anonymous": false, + "constant": false, "inputs": [ { - "indexed": false, - "name": "borrower", - "type": "address" - }, - { - "indexed": false, - "name": "borrowAmount", - "type": "uint256" - }, - { - "indexed": false, - "name": "accountBorrows", - "type": "uint256" - }, + "internalType": "address[]", + "name": "cTokens", + "type": "address[]" + } + ], + "name": "enterMarkets", + "outputs": [ { - "indexed": false, - "name": "totalBorrows", - "type": "uint256" + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" } ], - "name": "Borrow", - "type": "event", - "signature": "0x13ed6866d4e1ee6da46f845c46d7e54120883d75c5ea9a2dacc1c4ca8984ab80" + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xc2998238" }, { - "anonymous": false, + "constant": false, "inputs": [ { - "indexed": false, - "name": "payer", - "type": "address" - }, - { - "indexed": false, - "name": "borrower", + "internalType": "address", + "name": "cTokenAddress", "type": "address" - }, - { - "indexed": false, - "name": "repayAmount", - "type": "uint256" - }, - { - "indexed": false, - "name": "accountBorrows", - "type": "uint256" - }, + } + ], + "name": "exitMarket", + "outputs": [ { - "indexed": false, - "name": "totalBorrows", + "internalType": "uint256", + "name": "", "type": "uint256" } ], - "name": "RepayBorrow", - "type": "event", - "signature": "0x1a2a22cb034d26d1854bdc6666a5b91fe25efbbb5dcad3b0355478d6f5c362a1" + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xede4edd0" }, { - "anonymous": false, + "constant": true, "inputs": [ { - "indexed": false, - "name": "liquidator", - "type": "address" - }, - { - "indexed": false, - "name": "borrower", + "internalType": "address", + "name": "account", "type": "address" - }, + } + ], + "name": "getAccountLiquidity", + "outputs": [ { - "indexed": false, - "name": "repayAmount", + "internalType": "uint256", + "name": "", "type": "uint256" }, { - "indexed": false, - "name": "cTokenCollateral", - "type": "address" + "internalType": "uint256", + "name": "", + "type": "uint256" }, { - "indexed": false, - "name": "seizeTokens", + "internalType": "uint256", + "name": "", "type": "uint256" } ], - "name": "LiquidateBorrow", - "type": "event", - "signature": "0x298637f684da70674f26509b10f07ec2fbc77a335ab1e7d6215a4b2484d8bb52" + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x5ec88c79" }, { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "oldPendingAdmin", - "type": "address" - }, + "constant": true, + "inputs": [], + "name": "getAllMarkets", + "outputs": [ { - "indexed": false, - "name": "newPendingAdmin", - "type": "address" + "internalType": "contract CToken[]", + "name": "", + "type": "address[]" } ], - "name": "NewPendingAdmin", - "type": "event", - "signature": "0xca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a9" + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xb0772d0b" }, { - "anonymous": false, + "constant": true, "inputs": [ { - "indexed": false, - "name": "oldAdmin", + "internalType": "address", + "name": "account", "type": "address" - }, + } + ], + "name": "getAssetsIn", + "outputs": [ { - "indexed": false, - "name": "newAdmin", - "type": "address" + "internalType": "contract CToken[]", + "name": "", + "type": "address[]" } ], - "name": "NewAdmin", - "type": "event", - "signature": "0xf9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc" + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xabfceffc" }, { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "oldComptroller", - "type": "address" - }, + "constant": true, + "inputs": [], + "name": "getBlockNumber", + "outputs": [ { - "indexed": false, - "name": "newComptroller", - "type": "address" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "name": "NewComptroller", - "type": "event", - "signature": "0x7ac369dbd14fa5ea3f473ed67cc9d598964a77501540ba6751eb0b3decf5870d" + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x42cbb15c" }, { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "oldInterestRateModel", - "type": "address" - }, + "constant": true, + "inputs": [], + "name": "getCompAddress", + "outputs": [ { - "indexed": false, - "name": "newInterestRateModel", + "internalType": "address", + "name": "", "type": "address" } ], - "name": "NewMarketInterestRateModel", - "type": "event", - "signature": "0xedffc32e068c7c95dfd4bdfd5c4d939a084d6b11c4199eac8436ed234d72f926" + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x9d1b5a0a" }, { - "anonymous": false, + "constant": true, "inputs": [ { - "indexed": false, - "name": "oldReserveFactorMantissa", - "type": "uint256" + "internalType": "address", + "name": "account", + "type": "address" }, { - "indexed": false, - "name": "newReserveFactorMantissa", - "type": "uint256" - } - ], - "name": "NewReserveFactor", - "type": "event", - "signature": "0xaaa68312e2ea9d50e16af5068410ab56e1a1fd06037b1a35664812c30f821460" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "admin", + "internalType": "address", + "name": "cTokenModify", "type": "address" }, { - "indexed": false, - "name": "reduceAmount", + "internalType": "uint256", + "name": "redeemTokens", "type": "uint256" }, { - "indexed": false, - "name": "newTotalReserves", + "internalType": "uint256", + "name": "borrowAmount", "type": "uint256" } ], - "name": "ReservesReduced", - "type": "event", - "signature": "0x3bad0c59cf2f06e7314077049f48a93578cd16f5ef92329f1dab1420a99c177e" - }, - { - "anonymous": false, - "inputs": [ + "name": "getHypotheticalAccountLiquidity", + "outputs": [ { - "indexed": false, - "name": "error", + "internalType": "uint256", + "name": "", "type": "uint256" }, { - "indexed": false, - "name": "info", + "internalType": "uint256", + "name": "", "type": "uint256" }, { - "indexed": false, - "name": "detail", + "internalType": "uint256", + "name": "", "type": "uint256" } ], - "name": "Failure", - "type": "event", - "signature": "0x45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0" + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x4e79238f" }, { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "from", - "type": "address" - }, - { - "indexed": true, - "name": "to", - "type": "address" - }, + "constant": true, + "inputs": [], + "name": "isComptroller", + "outputs": [ { - "indexed": false, - "name": "amount", - "type": "uint256" + "internalType": "bool", + "name": "", + "type": "bool" } ], - "name": "Transfer", - "type": "event", - "signature": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x007e3dd2" }, { - "anonymous": false, + "constant": true, "inputs": [ { - "indexed": true, - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "name": "spender", + "internalType": "address", + "name": "", "type": "address" - }, - { - "indexed": false, - "name": "amount", - "type": "uint256" } ], - "name": "Approval", - "type": "event", - "signature": "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925" - } - ], - "USDC": [ - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "spender", - "type": "address" - }, + "name": "lastContributorBlock", + "outputs": [ { - "indexed": false, "internalType": "uint256", - "name": "amount", + "name": "", "type": "uint256" } ], - "name": "Approval", - "type": "event", - "signature": "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925" + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xbea6b8b8" }, { - "anonymous": false, + "constant": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "from", + "name": "cTokenBorrowed", "type": "address" }, { - "indexed": true, "internalType": "address", - "name": "to", + "name": "cTokenCollateral", "type": "address" }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event", - "signature": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" - }, - { - "constant": true, - "inputs": [ { "internalType": "address", - "name": "owner", + "name": "liquidator", "type": "address" }, { "internalType": "address", - "name": "spender", + "name": "borrower", "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" } ], - "name": "allowance", + "name": "liquidateBorrowAllowed", "outputs": [ { "internalType": "uint256", - "name": "remaining", + "name": "", "type": "uint256" } ], "payable": false, - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function", - "signature": "0xdd62ed3e" + "signature": "0x5fc7e71e" }, { "constant": false, "inputs": [ { "internalType": "address", - "name": "spender", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", "type": "address" }, { "internalType": "uint256", - "name": "amount", + "name": "actualRepayAmount", "type": "uint256" - } - ], - "name": "approve", - "outputs": [ + }, { - "internalType": "bool", - "name": "success", - "type": "bool" + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" } ], + "name": "liquidateBorrowVerify", + "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function", - "signature": "0x095ea7b3" + "signature": "0x47ef3b3b" }, { "constant": true, "inputs": [ { "internalType": "address", - "name": "owner", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenCollateral", "type": "address" + }, + { + "internalType": "uint256", + "name": "actualRepayAmount", + "type": "uint256" } ], - "name": "balanceOf", + "name": "liquidateCalculateSeizeTokens", "outputs": [ { "internalType": "uint256", - "name": "balance", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function", - "signature": "0x70a08231" + "signature": "0xc488847b" }, { "constant": true, "inputs": [], - "name": "decimals", + "name": "liquidationIncentiveMantissa", "outputs": [ { - "internalType": "uint8", + "internalType": "uint256", "name": "", - "type": "uint8" + "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function", - "signature": "0x313ce567" + "signature": "0x4ada90af" }, { "constant": true, - "inputs": [], - "name": "name", - "outputs": [ + "inputs": [ { - "internalType": "string", + "internalType": "address", "name": "", - "type": "string" + "type": "address" } ], - "payable": false, - "stateMutability": "view", - "type": "function", - "signature": "0x06fdde03" - }, - { - "constant": true, - "inputs": [], - "name": "symbol", + "name": "markets", "outputs": [ { - "internalType": "string", - "name": "", - "type": "string" + "internalType": "bool", + "name": "isListed", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "collateralFactorMantissa", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isComped", + "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function", - "signature": "0x95d89b41" + "signature": "0x8e8f294b" }, { "constant": true, "inputs": [], - "name": "totalSupply", + "name": "maxAssets", "outputs": [ { "internalType": "uint256", @@ -41060,181 +45426,177 @@ "payable": false, "stateMutability": "view", "type": "function", - "signature": "0x18160ddd" + "signature": "0x94b2294b" }, { "constant": false, "inputs": [ { "internalType": "address", - "name": "dst", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "minter", "type": "address" }, { "internalType": "uint256", - "name": "amount", + "name": "mintAmount", "type": "uint256" } ], - "name": "transfer", + "name": "mintAllowed", "outputs": [ { - "internalType": "bool", - "name": "success", - "type": "bool" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], "payable": false, "stateMutability": "nonpayable", "type": "function", - "signature": "0xa9059cbb" + "signature": "0x4ef4c3e1" }, { - "constant": false, + "constant": true, "inputs": [ { "internalType": "address", - "name": "src", - "type": "address" - }, - { - "internalType": "address", - "name": "dst", + "name": "", "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" } ], - "name": "transferFrom", + "name": "mintGuardianPaused", "outputs": [ { "internalType": "bool", - "name": "success", + "name": "", "type": "bool" } ], "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function", - "signature": "0x23b872dd" - } - ], - "DSR_Updateable": [ + "signature": "0x731f0c2b" + }, { + "constant": false, "inputs": [ - { - "internalType": "uint256", - "name": "jumpMultiplierPerYear", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "kink_", - "type": "uint256" - }, { "internalType": "address", - "name": "pot_", + "name": "cToken", "type": "address" }, { "internalType": "address", - "name": "jug_", + "name": "minter", "type": "address" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "constructor", - "signature": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "baseRatePerBlock", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "multiplierPerBlock", - "type": "uint256" }, { - "indexed": false, "internalType": "uint256", - "name": "jumpMultiplierPerBlock", + "name": "actualMintAmount", "type": "uint256" }, { - "indexed": false, "internalType": "uint256", - "name": "kink", + "name": "mintTokens", "type": "uint256" } ], - "name": "NewInterestParams", - "type": "event", - "signature": "0x6960ab234c7ef4b0c9197100f5393cfcde7c453ac910a27bd2000aa1dd4c068d" + "name": "mintVerify", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x41c728b9" }, { "constant": true, "inputs": [], - "name": "assumedOneMinusReserveFactorMantissa", + "name": "oracle", "outputs": [ { - "internalType": "uint256", + "internalType": "contract PriceOracle", "name": "", - "type": "uint256" + "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function", - "signature": "0x6dac7cd5" + "signature": "0x7dc0d1d0" }, { "constant": true, "inputs": [], - "name": "baseRatePerBlock", + "name": "pauseGuardian", "outputs": [ { - "internalType": "uint256", + "internalType": "address", "name": "", - "type": "uint256" + "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function", - "signature": "0xf14039de" + "signature": "0x24a3d622" }, { "constant": true, "inputs": [], - "name": "blocksPerYear", + "name": "pendingAdmin", "outputs": [ { - "internalType": "uint256", + "internalType": "address", "name": "", - "type": "uint256" + "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function", - "signature": "0xa385fb96" + "signature": "0x26782247" }, { "constant": true, "inputs": [], - "name": "dsrPerBlock", + "name": "pendingComptrollerImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xdcfbc0c7" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "redeemer", + "type": "address" + }, + { + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + } + ], + "name": "redeemAllowed", "outputs": [ { "internalType": "uint256", @@ -41243,46 +45605,66 @@ } ], "payable": false, - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function", - "signature": "0x96456c5c" + "signature": "0xeabe7d91" }, { - "constant": true, - "inputs": [], - "name": "gapPerBlock", - "outputs": [ + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "redeemer", + "type": "address" + }, { "internalType": "uint256", - "name": "", + "name": "redeemAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "redeemTokens", "type": "uint256" } ], + "name": "redeemVerify", + "outputs": [], "payable": false, - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function", - "signature": "0xf52d21f3" + "signature": "0x51dff989" }, { - "constant": true, + "constant": false, "inputs": [ { - "internalType": "uint256", - "name": "cash", - "type": "uint256" + "internalType": "address", + "name": "cToken", + "type": "address" }, { - "internalType": "uint256", - "name": "borrows", - "type": "uint256" + "internalType": "address", + "name": "payer", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" }, { "internalType": "uint256", - "name": "reserves", + "name": "repayAmount", "type": "uint256" } ], - "name": "getBorrowRate", + "name": "repayBorrowAllowed", "outputs": [ { "internalType": "uint256", @@ -41291,35 +45673,76 @@ } ], "payable": false, - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function", - "signature": "0x15f24053" + "signature": "0x24008a62" }, { - "constant": true, + "constant": false, "inputs": [ { - "internalType": "uint256", - "name": "cash", - "type": "uint256" + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "payer", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" }, { "internalType": "uint256", - "name": "borrows", + "name": "actualRepayAmount", "type": "uint256" }, { "internalType": "uint256", - "name": "reserves", + "name": "borrowerIndex", "type": "uint256" + } + ], + "name": "repayBorrowVerify", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x1ededc91" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" }, { "internalType": "uint256", - "name": "reserveFactorMantissa", + "name": "seizeTokens", "type": "uint256" } ], - "name": "getSupplyRate", + "name": "seizeAllowed", "outputs": [ { "internalType": "uint256", @@ -41328,14 +45751,14 @@ } ], "payable": false, - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function", - "signature": "0xb8168816" + "signature": "0xd02f7351" }, { "constant": true, "inputs": [], - "name": "isInterestRateModel", + "name": "seizeGuardianPaused", "outputs": [ { "internalType": "bool", @@ -41346,28 +45769,69 @@ "payable": false, "stateMutability": "view", "type": "function", - "signature": "0x2191f92a" + "signature": "0xac0b0bb7" }, { - "constant": true, - "inputs": [], - "name": "jumpMultiplierPerBlock", - "outputs": [ + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, { "internalType": "uint256", - "name": "", + "name": "seizeTokens", "type": "uint256" } ], + "name": "seizeVerify", + "outputs": [], "payable": false, - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function", - "signature": "0xb9f9850a" + "signature": "0x6d35bf91" }, { - "constant": true, - "inputs": [], - "name": "kink", + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "transferTokens", + "type": "uint256" + } + ], + "name": "transferAllowed", "outputs": [ { "internalType": "uint256", @@ -41376,67 +45840,72 @@ } ], "payable": false, - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function", - "signature": "0xfd2da339" + "signature": "0xbdcdc258" }, { "constant": true, "inputs": [], - "name": "multiplierPerBlock", + "name": "transferGuardianPaused", "outputs": [ { - "internalType": "uint256", + "internalType": "bool", "name": "", - "type": "uint256" + "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function", - "signature": "0x8726bb89" + "signature": "0x87f76303" }, { "constant": false, - "inputs": [], - "name": "poke", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function", - "signature": "0x18178358" - }, - { - "constant": true, "inputs": [ { - "internalType": "uint256", - "name": "cash", - "type": "uint256" + "internalType": "address", + "name": "cToken", + "type": "address" }, { - "internalType": "uint256", - "name": "borrows", - "type": "uint256" + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" }, { "internalType": "uint256", - "name": "reserves", + "name": "transferTokens", "type": "uint256" } ], - "name": "utilizationRate", - "outputs": [ + "name": "transferVerify", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x6a56947e" + }, + { + "constant": false, + "inputs": [ { - "internalType": "uint256", - "name": "", - "type": "uint256" + "internalType": "address", + "name": "contributor", + "type": "address" } ], + "name": "updateContributorRewards", + "outputs": [], "payable": false, - "stateMutability": "pure", + "stateMutability": "nonpayable", "type": "function", - "signature": "0x6e71e2d8" + "signature": "0x741b2525" } ] -} +} \ No newline at end of file diff --git a/networks/mainnet.json b/networks/mainnet.json index 39081fb3c..17c870bbb 100644 --- a/networks/mainnet.json +++ b/networks/mainnet.json @@ -64,11 +64,13 @@ "StdComptrollerG6": "0x7d47d3f06A9C10576bc5DC87ceFbf3288F96Ea04", "Base200bps_Slope222bps_Kink90_Jump40": "0x5562024784cc914069d67D89a28e3201bF7b57E7", "SAI": "0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359", + "StdComptrollerG7": "0xbe7616B06f71e363A310Aa8CE8aD99654401ead7", "REP": "0x1985365e9f78359a9B6AD760e32412f4a445E862", "cZRX": "0xB3319f5D18Bc0D84dD1b4825Dcde5d5f7266d407", "cWBTC": "0xC11b1268C1A384e55C48c2391d8d480264A3A7F4", "USDC": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", - "DSR_Updateable": "0xfeD941d39905B23D6FAf02C8301d40bD4834E27F" + "DSR_Updateable": "0xfeD941d39905B23D6FAf02C8301d40bD4834E27F", + "ComptrollerG7": "0xF262E79D53223B0A69CCa13C1f280E54095aD3b6" }, "Blocks": { "cUSDC": 7710760, @@ -113,9 +115,11 @@ "Base200bps_Slope2000bps_Jump8000bps_Kink90": 9847407, "StdComptrollerG6": 11395321, "Base200bps_Slope222bps_Kink90_Jump40": 8983555, + "StdComptrollerG7": 11499181, "cZRX": 7710733, "cWBTC": 8163813, - "DSR_Updateable": 10504587 + "DSR_Updateable": 10504587, + "ComptrollerG7": 11458479 }, "PriceFeed": { "description": "Open Oracle Uniswap Anchored View + UNI", @@ -153,13 +157,13 @@ "contract": "Comptroller", "description": "Standard Comptroller Impl" }, - "StdComptrollerG2": { - "address": "0xf592eF673057a451c49c9433E278c5d59b56132c", + "StdComptroller_2_6": { + "address": "0x97BD4Cc841FC999194174cd1803C543247a014fe", "contract": "Comptroller", "description": "Standard Comptroller Impl" }, - "StdComptroller_2_6": { - "address": "0x97BD4Cc841FC999194174cd1803C543247a014fe", + "StdComptrollerG2": { + "address": "0xf592eF673057a451c49c9433E278c5d59b56132c", "contract": "Comptroller", "description": "Standard Comptroller Impl" }, @@ -182,6 +186,16 @@ "address": "0x7d47d3f06A9C10576bc5DC87ceFbf3288F96Ea04", "contract": "Comptroller", "description": "Standard Comptroller Impl" + }, + "StdComptrollerG7": { + "address": "0xbe7616B06f71e363A310Aa8CE8aD99654401ead7", + "contract": "Comptroller", + "description": "Standard Comptroller Impl" + }, + "ComptrollerG7": { + "address": "0xF262E79D53223B0A69CCa13C1f280E54095aD3b6", + "contract": "Comptroller", + "description": "Standard Comptroller Impl" } }, "Comp": { @@ -248,8 +262,10 @@ "Base200bps_Slope2000bps_Jump8000bps_Kink90": "0x00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000002c68af0bb1400000000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000022b1c8c1227a00000", "StdComptrollerG6": "0x", "Base200bps_Slope222bps_Kink90_Jump40": "0x00000000000000000000000000000000000000000000000000470de4df820000000000000000000000000000000000000000000000000000004ef2fe4dac8cc00000000000000000000000000000000000000000000000000c7d713b49da00000000000000000000000000000000000000000000000000000000000000000028", + "StdComptrollerG7": "0x", "cZRX": "0x000000000000000000000000e41d2489571d322189246dafa5ebde1f4699f4980000000000000000000000003d9819210a31b4961b30ef54be2aed79b9c9cd3b000000000000000000000000bae04cbf96391086dc643e842b517734e214d698000000000000000000000000000000000000000000a56fa5b99019a5c800000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000b436f6d706f756e642030780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004635a525800000000000000000000000000000000000000000000000000000000", - "cWBTC": "0x0000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c5990000000000000000000000003d9819210a31b4961b30ef54be2aed79b9c9cd3b000000000000000000000000bae04cbf96391086dc643e842b517734e214d69800000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000014436f6d706f756e6420577261707065642042544300000000000000000000000000000000000000000000000000000000000000000000000000000000000000056357425443000000000000000000000000000000000000000000000000000000" + "cWBTC": "0x0000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c5990000000000000000000000003d9819210a31b4961b30ef54be2aed79b9c9cd3b000000000000000000000000bae04cbf96391086dc643e842b517734e214d69800000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000014436f6d706f756e6420577261707065642042544300000000000000000000000000000000000000000000000000000000000000000000000000000000000000056357425443000000000000000000000000000000000000000000000000000000", + "ComptrollerG7": "0x" }, "Tokens": { "ZRX": { @@ -584,4 +600,4 @@ "description": "DAIInterestRateModelV3 jump=1090000000000000000 kink=800000000000000000 pot=0x197e90f9fad81970ba7976f33cbd77088e5d7cf7 jug=0x19c0976f590d67707e62397c87829d896dc0f1f1 owner=0x6d903f6003cca6255d85cca4d3b5e5146dc33925" } } -} +} \ No newline at end of file diff --git a/package.json b/package.json index a41246bb7..d8c7b6f74 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "lint": "./script/lint", "repl": "./scenario/script/repl", "profile": "yarn test tests/gasProfiler.js", + "report": "npx run ./script/saddle/gasReport.js", "test": "./script/test", "test:prepare": "NO_RUN=true ./script/test", "checksize": "npx run ./script/saddle/comptrollerSize.js" diff --git a/scenario/src/Builder/ComptrollerImplBuilder.ts b/scenario/src/Builder/ComptrollerImplBuilder.ts index 801af1a9d..f01b4d233 100644 --- a/scenario/src/Builder/ComptrollerImplBuilder.ts +++ b/scenario/src/Builder/ComptrollerImplBuilder.ts @@ -23,6 +23,9 @@ const ComptrollerScenarioG4Contract = getContract('ComptrollerScenarioG4'); const ComptrollerG5Contract = getContract('ComptrollerG5'); const ComptrollerScenarioG5Contract = getContract('ComptrollerScenarioG5'); +const ComptrollerG6Contract = getContract('ComptrollerG6'); +const ComptrollerScenarioG6Contract = getContract('ComptrollerScenarioG6'); + const ComptrollerScenarioContract = getTestContract('ComptrollerScenario'); const ComptrollerContract = getContract('Comptroller'); @@ -124,6 +127,22 @@ export async function buildComptrollerImpl( }) ), + new Fetcher<{ name: StringV }, ComptrollerImplData>( + ` + #### ScenarioG6 + * "ScenarioG6 name:" - The Comptroller Scenario for local testing (G6) + * E.g. "ComptrollerImpl Deploy ScenarioG6 MyScen" + `, + 'ScenarioG6', + [new Arg('name', getStringV)], + async (world, { name }) => ({ + invokation: await ComptrollerScenarioG6Contract.deploy(world, from, []), + name: name.val, + contract: 'ComptrollerScenarioG6Contract', + description: 'ScenarioG6 Comptroller Impl' + }) + ), + new Fetcher<{ name: StringV }, ComptrollerImplData>( ` #### Scenario @@ -235,6 +254,24 @@ export async function buildComptrollerImpl( } ), + new Fetcher<{ name: StringV }, ComptrollerImplData>( + ` + #### StandardG6 + * "StandardG6 name:" - The standard generation 6 Comptroller contract + * E.g. "Comptroller Deploy StandardG6 MyStandard" + `, + 'StandardG6', + [new Arg('name', getStringV)], + async (world, { name }) => { + return { + invokation: await ComptrollerG6Contract.deploy(world, from, []), + name: name.val, + contract: 'ComptrollerG6', + description: 'StandardG6 Comptroller Impl' + }; + } + ), + new Fetcher<{ name: StringV }, ComptrollerImplData>( ` #### Standard diff --git a/scenario/src/Contract/Comptroller.ts b/scenario/src/Contract/Comptroller.ts index 1ac2668c5..af27b4ae2 100644 --- a/scenario/src/Contract/Comptroller.ts +++ b/scenario/src/Contract/Comptroller.ts @@ -60,6 +60,8 @@ interface ComptrollerMethods { updateContributorRewards(account: string): Sendable _grantComp(account: string, encodedNumber): Sendable _setCompRate(encodedNumber): Sendable + _setCompSpeed(cToken: string, encodedNumber): Sendable + _setContributorCompSpeed(account: string, encodedNumber): Sendable _setMarketBorrowCaps(cTokens:string[], borrowCaps:encodedNumber[]): Sendable _setBorrowCapGuardian(string): Sendable borrowCapGuardian(): Callable diff --git a/scenario/src/Event/ComptrollerEvent.ts b/scenario/src/Event/ComptrollerEvent.ts index 7961ce161..50d83024f 100644 --- a/scenario/src/Event/ComptrollerEvent.ts +++ b/scenario/src/Event/ComptrollerEvent.ts @@ -284,6 +284,30 @@ async function setCompRate(world: World, from: string, comptroller: Comptroller, return world; } +async function setCompSpeed(world: World, from: string, comptroller: Comptroller, cToken: CToken, speed: NumberV): Promise { + let invokation = await invoke(world, comptroller.methods._setCompSpeed(cToken._address, speed.encode()), from, ComptrollerErrorReporter); + + world = addAction( + world, + `Comp speed for market ${cToken._address} set to ${speed.show()}`, + invokation + ); + + return world; +} + +async function setContributorCompSpeed(world: World, from: string, comptroller: Comptroller, contributor: string, speed: NumberV): Promise { + let invokation = await invoke(world, comptroller.methods._setContributorCompSpeed(contributor, speed.encode()), from, ComptrollerErrorReporter); + + world = addAction( + world, + `Comp speed for contributor ${contributor} set to ${speed.show()}`, + invokation + ); + + return world; +} + async function printLiquidity(world: World, comptroller: Comptroller): Promise { let enterEvents = await getPastEvents(world, comptroller, 'StdComptroller', 'MarketEntered'); let addresses = enterEvents.map((event) => event.returnValues['account']); @@ -764,6 +788,32 @@ export function comptrollerCommands() { ], (world, from, {comptroller, rate}) => setCompRate(world, from, comptroller, rate) ), + new Command<{comptroller: Comptroller, cToken: CToken, speed: NumberV}>(` + #### SetCompSpeed + * "Comptroller SetCompSpeed " - Sets COMP speed for market + * E.g. "Comptroller SetCompSpeed cToken 1000 + `, + "SetCompSpeed", + [ + new Arg("comptroller", getComptroller, {implicit: true}), + new Arg("cToken", getCTokenV), + new Arg("speed", getNumberV) + ], + (world, from, {comptroller, cToken, speed}) => setCompSpeed(world, from, comptroller, cToken, speed) + ), + new Command<{comptroller: Comptroller, contributor: AddressV, speed: NumberV}>(` + #### SetContributorCompSpeed + * "Comptroller SetContributorCompSpeed " - Sets COMP speed for contributor + * E.g. "Comptroller SetContributorCompSpeed contributor 1000 + `, + "SetContributorCompSpeed", + [ + new Arg("comptroller", getComptroller, {implicit: true}), + new Arg("contributor", getAddressV), + new Arg("speed", getNumberV) + ], + (world, from, {comptroller, contributor, speed}) => setContributorCompSpeed(world, from, comptroller, contributor.val, speed) + ), new Command<{comptroller: Comptroller, cTokens: CToken[], borrowCaps: NumberV[]}>(` #### SetMarketBorrowCaps diff --git a/scenario/src/Event/ComptrollerImplEvent.ts b/scenario/src/Event/ComptrollerImplEvent.ts index fbbfc4cbd..9ca9c49a5 100644 --- a/scenario/src/Event/ComptrollerImplEvent.ts +++ b/scenario/src/Event/ComptrollerImplEvent.ts @@ -196,6 +196,29 @@ async function becomeG5( return world; } +async function becomeG6( + world: World, + from: string, + comptrollerImpl: ComptrollerImpl, + unitroller: Unitroller +): Promise { + let invokation = await invoke( + world, + comptrollerImpl.methods._become(unitroller._address), + from, + ComptrollerErrorReporter + ); + + if (!world.dryRun) { + // Skip this specifically on dry runs since it's likely to crash due to a number of reasons + world = await mergeContractABI(world, 'Comptroller', unitroller, unitroller.name, comptrollerImpl.name); + } + + world = addAction(world, `Become ${unitroller._address}'s Comptroller Impl`, invokation); + + return world; +} + async function become( world: World, from: string, @@ -384,6 +407,26 @@ export function comptrollerImplCommands() { { namePos: 1 } ), + new Command<{ + unitroller: Unitroller; + comptrollerImpl: ComptrollerImpl; + }>( + ` + #### BecomeG6 + * "ComptrollerImpl BecomeG6" - Become the comptroller, if possible. + * E.g. "ComptrollerImpl MyImpl BecomeG6 + `, + 'BecomeG6', + [ + new Arg('unitroller', getUnitroller, { implicit: true }), + new Arg('comptrollerImpl', getComptrollerImpl) + ], + (world, from, { unitroller, comptrollerImpl }) => { + return becomeG6(world, from, comptrollerImpl, unitroller) + }, + { namePos: 1 } + ), + new Command<{ unitroller: Unitroller; comptrollerImpl: ComptrollerImpl; diff --git a/script/saddle/gasReport.js b/script/saddle/gasReport.js new file mode 100644 index 000000000..c76f29f0e --- /dev/null +++ b/script/saddle/gasReport.js @@ -0,0 +1,16 @@ +const fs = require('fs'); + +(async () => { + fs.readFile('gasCosts.json', (err, data) => { + if (err) throw err; + let gasReport = JSON.parse(data); + + console.log("Gas report") + console.log("----------\n") + + for (const [scenario, report] of Object.entries(gasReport)) { + cost = report.fee; + console.log(scenario, "-", cost, "gas"); + } + }); +})(); diff --git a/spec/scenario/CoreMacros b/spec/scenario/CoreMacros index 38d0b3b5d..3d0f0efc5 100644 --- a/spec/scenario/CoreMacros +++ b/spec/scenario/CoreMacros @@ -41,6 +41,10 @@ Macro NewComptroller price=1.0 closeFactor=0.1 maxAssets=20 ComptrollerImpl Deploy ScenarioG5 ComptrollerG5 Unitroller SetPendingImpl ComptrollerG5 ComptrollerImpl ComptrollerG5 BecomeG5 + --g6 + ComptrollerImpl Deploy ScenarioG6 ComptrollerG6 + Unitroller SetPendingImpl ComptrollerG6 + ComptrollerImpl ComptrollerG6 BecomeG6 --current ComptrollerImpl Deploy Scenario ComptrollerScen Unitroller SetPendingImpl ComptrollerScen diff --git a/spec/scenario/Flywheel/CompSpeed.scen b/spec/scenario/Flywheel/CompSpeed.scen new file mode 100644 index 000000000..fe0f1ef37 --- /dev/null +++ b/spec/scenario/Flywheel/CompSpeed.scen @@ -0,0 +1,95 @@ +-- Tests for the grants and math patch + +Macro FlywheelComptroller price=1.0 borrowRate=0.000005 compInitAmount=5000000e18 + Unitroller Deploy + PriceOracle Deploy Fixed price + PriceOracleProxy Deploy Admin (PriceOracle Address) (Address Zero) (Address Zero) (Address Zero) (Address Zero) (Address Zero) + ----g2 + ComptrollerImpl Deploy ScenarioG2 ComptrollerScenG2 + Unitroller SetPendingImpl ComptrollerScenG2 + ComptrollerImpl ComptrollerScenG2 BecomeG2 + --list some tokens + Comptroller SetPriceOracle (PriceOracleProxy Address) + Comptroller SetMaxAssets 20 + Comptroller SetCloseFactor 0.5 + Comptroller LiquidationIncentive 1.1 + NewCToken ZRX cZRX + NewCToken BAT cBAT + Support cZRX collateralFactor:0.5 + Support cBAT collateralFactor:0.5 + -- final + ComptrollerImpl Deploy ScenarioG3 ComptrollerScen + Unitroller SetPendingImpl ComptrollerScen + ComptrollerImpl ComptrollerScen BecomeG3 1e18 [cZRX cBAT] + Erc20 Deploy Standard COMP "COMP Token" 18 + Give (Address Comptroller) compInitAmount COMP + +Macro GrantsComptroller + FlywheelComptroller + -- g4 + ComptrollerImpl Deploy ScenarioG4 ComptrollerScen + Unitroller SetPendingImpl ComptrollerScen + ComptrollerImpl ComptrollerScen BecomeG4 + -- g5 + ComptrollerImpl Deploy ScenarioG5 ComptrollerScen + Unitroller SetPendingImpl ComptrollerScen + ComptrollerImpl ComptrollerScen BecomeG5 + -- current + ComptrollerImpl Deploy Scenario ComptrollerScen + Unitroller SetPendingImpl ComptrollerScen + ComptrollerImpl ComptrollerScen Become + +Macro InitSpeeds + Prep Geoff 100e18 ZRX cZRX + Mint Geoff 50e18 cZRX--tokenbalance = 50e18 / 2e9 = 2.5e10 + Prep Coburn Some BAT cBAT + Mint Coburn 6e18 cBAT--tokenbalance = 6e18 / 2e9 = 3e9 + EnterMarkets Coburn cBAT + Borrow Coburn 1e18 cZRX + Comptroller SetCompSpeed cZRX 1 + Comptroller SetCompSpeed cBAT 1 + Comptroller RefreshCompSpeeds + Comptroller Send "setCompAddress(address)" (Address COMP) + +Test "COMP speed can be set per market" + GrantsComptroller + InitSpeeds + -- Baseline comp amounts + Assert Equal (Comptroller CompAccrued Geoff) 0 + Assert Equal (Erc20 COMP TokenBalance Geoff) 0 + -- Comp speed can be set + Comptroller SetCompSpeed cZRX 2 + FastForward 1000 Blocks + Comptroller ClaimComp Geoff + Assert Equal (Comptroller CompAccrued Geoff) 0 + Assert Equal (Erc20 COMP TokenBalance Geoff) 2000 + -- Comp speed can be changed + Comptroller SetCompSpeed cZRX 4 + FastForward 1000 Blocks + Comptroller ClaimComp Geoff + Assert Equal (Comptroller CompAccrued Geoff) 0 + Assert Equal (Erc20 COMP TokenBalance Geoff) 6000 + -- Comp speed can be removed + Comptroller SetCompSpeed cZRX 0 + FastForward 1000 Blocks + Comptroller ClaimComp Geoff + Assert Equal (Comptroller CompAccrued Geoff) 0 + Assert Equal (Erc20 COMP TokenBalance Geoff) 6000 + +Test "Set comp rate is removed" + GrantsComptroller + InitSpeeds + AllowFailures + Comptroller SetCompRate 5 + +Test "Comp is not claimed automatically" + GrantsComptroller + InitSpeeds + Comptroller SetCompSpeed cZRX 2 + FastForward 100000 Blocks + -- Check comp is not claimed automatically + Mint Geoff 50e18 cZRX + Assert Equal (Erc20 COMP TokenBalance Geoff) 0 + -- Confirm there was comp to claim + Comptroller ClaimComp Geoff + Assert Equal (Erc20 COMP TokenBalance Geoff) 200000 diff --git a/spec/scenario/Flywheel/Grants.scen b/spec/scenario/Flywheel/Grants.scen index d8c61b12e..951635ee4 100644 --- a/spec/scenario/Flywheel/Grants.scen +++ b/spec/scenario/Flywheel/Grants.scen @@ -34,6 +34,10 @@ Macro GrantsComptroller ComptrollerImpl Deploy ScenarioG5 ComptrollerScen Unitroller SetPendingImpl ComptrollerScen ComptrollerImpl ComptrollerScen BecomeG5 + -- g6 + ComptrollerImpl Deploy ScenarioG6 ComptrollerScen + Unitroller SetPendingImpl ComptrollerScen + ComptrollerImpl ComptrollerScen BecomeG6 -- current ComptrollerImpl Deploy Scenario ComptrollerScen Unitroller SetPendingImpl ComptrollerScen @@ -46,6 +50,8 @@ Macro InitSpeeds Mint Coburn 6e18 cBAT--tokenbalance = 6e18 / 2e9 = 3e9 EnterMarkets Coburn cBAT Borrow Coburn 1e18 cZRX + Comptroller SetCompSpeed cZRX 1 + Comptroller SetCompSpeed cBAT 1 Comptroller RefreshCompSpeeds Comptroller Send "setCompAddress(address)" (Address COMP) diff --git a/spec/sim/0006-setspeed-manual-claims/deploy.scen b/spec/sim/0006-setspeed-manual-claims/deploy.scen new file mode 100755 index 000000000..46518d956 --- /dev/null +++ b/spec/sim/0006-setspeed-manual-claims/deploy.scen @@ -0,0 +1,8 @@ +#!/usr/bin/env yarn repl -n mainnet -s + +PrintTransactionLogs + +-- Deploy the flywheel impl +ComptrollerImpl Deploy Standard StdComptrollerG7 + +Print "Deployed OK!" diff --git a/spec/sim/0006-setspeed-manual-claims/hypothetical_upgrade.scen b/spec/sim/0006-setspeed-manual-claims/hypothetical_upgrade.scen new file mode 100755 index 000000000..780ccee14 --- /dev/null +++ b/spec/sim/0006-setspeed-manual-claims/hypothetical_upgrade.scen @@ -0,0 +1,102 @@ +#!/usr/bin/env yarn repl -s + +-- This script tests a hypothetical upgrade with manual COMP claims and manual COMP speed setting + +PrintTransactionLogs +Alias CompHolder "0xC89b6f0146642688bb254bF93C28fcCF1E182C81" +Alias USDCWhale "0x3dfd23a6c5e8bbcfc9581d2e864a68feb6a076d3" +Alias DAIWhale "0x47ac0Fb4F2D84898e4D9E7b4DaB3C24507a6D503" +Web3Fork "https://mainnet-eth.compound.finance/@11458477" (CompHolder USDCWhale DAIWhale) +UseConfigs mainnet + +-- Deploy the flywheel impl +ComptrollerImpl Deploy Standard ComptrollerG7 + +-- Baseline USDC comp speed before the patch +Assert Equal (Comptroller CompSpeed cUSDC) 5.3786477206671197e16 + +-- Mint tokens +From DAIWhale (Trx GasPrice 0 (Erc20 DAI Approve cDAI UInt256Max)) +From DAIWhale (Trx GasPrice 0 (CToken cDAI Mint 10000e6)) +From USDCWhale (Trx GasPrice 0 (Erc20 USDC Approve cUSDC UInt256Max)) +From USDCWhale (Trx GasPrice 0 (CToken cUSDC Mint 10000e6)) + +-- Baseline COMP claim speed +Assert Equal (Comptroller CheckIsComped cDAI) True + +Comptroller ClaimComp DAIWhale +AdvanceBlocks 1000 +Expect Changes (Erc20 Comp TokenBalance DAIWhale) 7.77e2 +Comptroller ClaimComp DAIWhale + +-- Propose to apply the patch + +From CompHolder (Comp Delegate CompHolder) +From CompHolder (Governor GovernorAlpha Propose "Disable automatic comp speed refresh and automatic claims and change comp speed" [(Address Unitroller) (Address ComptrollerG7) (Address Unitroller)] [0 0 0] ["_setPendingImplementation(address)" "_become(address)" "_setCompSpeed(address,uint256)"] [[(Address ComptrollerG7)] [(Address Unitroller)] [(Address cUSDC) 30000000000000000]]) + +-- Vote for, queue, and execute the proposal + +MineBlock +From CompHolder (Governor GovernorAlpha Proposal LastProposal Vote For) +AdvanceBlocks 20000 +Governor GovernorAlpha Proposal LastProposal Queue +IncreaseTime 604910 +Governor GovernorAlpha Proposal LastProposal Execute +ComptrollerImpl ComptrollerG7 MergeABI + +-- Check that speed has changed +Assert Equal (Comptroller CompSpeed cUSDC) 3.0e16 + +-- Check that COMP is still accruing at the same speed +Comptroller ClaimComp DAIWhale +AdvanceBlocks 1000 +Expect Changes (Erc20 Comp TokenBalance DAIWhale) 7.77e2 +Comptroller ClaimComp DAIWhale + +-- Check that minting some USDC wont result in any automatic claims +AdvanceBlocks 1000000 +From USDCWhale (Trx GasPrice 0 (Erc20 USDC Approve cUSDC UInt256Max)) +Expect Changes (Erc20 Comp TokenBalance USDCWhale) 0 +From USDCWhale (Trx GasPrice 0 (CToken cUSDC Mint 10000e6)) + +-- Prepare second proposal +From CompHolder (Governor GovernorAlpha Propose "Remove USDC market by setting comp speed to 0" [(Address Unitroller)] [0] ["_setCompSpeed(address,uint256)"] [[(Address cUSDC) 0]]) + +-- Vote for, queue, and execute the second proposal + +MineBlock +From CompHolder (Governor GovernorAlpha Proposal LastProposal Vote For) +AdvanceBlocks 20000 +Governor GovernorAlpha Proposal LastProposal Queue +IncreaseTime 604910 +Governor GovernorAlpha Proposal LastProposal Execute + +AdvanceBlocks 1000 + +-- Check speed is now 0 +Assert Equal (Comptroller CompSpeed cUSDC) 0 + +-- True up balances +Comptroller ClaimComp USDCWhale + +-- Check no more comp accrued +AdvanceBlocks 1000000 +Expect Changes (Erc20 Comp TokenBalance USDCWhale) 0 +Comptroller ClaimComp USDCWhale + +-- Prepare final proposal +From CompHolder (Governor GovernorAlpha Propose "Reset USDC comp speed" [(Address Unitroller)] [0] ["_setCompSpeed(address,uint256)"] [[(Address cUSDC) 27000000000000000]]) + +-- Vote for, queue, and execute the final proposal + +MineBlock +From CompHolder (Governor GovernorAlpha Proposal LastProposal Vote For) +AdvanceBlocks 20000 +Governor GovernorAlpha Proposal LastProposal Queue +IncreaseTime 604910 +Governor GovernorAlpha Proposal LastProposal Execute + +-- Check new speed +Assert Equal (Comptroller CompSpeed cUSDC) 2.7e16 + +Print "Upgrade OK!" diff --git a/spec/sim/0006-setspeed-manual-claims/hypothetical_upgrade_borrower.scen b/spec/sim/0006-setspeed-manual-claims/hypothetical_upgrade_borrower.scen new file mode 100755 index 000000000..3dfa682b6 --- /dev/null +++ b/spec/sim/0006-setspeed-manual-claims/hypothetical_upgrade_borrower.scen @@ -0,0 +1,53 @@ +#!/usr/bin/env yarn repl -s + +-- This script tests a hypothetical upgrade with manual COMP claims and manual COMP speed setting + +PrintTransactionLogs +Alias CompHolder "0xC89b6f0146642688bb254bF93C28fcCF1E182C81" +Alias USDCWhale "0x3dfd23a6c5e8bbcfc9581d2e864a68feb6a076d3" +Alias DAIWhale "0x47ac0Fb4F2D84898e4D9E7b4DaB3C24507a6D503" +Alias BigBorrower "0x847956f7f7ff49714fb2d70a0d0cd44a6376990f" +Web3Fork "https://mainnet-eth.compound.finance/@11458477" (CompHolder USDCWhale DAIWhale) +UseConfigs mainnet + +-- Deploy the flywheel impl +ComptrollerImpl Deploy Standard ComptrollerG7 + +-- Baseline USDC comp speed before the patch +Assert Equal (Comptroller CompSpeed cUSDC) 5.3786477206671197e16 + +-- Mint tokens +From DAIWhale (Trx GasPrice 0 (Erc20 DAI Approve cDAI UInt256Max)) +From DAIWhale (Trx GasPrice 0 (CToken cDAI Mint 10000e6)) +From USDCWhale (Trx GasPrice 0 (Erc20 USDC Approve cUSDC UInt256Max)) +From USDCWhale (Trx GasPrice 0 (CToken cUSDC Mint 10000e6)) + +-- Baseline COMP claim speed +Assert Equal (Comptroller CheckIsComped cDAI) True + +Comptroller ClaimComp BigBorrower +AdvanceBlocks 1000 +Expect Changes (Erc20 Comp TokenBalance BigBorrower) 2.893496802261224189e18 +Comptroller ClaimComp BigBorrower + +-- Propose to apply the patch + +From CompHolder (Comp Delegate CompHolder) +From CompHolder (Governor GovernorAlpha Propose "Disable automatic comp speed refresh and automatic claims and change comp speed" [(Address Unitroller) (Address ComptrollerG7) (Address Unitroller)] [0 0 0] ["_setPendingImplementation(address)" "_become(address)" "_setCompSpeed(address,uint256)"] [[(Address ComptrollerG7)] [(Address Unitroller)] [(Address cUSDC) 30000000000000000]]) + +-- Vote for, queue, and execute the proposal + +MineBlock +From CompHolder (Governor GovernorAlpha Proposal LastProposal Vote For) +AdvanceBlocks 20000 +Governor GovernorAlpha Proposal LastProposal Queue +IncreaseTime 604910 +Governor GovernorAlpha Proposal LastProposal Execute +ComptrollerImpl ComptrollerG7 MergeABI + +Comptroller ClaimComp BigBorrower +AdvanceBlocks 1000 +Expect Changes (Erc20 Comp TokenBalance BigBorrower) 2.893496802261224189e18 +Comptroller ClaimComp BigBorrower + +Print "Upgrade OK!" diff --git a/spec/sim/0006-setspeed-manual-claims/hypothetical_upgrade_post_deploy.scen b/spec/sim/0006-setspeed-manual-claims/hypothetical_upgrade_post_deploy.scen new file mode 100755 index 000000000..f63b7a7a8 --- /dev/null +++ b/spec/sim/0006-setspeed-manual-claims/hypothetical_upgrade_post_deploy.scen @@ -0,0 +1,95 @@ +#!/usr/bin/env yarn repl -s + +-- This script tests a hypothetical upgrade with manual COMP claims and manual COMP speed setting + +PrintTransactionLogs +Alias CompHolder "0xC89b6f0146642688bb254bF93C28fcCF1E182C81" +Alias USDCWhale "0x3dfd23a6c5e8bbcfc9581d2e864a68feb6a076d3" +Alias DAIWhale "0x47ac0Fb4F2D84898e4D9E7b4DaB3C24507a6D503" +Alias NewComptroller "0xbe7616B06f71e363A310Aa8CE8aD99654401ead7" +Web3Fork "https://mainnet-eth.compound.finance/@11499182" (CompHolder USDCWhale DAIWhale) +UseConfigs mainnet + +-- Mint tokens +From DAIWhale (Trx GasPrice 0 (Erc20 DAI Approve cDAI UInt256Max)) +From DAIWhale (Trx GasPrice 0 (CToken cDAI Mint 10000e6)) +From USDCWhale (Trx GasPrice 0 (Erc20 USDC Approve cUSDC UInt256Max)) +From USDCWhale (Trx GasPrice 0 (CToken cUSDC Mint 10000e6)) + +-- Baseline COMP claim speed +Assert Equal (Comptroller CheckIsComped cDAI) True + +Comptroller ClaimComp DAIWhale +AdvanceBlocks 1000 +Comptroller ClaimComp DAIWhale + +-- Propose to apply the patch + +From CompHolder (Comp Delegate CompHolder) +From CompHolder (Governor GovernorAlpha Propose "Disable automatic comp speed refresh and automatic claims and change comp speed" [(Address Unitroller) (Address NewComptroller) (Address Unitroller)] [0 0 0] ["_setPendingImplementation(address)" "_become(address)" "_setCompSpeed(address,uint256)"] [[(Address NewComptroller)] [(Address Unitroller)] [(Address cUSDC) 30000000000000000]]) + +-- Vote for, queue, and execute the proposal + +MineBlock +From CompHolder (Governor GovernorAlpha Proposal LastProposal Vote For) +AdvanceBlocks 20000 +Governor GovernorAlpha Proposal LastProposal Queue +IncreaseTime 604910 +Governor GovernorAlpha Proposal LastProposal Execute +ComptrollerImpl ComptrollerG7 MergeABI + +-- Check that speed has changed +Assert Equal (Comptroller CompSpeed cUSDC) 3.0e16 + +-- Check that COMP is still accruing at the same speed +Comptroller ClaimComp DAIWhale +AdvanceBlocks 1000 +Comptroller ClaimComp DAIWhale + +-- Check that minting some USDC wont result in any automatic claims +AdvanceBlocks 1000000 +From USDCWhale (Trx GasPrice 0 (Erc20 USDC Approve cUSDC UInt256Max)) +Expect Changes (Erc20 Comp TokenBalance USDCWhale) 0 +From USDCWhale (Trx GasPrice 0 (CToken cUSDC Mint 10000e6)) + +-- Prepare second proposal +From CompHolder (Governor GovernorAlpha Propose "Remove USDC market by setting comp speed to 0" [(Address Unitroller)] [0] ["_setCompSpeed(address,uint256)"] [[(Address cUSDC) 0]]) + +-- Vote for, queue, and execute the second proposal + +MineBlock +From CompHolder (Governor GovernorAlpha Proposal LastProposal Vote For) +AdvanceBlocks 20000 +Governor GovernorAlpha Proposal LastProposal Queue +IncreaseTime 604910 +Governor GovernorAlpha Proposal LastProposal Execute + +AdvanceBlocks 1000 + +-- Check speed is now 0 +Assert Equal (Comptroller CompSpeed cUSDC) 0 + +-- True up balances +Comptroller ClaimComp USDCWhale + +-- Check no more comp accrued +AdvanceBlocks 1000000 +Expect Changes (Erc20 Comp TokenBalance USDCWhale) 0 +Comptroller ClaimComp USDCWhale + +-- Prepare final proposal +From CompHolder (Governor GovernorAlpha Propose "Reset USDC comp speed" [(Address Unitroller)] [0] ["_setCompSpeed(address,uint256)"] [[(Address cUSDC) 27000000000000000]]) + +-- Vote for, queue, and execute the final proposal + +MineBlock +From CompHolder (Governor GovernorAlpha Proposal LastProposal Vote For) +AdvanceBlocks 20000 +Governor GovernorAlpha Proposal LastProposal Queue +IncreaseTime 604910 +Governor GovernorAlpha Proposal LastProposal Execute + +-- Check new speed +Assert Equal (Comptroller CompSpeed cUSDC) 2.7e16 + +Print "Upgrade OK!" diff --git a/spec/sim/0006-setspeed-manual-claims/hypothetical_upgrade_post_propose.scen b/spec/sim/0006-setspeed-manual-claims/hypothetical_upgrade_post_propose.scen new file mode 100755 index 000000000..49b33c92a --- /dev/null +++ b/spec/sim/0006-setspeed-manual-claims/hypothetical_upgrade_post_propose.scen @@ -0,0 +1,86 @@ +#!/usr/bin/env yarn repl -s + +-- This script tests a hypothetical upgrade with manual COMP claims and manual COMP speed setting + +PrintTransactionLogs +Alias CompHolder1 "0xC89b6f0146642688bb254bF93C28fcCF1E182C81" +Alias CompHolder2 "0xed409c9ff60f3020abf9012bcd45fc294f5608ff" +Alias CompHolder3 "0x6626593c237f530d15ae9980a95ef938ac15c35c" +Alias USDCWhale "0x3dfd23a6c5e8bbcfc9581d2e864a68feb6a076d3" +Alias DAIWhale "0x47ac0Fb4F2D84898e4D9E7b4DaB3C24507a6D503" +Alias NewComptroller "0xbe7616B06f71e363A310Aa8CE8aD99654401ead7" +Web3Fork "https://mainnet-eth.compound.finance/@11499432" (CompHolder1 CompHolder2 CompHolder3 USDCWhale DAIWhale) +UseConfigs mainnet + +-- Baseline the speed +Assert Equal (Comptroller CompSpeed cUSDC) 6.5604507401004006e16 + +MineBlock +From CompHolder1 (Governor GovernorAlpha Proposal LastProposal Vote For) +From CompHolder2 (Governor GovernorAlpha Proposal LastProposal Vote For) +From CompHolder3 (Governor GovernorAlpha Proposal LastProposal Vote For) +AdvanceBlocks 20000 +Governor GovernorAlpha Proposal LastProposal Queue +IncreaseTime 604910 +Governor GovernorAlpha Proposal LastProposal Execute +ComptrollerImpl ComptrollerG7 MergeABI + +-- Check that speed has not changed +Assert Equal (Comptroller CompSpeed cUSDC) 6.5604507401004006e16 + +-- Check that COMP is still accruing at the same speed +Comptroller ClaimComp DAIWhale +AdvanceBlocks 1000 +Comptroller ClaimComp DAIWhale + +-- Check that minting some USDC wont result in any automatic claims +AdvanceBlocks 1000000 +From USDCWhale (Trx GasPrice 0 (Erc20 USDC Approve cUSDC UInt256Max)) +Expect Changes (Erc20 Comp TokenBalance USDCWhale) 0 +From USDCWhale (Trx GasPrice 0 (CToken cUSDC Mint 10000e6)) + +-- Prepare second proposal +From CompHolder3 (Governor GovernorAlpha Propose "Remove USDC market by setting comp speed to 0" [(Address Unitroller)] [0] ["_setCompSpeed(address,uint256)"] [[(Address cUSDC) 0]]) + +-- Vote for, queue, and execute the second proposal + +MineBlock +From CompHolder1 (Governor GovernorAlpha Proposal LastProposal Vote For) +From CompHolder2 (Governor GovernorAlpha Proposal LastProposal Vote For) +From CompHolder3 (Governor GovernorAlpha Proposal LastProposal Vote For) +AdvanceBlocks 20000 +Governor GovernorAlpha Proposal LastProposal Queue +IncreaseTime 604910 +Governor GovernorAlpha Proposal LastProposal Execute + +AdvanceBlocks 1000 + +-- Check speed is now 0 +Assert Equal (Comptroller CompSpeed cUSDC) 0 + +-- True up balances +Comptroller ClaimComp USDCWhale + +-- Check no more comp accrued +AdvanceBlocks 1000000 +Expect Changes (Erc20 Comp TokenBalance USDCWhale) 0 +Comptroller ClaimComp USDCWhale + +-- Prepare final proposal +From CompHolder3 (Governor GovernorAlpha Propose "Reset USDC comp speed" [(Address Unitroller)] [0] ["_setCompSpeed(address,uint256)"] [[(Address cUSDC) 27000000000000000]]) + +-- Vote for, queue, and execute the final proposal + +MineBlock +From CompHolder1 (Governor GovernorAlpha Proposal LastProposal Vote For) +From CompHolder2 (Governor GovernorAlpha Proposal LastProposal Vote For) +From CompHolder3 (Governor GovernorAlpha Proposal LastProposal Vote For) +AdvanceBlocks 20000 +Governor GovernorAlpha Proposal LastProposal Queue +IncreaseTime 604910 +Governor GovernorAlpha Proposal LastProposal Execute + +-- Check new speed +Assert Equal (Comptroller CompSpeed cUSDC) 2.7e16 + +Print "Upgrade OK!" diff --git a/tests/Contracts/ComptrollerHarness.sol b/tests/Contracts/ComptrollerHarness.sol index 7e5812c0c..1f7e79d9c 100644 --- a/tests/Contracts/ComptrollerHarness.sol +++ b/tests/Contracts/ComptrollerHarness.sol @@ -47,8 +47,44 @@ contract ComptrollerHarness is Comptroller { return compAddress; } - function setCompSpeed(address cToken, uint compSpeed) public { - compSpeeds[cToken] = compSpeed; + /** + * @notice Set the amount of COMP distributed per block + * @param compRate_ The amount of COMP wei per block to distribute + */ + function harnessSetCompRate(uint compRate_) public { + compRate = compRate_; + } + + /** + * @notice Recalculate and update COMP speeds for all COMP markets + */ + function harnessRefreshCompSpeeds() public { + CToken[] memory allMarkets_ = allMarkets; + + for (uint i = 0; i < allMarkets_.length; i++) { + CToken cToken = allMarkets_[i]; + Exp memory borrowIndex = Exp({mantissa: cToken.borrowIndex()}); + updateCompSupplyIndex(address(cToken)); + updateCompBorrowIndex(address(cToken), borrowIndex); + } + + Exp memory totalUtility = Exp({mantissa: 0}); + Exp[] memory utilities = new Exp[](allMarkets_.length); + for (uint i = 0; i < allMarkets_.length; i++) { + CToken cToken = allMarkets_[i]; + if (compSpeeds[address(cToken)] > 0) { + Exp memory assetPrice = Exp({mantissa: oracle.getUnderlyingPrice(cToken)}); + Exp memory utility = mul_(assetPrice, cToken.totalBorrows()); + utilities[i] = utility; + totalUtility = add_(totalUtility, utility); + } + } + + for (uint i = 0; i < allMarkets_.length; i++) { + CToken cToken = allMarkets[i]; + uint newSpeed = totalUtility.mantissa > 0 ? mul_(compRate, div_(utilities[i], totalUtility)) : 0; + setCompSpeedInternal(cToken, newSpeed); + } } function setCompBorrowerIndex(address cToken, address borrower, uint index) public { @@ -59,6 +95,16 @@ contract ComptrollerHarness is Comptroller { compSupplierIndex[cToken][supplier] = index; } + function harnessDistributeAllBorrowerComp(address cToken, address borrower, uint marketBorrowIndexMantissa) public { + distributeBorrowerComp(cToken, borrower, Exp({mantissa: marketBorrowIndexMantissa})); + compAccrued[borrower] = grantCompInternal(borrower, compAccrued[borrower]); + } + + function harnessDistributeAllSupplierComp(address cToken, address supplier) public { + distributeSupplierComp(cToken, supplier); + compAccrued[supplier] = grantCompInternal(supplier, compAccrued[supplier]); + } + function harnessUpdateCompBorrowIndex(address cToken, uint marketBorrowIndexMantissa) public { updateCompBorrowIndex(cToken, Exp({mantissa: marketBorrowIndexMantissa})); } @@ -68,15 +114,25 @@ contract ComptrollerHarness is Comptroller { } function harnessDistributeBorrowerComp(address cToken, address borrower, uint marketBorrowIndexMantissa) public { - distributeBorrowerComp(cToken, borrower, Exp({mantissa: marketBorrowIndexMantissa}), false); + distributeBorrowerComp(cToken, borrower, Exp({mantissa: marketBorrowIndexMantissa})); } function harnessDistributeSupplierComp(address cToken, address supplier) public { - distributeSupplierComp(cToken, supplier, false); + distributeSupplierComp(cToken, supplier); } function harnessTransferComp(address user, uint userAccrued, uint threshold) public returns (uint) { - return transferComp(user, userAccrued, threshold); + if (userAccrued > 0 && userAccrued >= threshold) { + return grantCompInternal(user, userAccrued); + } + return userAccrued; + } + + function harnessAddCompMarkets(address[] memory cTokens) public { + for (uint i = 0; i < cTokens.length; i++) { + // temporarily set compSpeed to 1 (will be fixed by `harnessRefreshCompSpeeds`) + setCompSpeedInternal(CToken(cTokens[i]), 1); + } } function harnessFastForward(uint blocks) public returns (uint) { @@ -96,7 +152,7 @@ contract ComptrollerHarness is Comptroller { uint m = allMarkets.length; uint n = 0; for (uint i = 0; i < m; i++) { - if (markets[address(allMarkets[i])].isComped) { + if (compSpeeds[address(allMarkets[i])] > 0) { n++; } } @@ -104,7 +160,7 @@ contract ComptrollerHarness is Comptroller { address[] memory compMarkets = new address[](n); uint k = 0; for (uint i = 0; i < m; i++) { - if (markets[address(allMarkets[i])].isComped) { + if (compSpeeds[address(allMarkets[i])] > 0) { compMarkets[k++] = address(allMarkets[i]); } } diff --git a/tests/Contracts/ComptrollerScenario.sol b/tests/Contracts/ComptrollerScenario.sol index 779ec6119..866ac3526 100644 --- a/tests/Contracts/ComptrollerScenario.sol +++ b/tests/Contracts/ComptrollerScenario.sol @@ -36,4 +36,36 @@ contract ComptrollerScenario is Comptroller { function unlist(CToken cToken) public { markets[address(cToken)].isListed = false; } + + /** + * @notice Recalculate and update COMP speeds for all COMP markets + */ + function refreshCompSpeeds() public { + CToken[] memory allMarkets_ = allMarkets; + + for (uint i = 0; i < allMarkets_.length; i++) { + CToken cToken = allMarkets_[i]; + Exp memory borrowIndex = Exp({mantissa: cToken.borrowIndex()}); + updateCompSupplyIndex(address(cToken)); + updateCompBorrowIndex(address(cToken), borrowIndex); + } + + Exp memory totalUtility = Exp({mantissa: 0}); + Exp[] memory utilities = new Exp[](allMarkets_.length); + for (uint i = 0; i < allMarkets_.length; i++) { + CToken cToken = allMarkets_[i]; + if (compSpeeds[address(cToken)] > 0) { + Exp memory assetPrice = Exp({mantissa: oracle.getUnderlyingPrice(cToken)}); + Exp memory utility = mul_(assetPrice, cToken.totalBorrows()); + utilities[i] = utility; + totalUtility = add_(totalUtility, utility); + } + } + + for (uint i = 0; i < allMarkets_.length; i++) { + CToken cToken = allMarkets[i]; + uint newSpeed = totalUtility.mantissa > 0 ? mul_(compRate, div_(utilities[i], totalUtility)) : 0; + setCompSpeedInternal(cToken, newSpeed); + } + } } diff --git a/tests/Contracts/ComptrollerScenarioG6.sol b/tests/Contracts/ComptrollerScenarioG6.sol new file mode 100644 index 000000000..d1cc6fe8f --- /dev/null +++ b/tests/Contracts/ComptrollerScenarioG6.sol @@ -0,0 +1,43 @@ +pragma solidity ^0.5.16; + +import "../../contracts/ComptrollerG6.sol"; + +contract ComptrollerScenarioG6 is ComptrollerG6 { + uint public blockNumber; + address public compAddress; + + constructor() ComptrollerG6() public {} + + function fastForward(uint blocks) public returns (uint) { + blockNumber += blocks; + return blockNumber; + } + + function setCompAddress(address compAddress_) public { + compAddress = compAddress_; + } + + function getCompAddress() public view returns (address) { + return compAddress; + } + + function setBlockNumber(uint number) public { + blockNumber = number; + } + + function getBlockNumber() public view returns (uint) { + return blockNumber; + } + + function membershipLength(CToken cToken) public view returns (uint) { + return accountAssets[address(cToken)].length; + } + + function unlist(CToken cToken) public { + markets[address(cToken)].isListed = false; + } + + function setCompSpeed(address cToken, uint compSpeed) public { + compSpeeds[cToken] = compSpeed; + } +} diff --git a/tests/Contracts/RefreshSpeedsProxy.sol b/tests/Contracts/RefreshSpeedsProxy.sol deleted file mode 100644 index 6b6438545..000000000 --- a/tests/Contracts/RefreshSpeedsProxy.sol +++ /dev/null @@ -1,11 +0,0 @@ -pragma solidity ^0.5.16; - -interface IComptroller { - function refreshCompSpeeds() external; -} - -contract RefreshSpeedsProxy { - constructor(address comptroller) public { - IComptroller(comptroller).refreshCompSpeeds(); - } -} diff --git a/tests/Flywheel/FlywheelTest.js b/tests/Flywheel/FlywheelTest.js index 5e30438f0..d53258c40 100644 --- a/tests/Flywheel/FlywheelTest.js +++ b/tests/Flywheel/FlywheelTest.js @@ -87,7 +87,6 @@ describe('Flywheel', () => { cREP = await makeCToken({comptroller, supportMarket: true, underlyingPrice: 2, interestRateModelOpts}); cZRX = await makeCToken({comptroller, supportMarket: true, underlyingPrice: 3, interestRateModelOpts}); cEVIL = await makeCToken({comptroller, supportMarket: false, underlyingPrice: 3, interestRateModelOpts}); - await send(comptroller, '_addCompMarkets', [[cLOW, cREP, cZRX].map(c => c._address)]); }); describe('_grantComp()', () => { @@ -118,18 +117,80 @@ describe('Flywheel', () => { describe('getCompMarkets()', () => { it('should return the comp markets', async () => { + for (let mkt of [cLOW, cREP, cZRX]) { + await send(comptroller, '_setCompSpeed', [mkt._address, etherExp(0.5)]); + } expect(await call(comptroller, 'getCompMarkets')).toEqual( [cLOW, cREP, cZRX].map((c) => c._address) ); }); }); + describe('_setCompSpeed()', () => { + it('should update market index when calling setCompSpeed', async () => { + const mkt = cREP; + await send(comptroller, 'setBlockNumber', [0]); + await send(mkt, 'harnessSetTotalSupply', [etherUnsigned(10e18)]); + + await send(comptroller, '_setCompSpeed', [mkt._address, etherExp(0.5)]); + await fastForward(comptroller, 20); + await send(comptroller, '_setCompSpeed', [mkt._address, etherExp(1)]); + + const {index, block} = await call(comptroller, 'compSupplyState', [mkt._address]); + expect(index).toEqualNumber(2e36); + expect(block).toEqualNumber(20); + }); + + it('should correctly drop a comp market if called by admin', async () => { + for (let mkt of [cLOW, cREP, cZRX]) { + await send(comptroller, '_setCompSpeed', [mkt._address, etherExp(0.5)]); + } + const tx = await send(comptroller, '_setCompSpeed', [cLOW._address, 0]); + expect(await call(comptroller, 'getCompMarkets')).toEqual( + [cREP, cZRX].map((c) => c._address) + ); + expect(tx).toHaveLog('CompSpeedUpdated', { + cToken: cLOW._address, + newSpeed: 0 + }); + }); + + it('should correctly drop a comp market from middle of array', async () => { + for (let mkt of [cLOW, cREP, cZRX]) { + await send(comptroller, '_setCompSpeed', [mkt._address, etherExp(0.5)]); + } + await send(comptroller, '_setCompSpeed', [cREP._address, 0]); + expect(await call(comptroller, 'getCompMarkets')).toEqual( + [cLOW, cZRX].map((c) => c._address) + ); + }); + + it('should not drop a comp market unless called by admin', async () => { + for (let mkt of [cLOW, cREP, cZRX]) { + await send(comptroller, '_setCompSpeed', [mkt._address, etherExp(0.5)]); + } + await expect( + send(comptroller, '_setCompSpeed', [cLOW._address, 0], {from: a1}) + ).rejects.toRevert('revert only admin can set comp speed'); + }); + + it('should not add non-listed markets', async () => { + const cBAT = await makeCToken({ comptroller, supportMarket: false }); + await expect( + send(comptroller, 'harnessAddCompMarkets', [[cBAT._address]]) + ).rejects.toRevert('revert comp market is not listed'); + + const markets = await call(comptroller, 'getCompMarkets'); + expect(markets).toEqual([]); + }); + }); + describe('updateCompBorrowIndex()', () => { it('should calculate comp borrower index correctly', async () => { const mkt = cREP; + await send(comptroller, '_setCompSpeed', [mkt._address, etherExp(0.5)]); await send(comptroller, 'setBlockNumber', [100]); await send(mkt, 'harnessSetTotalBorrows', [etherUnsigned(11e18)]); - await send(comptroller, 'setCompSpeed', [mkt._address, etherExp(0.5)]); await send(comptroller, 'harnessUpdateCompBorrowIndex', [ mkt._address, etherExp(1.1), @@ -171,7 +232,7 @@ describe('Flywheel', () => { it('should not update index if no blocks passed since last accrual', async () => { const mkt = cREP; - await send(comptroller, 'setCompSpeed', [mkt._address, etherExp(0.5)]); + await send(comptroller, '_setCompSpeed', [mkt._address, etherExp(0.5)]); await send(comptroller, 'harnessUpdateCompBorrowIndex', [ mkt._address, etherExp(1.1), @@ -184,8 +245,9 @@ describe('Flywheel', () => { it('should not update index if comp speed is 0', async () => { const mkt = cREP; - await send(comptroller, 'setCompSpeed', [mkt._address, etherExp(0)]); + await send(comptroller, '_setCompSpeed', [mkt._address, etherExp(0.5)]); await send(comptroller, 'setBlockNumber', [100]); + await send(comptroller, '_setCompSpeed', [mkt._address, etherExp(0)]); await send(comptroller, 'harnessUpdateCompBorrowIndex', [ mkt._address, etherExp(1.1), @@ -200,9 +262,9 @@ describe('Flywheel', () => { describe('updateCompSupplyIndex()', () => { it('should calculate comp supplier index correctly', async () => { const mkt = cREP; + await send(comptroller, '_setCompSpeed', [mkt._address, etherExp(0.5)]); await send(comptroller, 'setBlockNumber', [100]); await send(mkt, 'harnessSetTotalSupply', [etherUnsigned(10e18)]); - await send(comptroller, 'setCompSpeed', [mkt._address, etherExp(0.5)]); await send(comptroller, 'harnessUpdateCompSupplyIndex', [mkt._address]); /* suppyTokens = 10e18 @@ -240,7 +302,7 @@ describe('Flywheel', () => { const mkt = cREP; await send(comptroller, 'setBlockNumber', [0]); await send(mkt, 'harnessSetTotalSupply', [etherUnsigned(10e18)]); - await send(comptroller, 'setCompSpeed', [mkt._address, etherExp(0.5)]); + await send(comptroller, '_setCompSpeed', [mkt._address, etherExp(0.5)]); await send(comptroller, 'harnessUpdateCompSupplyIndex', [mkt._address]); const {index, block} = await call(comptroller, 'compSupplyState', [mkt._address]); @@ -250,9 +312,10 @@ describe('Flywheel', () => { it('should not matter if the index is updated multiple times', async () => { const compRemaining = compRate.multipliedBy(100) + await send(comptroller, 'harnessAddCompMarkets', [[cLOW._address]]); await send(comptroller.comp, 'transfer', [comptroller._address, compRemaining], {from: root}); await pretendBorrow(cLOW, a1, 1, 1, 100); - await send(comptroller, 'refreshCompSpeeds'); + await send(comptroller, 'harnessRefreshCompSpeeds'); await quickMint(cLOW, a2, etherUnsigned(10e18)); await quickMint(cLOW, a3, etherUnsigned(15e18)); @@ -289,8 +352,8 @@ describe('Flywheel', () => { expect(txT1.gasUsed).toBeLessThan(200000); expect(txT1.gasUsed).toBeGreaterThan(150000); - expect(txT2.gasUsed).toBeLessThan(200000); - expect(txT2.gasUsed).toBeGreaterThan(150000); + expect(txT2.gasUsed).toBeLessThan(150000); + expect(txT2.gasUsed).toBeGreaterThan(100000); }); }); @@ -324,8 +387,8 @@ describe('Flywheel', () => { = 5e18 * 5e36 / 1e36 = 25e18 */ const tx = await send(comptroller, "harnessDistributeBorrowerComp", [mkt._address, a1, etherUnsigned(1.1e18)]); - expect(await compAccrued(comptroller, a1)).toEqualNumber(0); - expect(await compBalance(comptroller, a1)).toEqualNumber(25e18); + expect(await compAccrued(comptroller, a1)).toEqualNumber(25e18); + expect(await compBalance(comptroller, a1)).toEqualNumber(0); expect(tx).toHaveLog('DistributedBorrowerComp', { cToken: mkt._address, borrower: a1, @@ -334,7 +397,7 @@ describe('Flywheel', () => { }); }); - it('should not transfer if below comp claim threshold', async () => { + it('should not transfer comp automatically', async () => { const mkt = cREP; await send(comptroller.comp, 'transfer', [comptroller._address, etherUnsigned(50e18)], {from: root}); await send(mkt, "harnessSetAccountBorrows", [a1, etherUnsigned(5.5e17), etherExp(1)]); @@ -385,7 +448,7 @@ describe('Flywheel', () => { = 5e18 * 5e36 / 1e36 = 25e18 */ - const tx = await send(comptroller, "harnessDistributeSupplierComp", [mkt._address, a1]); + const tx = await send(comptroller, "harnessDistributeAllSupplierComp", [mkt._address, a1]); expect(await compAccrued(comptroller, a1)).toEqualNumber(0); expect(await compBalance(comptroller, a1)).toEqualNumber(25e18); expect(tx).toHaveLog('DistributedSupplierComp', { @@ -411,7 +474,7 @@ describe('Flywheel', () => { = 5e18 * 4e36 / 1e36 = 20e18 */ - await send(comptroller, "harnessDistributeSupplierComp", [mkt._address, a1]); + await send(comptroller, "harnessDistributeAllSupplierComp", [mkt._address, a1]); expect(await compAccrued(comptroller, a1)).toEqualNumber(0); expect(await compBalance(comptroller, a1)).toEqualNumber(20e18); }); @@ -493,7 +556,8 @@ describe('Flywheel', () => { const compRemaining = compRate.multipliedBy(100), mintAmount = etherUnsigned(12e18), deltaBlocks = 10; await send(comptroller.comp, 'transfer', [comptroller._address, compRemaining], {from: root}); await pretendBorrow(cLOW, a1, 1, 1, 100); - await send(comptroller, 'refreshCompSpeeds'); + await send(comptroller, '_setCompSpeed', [cLOW._address, etherExp(0.5)]); + await send(comptroller, 'harnessRefreshCompSpeeds'); const speed = await call(comptroller, 'compSpeeds', [cLOW._address]); const a2AccruedPre = await compAccrued(comptroller, a2); const compBalancePre = await compBalance(comptroller, a2); @@ -502,7 +566,7 @@ describe('Flywheel', () => { const tx = await send(comptroller, 'claimComp', [a2]); const a2AccruedPost = await compAccrued(comptroller, a2); const compBalancePost = await compBalance(comptroller, a2); - expect(tx.gasUsed).toBeLessThan(330000); + expect(tx.gasUsed).toBeLessThan(400000); expect(speed).toEqualNumber(compRate); expect(a2AccruedPre).toEqualNumber(0); expect(a2AccruedPost).toEqualNumber(0); @@ -514,7 +578,8 @@ describe('Flywheel', () => { const compRemaining = compRate.multipliedBy(100), mintAmount = etherUnsigned(12e18), deltaBlocks = 10; await send(comptroller.comp, 'transfer', [comptroller._address, compRemaining], {from: root}); await pretendBorrow(cLOW, a1, 1, 1, 100); - await send(comptroller, 'refreshCompSpeeds'); + await send(comptroller, 'harnessAddCompMarkets', [[cLOW._address]]); + await send(comptroller, 'harnessRefreshCompSpeeds'); const speed = await call(comptroller, 'compSpeeds', [cLOW._address]); const a2AccruedPre = await compAccrued(comptroller, a2); const compBalancePre = await compBalance(comptroller, a2); @@ -523,7 +588,7 @@ describe('Flywheel', () => { const tx = await send(comptroller, 'claimComp', [a2, [cLOW._address]]); const a2AccruedPost = await compAccrued(comptroller, a2); const compBalancePost = await compBalance(comptroller, a2); - expect(tx.gasUsed).toBeLessThan(160000); + expect(tx.gasUsed).toBeLessThan(170000); expect(speed).toEqualNumber(compRate); expect(a2AccruedPre).toEqualNumber(0); expect(a2AccruedPost).toEqualNumber(0); @@ -561,14 +626,13 @@ describe('Flywheel', () => { } await pretendBorrow(cLOW, root, 1, 1, etherExp(10)); - await send(comptroller, 'refreshCompSpeeds'); + await send(comptroller, 'harnessRefreshCompSpeeds'); await fastForward(comptroller, deltaBlocks); await expect(send(comptroller, 'claimComp', [claimAccts, [cLOW._address, cEVIL._address], true, true])).rejects.toRevert('revert market must be listed'); }); - it('should claim the expected amount when holders and ctokens arg is duplicated', async () => { const compRemaining = compRate.multipliedBy(100), deltaBlocks = 10, mintAmount = etherExp(10); await send(comptroller.comp, 'transfer', [comptroller._address, compRemaining], {from: root}); @@ -579,7 +643,8 @@ describe('Flywheel', () => { send(cLOW, 'mint', [mintAmount], { from }); } await pretendBorrow(cLOW, root, 1, 1, etherExp(10)); - await send(comptroller, 'refreshCompSpeeds'); + await send(comptroller, 'harnessAddCompMarkets', [[cLOW._address]]); + await send(comptroller, 'harnessRefreshCompSpeeds'); await fastForward(comptroller, deltaBlocks); @@ -601,7 +666,8 @@ describe('Flywheel', () => { send(cLOW, 'mint', [mintAmount], { from }); } await pretendBorrow(cLOW, root, 1, 1, etherExp(10)); - await send(comptroller, 'refreshCompSpeeds'); + await send(comptroller, 'harnessAddCompMarkets', [[cLOW._address]]); + await send(comptroller, 'harnessRefreshCompSpeeds'); await fastForward(comptroller, deltaBlocks); @@ -622,7 +688,8 @@ describe('Flywheel', () => { await send(cLOW, 'harnessIncrementTotalBorrows', [borrowAmt]); await send(cLOW, 'harnessSetAccountBorrows', [acct, borrowAmt, borrowIdx]); } - await send(comptroller, 'refreshCompSpeeds'); + await send(comptroller, 'harnessAddCompMarkets', [[cLOW._address]]); + await send(comptroller, 'harnessRefreshCompSpeeds'); await send(comptroller, 'harnessFastForward', [10]); @@ -641,36 +708,30 @@ describe('Flywheel', () => { }); }); - describe('refreshCompSpeeds', () => { + describe('harnessRefreshCompSpeeds', () => { it('should start out 0', async () => { - await send(comptroller, 'refreshCompSpeeds'); + await send(comptroller, 'harnessRefreshCompSpeeds'); const speed = await call(comptroller, 'compSpeeds', [cLOW._address]); expect(speed).toEqualNumber(0); }); it('should get correct speeds with borrows', async () => { await pretendBorrow(cLOW, a1, 1, 1, 100); - const tx = await send(comptroller, 'refreshCompSpeeds'); + await send(comptroller, 'harnessAddCompMarkets', [[cLOW._address]]); + const tx = await send(comptroller, 'harnessRefreshCompSpeeds'); const speed = await call(comptroller, 'compSpeeds', [cLOW._address]); expect(speed).toEqualNumber(compRate); expect(tx).toHaveLog(['CompSpeedUpdated', 0], { cToken: cLOW._address, newSpeed: speed }); - expect(tx).toHaveLog(['CompSpeedUpdated', 1], { - cToken: cREP._address, - newSpeed: 0 - }); - expect(tx).toHaveLog(['CompSpeedUpdated', 2], { - cToken: cZRX._address, - newSpeed: 0 - }); }); it('should get correct speeds for 2 assets', async () => { await pretendBorrow(cLOW, a1, 1, 1, 100); await pretendBorrow(cZRX, a1, 1, 1, 100); - await send(comptroller, 'refreshCompSpeeds'); + await send(comptroller, 'harnessAddCompMarkets', [[cLOW._address, cZRX._address]]); + await send(comptroller, 'harnessRefreshCompSpeeds'); const speed1 = await call(comptroller, 'compSpeeds', [cLOW._address]); const speed2 = await call(comptroller, 'compSpeeds', [cREP._address]); const speed3 = await call(comptroller, 'compSpeeds', [cZRX._address]); @@ -678,62 +739,32 @@ describe('Flywheel', () => { expect(speed2).toEqualNumber(0); expect(speed3).toEqualNumber(compRate.dividedBy(4).multipliedBy(3)); }); - - it('should not be callable inside a contract', async () => { - await pretendBorrow(cLOW, a1, 1, 1, 100); - await pretendBorrow(cZRX, a1, 1, 1, 100); - await expect(deploy('RefreshSpeedsProxy', [comptroller._address])).rejects.toRevert('revert only externally owned accounts may refresh speeds'); - }); }); - describe('_addCompMarkets', () => { + describe('harnessAddCompMarkets', () => { it('should correctly add a comp market if called by admin', async () => { const cBAT = await makeCToken({comptroller, supportMarket: true}); - const tx = await send(comptroller, '_addCompMarkets', [[cBAT._address]]); + const tx1 = await send(comptroller, 'harnessAddCompMarkets', [[cLOW._address, cREP._address, cZRX._address]]); + const tx2 = await send(comptroller, 'harnessAddCompMarkets', [[cBAT._address]]); const markets = await call(comptroller, 'getCompMarkets'); expect(markets).toEqual([cLOW, cREP, cZRX, cBAT].map((c) => c._address)); - expect(tx).toHaveLog('MarketComped', { + expect(tx2).toHaveLog('CompSpeedUpdated', { cToken: cBAT._address, - isComped: true + newSpeed: 1 }); }); - it('should revert if not called by admin', async () => { - const cBAT = await makeCToken({ comptroller, supportMarket: true }); - await expect( - send(comptroller, '_addCompMarkets', [[cBAT._address]], {from: a1}) - ).rejects.toRevert('revert only admin can add comp market'); - }); - - it('should not add non-listed markets', async () => { - const cBAT = await makeCToken({ comptroller, supportMarket: false }); - await expect( - send(comptroller, '_addCompMarkets', [[cBAT._address]]) - ).rejects.toRevert('revert comp market is not listed'); - - const markets = await call(comptroller, 'getCompMarkets'); - expect(markets).toEqual([cLOW, cREP, cZRX].map((c) => c._address)); - }); - - it('should not add duplicate markets', async () => { - const cBAT = await makeCToken({comptroller, supportMarket: true}); - await send(comptroller, '_addCompMarkets', [[cBAT._address]]); - - await expect( - send(comptroller, '_addCompMarkets', [[cBAT._address]]) - ).rejects.toRevert('revert comp market already added'); - }); - it('should not write over a markets existing state', async () => { const mkt = cLOW._address; const bn0 = 10, bn1 = 20; const idx = etherUnsigned(1.5e36); + await send(comptroller, "harnessAddCompMarkets", [[mkt]]); await send(comptroller, "setCompSupplyState", [mkt, idx, bn0]); await send(comptroller, "setCompBorrowState", [mkt, idx, bn0]); await send(comptroller, "setBlockNumber", [bn1]); - await send(comptroller, "_dropCompMarket", [mkt]); - await send(comptroller, "_addCompMarkets", [[mkt]]); + await send(comptroller, "_setCompSpeed", [mkt, 0]); + await send(comptroller, "harnessAddCompMarkets", [[mkt]]); const supplyState = await call(comptroller, 'compSupplyState', [mkt]); expect(supplyState.block).toEqual(bn1.toString()); @@ -745,58 +776,6 @@ describe('Flywheel', () => { }); }); - describe('_dropCompMarket', () => { - it('should correctly drop a comp market if called by admin', async () => { - const tx = await send(comptroller, '_dropCompMarket', [cLOW._address]); - expect(await call(comptroller, 'getCompMarkets')).toEqual( - [cREP, cZRX].map((c) => c._address) - ); - expect(tx).toHaveLog('MarketComped', { - cToken: cLOW._address, - isComped: false - }); - }); - - it('should correctly drop a comp market from middle of array', async () => { - await send(comptroller, '_dropCompMarket', [cREP._address]); - expect(await call(comptroller, 'getCompMarkets')).toEqual( - [cLOW, cZRX].map((c) => c._address) - ); - }); - - it('should not drop a comp market unless called by admin', async () => { - await expect( - send(comptroller, '_dropCompMarket', [cLOW._address], {from: a1}) - ).rejects.toRevert('revert only admin can drop comp market'); - }); - - it('should not drop a comp market already dropped', async () => { - await send(comptroller, '_dropCompMarket', [cLOW._address]); - await expect( - send(comptroller, '_dropCompMarket', [cLOW._address]) - ).rejects.toRevert('revert market is not a comp market'); - }); - }); - - describe('_setCompRate', () => { - it('should correctly change comp rate if called by admin', async () => { - expect(await call(comptroller, 'compRate')).toEqualNumber(etherUnsigned(1e18)); - const tx1 = await send(comptroller, '_setCompRate', [etherUnsigned(3e18)]); - expect(await call(comptroller, 'compRate')).toEqualNumber(etherUnsigned(3e18)); - const tx2 = await send(comptroller, '_setCompRate', [etherUnsigned(2e18)]); - expect(await call(comptroller, 'compRate')).toEqualNumber(etherUnsigned(2e18)); - expect(tx2).toHaveLog('NewCompRate', { - oldCompRate: etherUnsigned(3e18), - newCompRate: etherUnsigned(2e18) - }); - }); - - it('should not change comp rate unless called by admin', async () => { - await expect( - send(comptroller, '_setCompRate', [cLOW._address], {from: a1}) - ).rejects.toRevert('revert only admin can change comp rate'); - }); - }); describe('updateContributorRewards', () => { it('should not fail when contributor rewards called on non-contributor', async () => { diff --git a/tests/Utils/Compound.js b/tests/Utils/Compound.js index 0404cccbc..e1cf05f20 100644 --- a/tests/Utils/Compound.js +++ b/tests/Utils/Compound.js @@ -76,6 +76,27 @@ async function makeComptroller(opts = {}) { return Object.assign(unitroller, { priceOracle }); } + if (kind == 'unitroller-g6') { + const unitroller = opts.unitroller || await deploy('Unitroller'); + const comptroller = await deploy('ComptrollerScenarioG6'); + const priceOracle = opts.priceOracle || await makePriceOracle(opts.priceOracleOpts); + const closeFactor = etherMantissa(dfn(opts.closeFactor, .051)); + const liquidationIncentive = etherMantissa(1); + const comp = opts.comp || await deploy('Comp', [opts.compOwner || root]); + const compRate = etherUnsigned(dfn(opts.compRate, 1e18)); + + await send(unitroller, '_setPendingImplementation', [comptroller._address]); + await send(comptroller, '_become', [unitroller._address]); + mergeInterface(unitroller, comptroller); + await send(unitroller, '_setLiquidationIncentive', [liquidationIncentive]); + await send(unitroller, '_setCloseFactor', [closeFactor]); + await send(unitroller, '_setPriceOracle', [priceOracle._address]); + await send(unitroller, '_setCompRate', [compRate]); + await send(unitroller, 'setCompAddress', [comp._address]); // harness only + + return Object.assign(unitroller, { priceOracle, comp }); + } + if (kind == 'unitroller') { const unitroller = opts.unitroller || await deploy('Unitroller'); const comptroller = await deploy('ComptrollerHarness'); @@ -92,7 +113,7 @@ async function makeComptroller(opts = {}) { await send(unitroller, '_setCloseFactor', [closeFactor]); await send(unitroller, '_setPriceOracle', [priceOracle._address]); await send(unitroller, 'setCompAddress', [comp._address]); // harness only - await send(unitroller, '_setCompRate', [compRate]); + await send(unitroller, 'harnessSetCompRate', [compRate]); return Object.assign(unitroller, { priceOracle, comp }); } diff --git a/tests/gasProfiler.js b/tests/gasProfiler.js index 92d6ebfd9..14af7c5de 100644 --- a/tests/gasProfiler.js +++ b/tests/gasProfiler.js @@ -1,19 +1,36 @@ const { etherUnsigned, etherMantissa, + etherExp, } = require('./Utils/Ethereum'); const { + makeComptroller, makeCToken, - fastForward, preApprove, preSupply, quickRedeem, } = require('./Utils/Compound'); +async function compBalance(comptroller, user) { + return etherUnsigned(await call(comptroller.comp, 'balanceOf', [user])) +} + +async function compAccrued(comptroller, user) { + return etherUnsigned(await call(comptroller, 'compAccrued', [user])); +} + +async function fastForwardPatch(patch, comptroller, blocks) { + if (patch == 'unitroller') { + return await send(comptroller, 'harnessFastForward', [blocks]); + } else { + return await send(comptroller, 'fastForward', [blocks]); + } +} + const fs = require('fs'); const util = require('util'); -const diffStringsUnified = require('jest-diff'); +const diffStringsUnified = require('jest-diff').default; async function preRedeem( @@ -59,95 +76,146 @@ async function mint(cToken, minter, mintAmount, exchangeRate) { return send(cToken, 'mint', [mintAmount], { from: minter }); } +async function claimComp(comptroller, holder) { + return send(comptroller, 'claimComp', [holder], { from: holder }); +} + /// GAS PROFILER: saves a digest of the gas prices of common CToken operations /// transiently fails, not sure why -describe('CToken', () => { +describe('Gas report', () => { let root, minter, redeemer, accounts, cToken; const exchangeRate = 50e3; const preMintAmount = etherUnsigned(30e4); const mintAmount = etherUnsigned(10e4); const mintTokens = mintAmount.div(exchangeRate); const redeemTokens = etherUnsigned(10e3); - const redeemAmount = redeemTokens.mul(exchangeRate); + const redeemAmount = redeemTokens.multipliedBy(exchangeRate); const filename = './gasCosts.json'; - beforeEach(async () => { - [root, minter, redeemer, ...accounts] = saddle.accounts; - cToken = await makeCToken({ - comptrollerOpts: { kind: 'bool' }, - interestRateModelOpts: { kind: 'white-paper'}, - exchangeRate + describe('CToken', () => { + beforeEach(async () => { + [root, minter, redeemer, ...accounts] = saddle.accounts; + cToken = await makeCToken({ + comptrollerOpts: { kind: 'bool'}, + interestRateModelOpts: { kind: 'white-paper'}, + exchangeRate + }); }); - }); - it('first mint', async () => { - await send(cToken, 'harnessSetAccrualBlockNumber', [40]); - await send(cToken, 'harnessSetBlockNumber', [41]); + it('first mint', async () => { + await send(cToken, 'harnessSetAccrualBlockNumber', [40]); + await send(cToken, 'harnessSetBlockNumber', [41]); - const trxReceipt = await mint(cToken, minter, mintAmount, exchangeRate); - recordGasCost(trxReceipt.gasUsed, 'first mint', filename); - }); + const trxReceipt = await mint(cToken, minter, mintAmount, exchangeRate); + recordGasCost(trxReceipt.gasUsed, 'first mint', filename); + }); - it.only('second mint', async () => { - await mint(cToken, minter, mintAmount, exchangeRate); + it('second mint', async () => { + await mint(cToken, minter, mintAmount, exchangeRate); - await send(cToken, 'harnessSetAccrualBlockNumber', [40]); - await send(cToken, 'harnessSetBlockNumber', [41]); + await send(cToken, 'harnessSetAccrualBlockNumber', [40]); + await send(cToken, 'harnessSetBlockNumber', [41]); - const mint2Receipt = await mint(cToken, minter, mintAmount, exchangeRate); - expect(Object.keys(mint2Receipt.events)).toEqual(['AccrueInterest', 'Transfer', 'Mint']); + const mint2Receipt = await mint(cToken, minter, mintAmount, exchangeRate); + expect(Object.keys(mint2Receipt.events)).toEqual(['AccrueInterest', 'Transfer', 'Mint']); - console.log(mint2Receipt.gasUsed); - const opcodeCount = {}; + console.log(mint2Receipt.gasUsed); + const opcodeCount = {}; - await saddle.trace(mint2Receipt, { - execLog: log => { - if (log.lastLog != undefined) { - const key = `${log.op} @ ${log.gasCost}`; - opcodeCount[key] = (opcodeCount[key] || 0) + 1; + await saddle.trace(mint2Receipt, { + execLog: log => { + if (log.lastLog != undefined) { + const key = `${log.op} @ ${log.gasCost}`; + opcodeCount[key] = (opcodeCount[key] || 0) + 1; + } } - } + }); + + recordGasCost(mint2Receipt.gasUsed, 'second mint', filename, opcodeCount); }); - recordGasCost(mint2Receipt.gasUsed, 'second mint', filename, opcodeCount); - }); + it('second mint, no interest accrued', async () => { + await mint(cToken, minter, mintAmount, exchangeRate); - it('second mint, no interest accrued', async () => { - await mint(cToken, minter, mintAmount, exchangeRate); + await send(cToken, 'harnessSetAccrualBlockNumber', [40]); + await send(cToken, 'harnessSetBlockNumber', [40]); - await send(cToken, 'harnessSetAccrualBlockNumber', [40]); - await send(cToken, 'harnessSetBlockNumber', [40]); + const mint2Receipt = await mint(cToken, minter, mintAmount, exchangeRate); + expect(Object.keys(mint2Receipt.events)).toEqual(['Transfer', 'Mint']); + recordGasCost(mint2Receipt.gasUsed, 'second mint, no interest accrued', filename); - const mint2Receipt = await mint(cToken, minter, mintAmount, exchangeRate); - expect(Object.keys(mint2Receipt.events)).toEqual(['Transfer', 'Mint']); - recordGasCost(mint2Receipt.gasUsed, 'second mint, no interest accrued', filename); + // console.log("NO ACCRUED"); + // const opcodeCount = {}; + // await saddle.trace(mint2Receipt, { + // execLog: log => { + // opcodeCount[log.op] = (opcodeCount[log.op] || 0) + 1; + // } + // }); + // console.log(getOpcodeDigest(opcodeCount)); + }); - // console.log("NO ACCRUED"); - // const opcodeCount = {}; - // await saddle.trace(mint2Receipt, { - // execLog: log => { - // opcodeCount[log.op] = (opcodeCount[log.op] || 0) + 1; - // } - // }); - // console.log(getOpcodeDigest(opcodeCount)); - }); + it('redeem', async () => { + await preRedeem(cToken, redeemer, redeemTokens, redeemAmount, exchangeRate); + const trxReceipt = await quickRedeem(cToken, redeemer, redeemTokens); + recordGasCost(trxReceipt.gasUsed, 'redeem', filename); + }); - it('redeem', async () => { - await preRedeem(cToken, redeemer, redeemTokens, redeemAmount, exchangeRate); - const trxReceipt = await quickRedeem(cToken, redeemer, redeemTokens); - recordGasCost(trxReceipt.gasUsed, 'redeem', filename); + it.skip('print mint opcode list', async () => { + await preMint(cToken, minter, mintAmount, mintTokens, exchangeRate); + const trxReceipt = await quickMint(cToken, minter, mintAmount); + const opcodeCount = {}; + await saddle.trace(trxReceipt, { + execLog: log => { + opcodeCount[log.op] = (opcodeCount[log.op] || 0) + 1; + } + }); + console.log(getOpcodeDigest(opcodeCount)); + }); }); - it.skip('print mint opcode list', async () => { - await preMint(cToken, minter, mintAmount, mintTokens, exchangeRate); - const trxReceipt = await quickMint(cToken, minter, mintAmount); - const opcodeCount = {}; - await saddle.trace(trxReceipt, { - execLog: log => { - opcodeCount[log.op] = (opcodeCount[log.op] || 0) + 1; + describe.each([ + ['unitroller-g6'], + ['unitroller'] + ])('Comp claims %s', (patch) => { + beforeEach(async () => { + [root, minter, redeemer, ...accounts] = saddle.accounts; + comptroller = await makeComptroller({ kind: patch }); + let interestRateModelOpts = {borrowRate: 0.000001}; + cToken = await makeCToken({comptroller, supportMarket: true, underlyingPrice: 2, interestRateModelOpts}); + if (patch == 'unitroller') { + await send(comptroller, '_setCompSpeed', [cToken._address, etherExp(0.05)]); + } else { + await send(comptroller, '_addCompMarkets', [[cToken].map(c => c._address)]); + await send(comptroller, 'setCompSpeed', [cToken._address, etherExp(0.05)]); } + await send(comptroller.comp, 'transfer', [comptroller._address, etherUnsigned(50e18)], {from: root}); + }); + + it(`${patch} second mint with comp accrued`, async () => { + await mint(cToken, minter, mintAmount, exchangeRate); + + await fastForwardPatch(patch, comptroller, 10); + + console.log('Comp balance before mint', (await compBalance(comptroller, minter)).toString()); + console.log('Comp accrued before mint', (await compAccrued(comptroller, minter)).toString()); + const mint2Receipt = await mint(cToken, minter, mintAmount, exchangeRate); + console.log('Comp balance after mint', (await compBalance(comptroller, minter)).toString()); + console.log('Comp accrued after mint', (await compAccrued(comptroller, minter)).toString()); + recordGasCost(mint2Receipt.gasUsed, `${patch} second mint with comp accrued`, filename); + }); + + it(`${patch} claim comp`, async () => { + await mint(cToken, minter, mintAmount, exchangeRate); + + await fastForwardPatch(patch, comptroller, 10); + + console.log('Comp balance before claim', (await compBalance(comptroller, minter)).toString()); + console.log('Comp accrued before claim', (await compAccrued(comptroller, minter)).toString()); + const claimReceipt = await claimComp(comptroller, minter); + console.log('Comp balance after claim', (await compBalance(comptroller, minter)).toString()); + console.log('Comp accrued after claim', (await compAccrued(comptroller, minter)).toString()); + recordGasCost(claimReceipt.gasUsed, `${patch} claim comp`, filename); }); - console.log(getOpcodeDigest(opcodeCount)); }); });