creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "contracts/CErc20Delegator.sol": {
        "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.23;\n\nimport \"contracts/CTokenInterfaces.sol\";\n\n/**\n * @title Compound's CErc20Delegator Contract\n * @notice CTokens which wrap an EIP-20 underlying and delegate to an implementation\n * @author Compound\n */\ncontract CErc20Delegator is CTokenInterface, CErc20Interface, CDelegatorInterface {\n    error Unauthorized();\n    \n    /**\n     * @notice Construct a new money market\n     * @param underlying_ The address of the underlying asset\n     * @param comptroller_ The address of the Comptroller\n     * @param interestRateModel_ The address of the interest rate model\n     * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18\n     * @param name_ ERC-20 name of this token\n     * @param symbol_ ERC-20 symbol of this token\n     * @param decimals_ ERC-20 decimal precision of this token\n     * @param admin_ Address of the administrator of this token\n     * @param implementation_ The address of the implementation the contract delegates to\n     * @param becomeImplementationData The encoded args for becomeImplementation\n     */\n    constructor(address underlying_,\n                ComptrollerInterface comptroller_,\n                InterestRateModel interestRateModel_,\n                uint initialExchangeRateMantissa_,\n                string memory name_,\n                string memory symbol_,\n                uint8 decimals_,\n                address payable admin_,\n                address implementation_,\n                bytes memory becomeImplementationData) {\n        // Creator of the contract is admin during initialization\n        admin = payable(msg.sender);\n\n        // First delegate gets to initialize the delegator (i.e. storage contract)\n        delegateTo(implementation_, abi.encodeWithSignature(\"initialize(address,address,address,uint256,string,string,uint8,uint8)\",\n                                                            underlying_,\n                                                            comptroller_,\n                                                            interestRateModel_,\n                                                            initialExchangeRateMantissa_,\n                                                            name_,\n                                                            symbol_,\n                                                            decimals_,\n                                                            CTokenStorage.MarketType.ERC20_MARKET));\n\n        // New implementations always get set via the settor (post-initialize)\n        _setImplementation(implementation_, false, becomeImplementationData);\n\n        // Set the proper admin now that initialization is done\n        admin = admin_;\n    }\n\n    /**\n     * @notice Called by the admin to update the implementation of the delegator\n     * @param implementation_ The address of the new implementation for delegation\n     * @param allowResign Flag to indicate whether to call _resignImplementation on the old implementation\n     * @param becomeImplementationData The encoded bytes data to be passed to _becomeImplementation\n     */\n    function _setImplementation(address implementation_, bool allowResign, bytes memory becomeImplementationData)override public {\n        if (msg.sender != admin) {\n            revert Unauthorized();\n        }\n\n        if (allowResign) {\n            delegateToImplementation(abi.encodeWithSignature(\"_resignImplementation()\"));\n        }\n\n        address oldImplementation = implementation;\n        implementation = implementation_;\n\n        delegateToImplementation(abi.encodeWithSignature(\"_becomeImplementation(bytes)\", becomeImplementationData));\n\n        emit NewImplementation(oldImplementation, implementation);\n    }\n\n    /**\n     * @notice Sender supplies assets into the market and receives cTokens in exchange\n     * @dev Accrues interest whether or not the operation succeeds, unless reverted\n     * @param mintAmount The amount of the underlying asset to supply\n     * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n     */\n    function mint(uint mintAmount) override external returns (uint) {\n        bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"mint(uint256)\", mintAmount));\n        return abi.decode(data, (uint));\n    }\n\n    /**\n     * @notice Sender redeems cTokens in exchange for the underlying asset\n     * @dev Accrues interest whether or not the operation succeeds, unless reverted\n     * @param redeemTokens The number of cTokens to redeem into underlying\n     * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n     */\n    function redeem(uint redeemTokens) override external returns (uint) {\n        bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"redeem(uint256)\", redeemTokens));\n        return abi.decode(data, (uint));\n    }\n\n    /**\n     * @notice Sender redeems cTokens in exchange for a specified amount of underlying asset\n     * @dev Accrues interest whether or not the operation succeeds, unless reverted\n     * @param redeemAmount The amount of underlying to redeem\n     * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n     */\n    function redeemUnderlying(uint redeemAmount) override external returns (uint) {\n        bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"redeemUnderlying(uint256)\", redeemAmount));\n        return abi.decode(data, (uint));\n    }\n\n    /**\n      * @notice Sender borrows assets from the protocol to their own address\n      * @param borrowAmount The amount of the underlying asset to borrow\n      * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n      */\n    function borrow(uint borrowAmount) override external returns (uint) {\n        bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"borrow(uint256)\", borrowAmount));\n        return abi.decode(data, (uint));\n    }\n\n    /**\n     * @notice Sender repays their own borrow\n     * @param repayAmount The amount to repay, or -1 for the full outstanding amount\n     * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n     */\n    function repayBorrow(uint repayAmount) override external returns (uint) {\n        bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"repayBorrow(uint256)\", repayAmount));\n        return abi.decode(data, (uint));\n    }\n\n    /**\n     * @notice Sender repays a borrow belonging to borrower\n     * @param borrower the account with the debt being payed off\n     * @param repayAmount The amount to repay, or -1 for the full outstanding amount\n     * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n     */\n    function repayBorrowBehalf(address borrower, uint repayAmount) override external returns (uint) {\n        bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"repayBorrowBehalf(address,uint256)\", borrower, repayAmount));\n        return abi.decode(data, (uint));\n    }\n\n    /**\n     * @notice The liquidator liquidates the borrowers collateral.\n     *  This function can only be called by the Comptroller.\n     * @param liquidator The liquidator who called Comptroller::batchLiquidateBorrow\n     * @param borrower The borrower of this cToken to be liquidated\n     * @param repayAmount The amount of the underlying borrowed asset to repay\n     * @return uint The amount of the underlying borrowed asset that was actually repaid\n     */\n    function _liquidateBorrow(address liquidator, address borrower, uint repayAmount) override external returns (uint) {\n        bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"_liquidateBorrow(address,address,uint256)\", liquidator, borrower, repayAmount));\n        return abi.decode(data, (uint));\n    }\n\n    /**\n     * @notice Transfer `amount` tokens from `msg.sender` to `dst`\n     * @param dst The address of the destination account\n     * @param amount The number of tokens to transfer\n     * @return Whether or not the transfer succeeded\n     */\n    function transfer(address dst, uint amount) override external returns (bool) {\n        bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"transfer(address,uint256)\", dst, amount));\n        return abi.decode(data, (bool));\n    }\n\n    /**\n     * @notice Transfer `amount` tokens from `src` to `dst`\n     * @param src The address of the source account\n     * @param dst The address of the destination account\n     * @param amount The number of tokens to transfer\n     * @return Whether or not the transfer succeeded\n     */\n    function transferFrom(address src, address dst, uint256 amount) override external returns (bool) {\n        bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"transferFrom(address,address,uint256)\", src, dst, amount));\n        return abi.decode(data, (bool));\n    }\n\n    /**\n     * @notice Approve `spender` to transfer up to `amount` from `src`\n     * @dev This will overwrite the approval amount for `spender`\n     *  and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve)\n     * @param spender The address of the account which may transfer tokens\n     * @param amount The number of tokens that are approved (-1 means infinite)\n     * @return Whether or not the approval succeeded\n     */\n    function approve(address spender, uint256 amount) override external returns (bool) {\n        bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"approve(address,uint256)\", spender, amount));\n        return abi.decode(data, (bool));\n    }\n\n    /**\n     * @notice Get the current allowance from `owner` for `spender`\n     * @param owner The address of the account which owns the tokens to be spent\n     * @param spender The address of the account which may transfer tokens\n     * @return The number of tokens allowed to be spent (-1 means infinite)\n     */\n    function allowance(address owner, address spender) override external view returns (uint) {\n        bytes memory data = delegateToViewImplementation(abi.encodeWithSignature(\"allowance(address,address)\", owner, spender));\n        return abi.decode(data, (uint));\n    }\n\n    /**\n     * @notice Get the token balance of the `owner`\n     * @param owner The address of the account to query\n     * @return The number of tokens owned by `owner`\n     */\n    function balanceOf(address owner) override external view returns (uint) {\n        bytes memory data = delegateToViewImplementation(abi.encodeWithSignature(\"balanceOf(address)\", owner));\n        return abi.decode(data, (uint));\n    }\n\n    /**\n     * @notice Get the underlying balance of the `owner`\n     * @dev This also accrues interest in a transaction\n     * @param owner The address of the account to query\n     * @return The amount of underlying owned by `owner`\n     */\n    function balanceOfUnderlying(address owner) override external returns (uint) {\n        bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"balanceOfUnderlying(address)\", owner));\n        return abi.decode(data, (uint));\n    }\n\n    /**\n     * @notice Get a snapshot of the account's balances, and the cached exchange rate\n     * @dev This is used by comptroller to more efficiently perform liquidity checks.\n     * @param account Address of the account to snapshot\n     * @return (possible error, token balance, borrow balance, exchange rate mantissa, borrow interest balance (always 0))\n     */\n    function getAccountSnapshot(address account) override external view returns (uint, uint, uint, uint, uint) {\n        bytes memory data = delegateToViewImplementation(abi.encodeWithSignature(\"getAccountSnapshot(address)\", account));\n        return abi.decode(data, (uint, uint, uint, uint, uint));\n    }\n\n    /**\n     * @notice Returns the current per-block borrow interest rate for this cToken\n     * @return The borrow interest rate per block, scaled by 1e18\n     */\n    function borrowRatePerBlock() override external view returns (uint) {\n        bytes memory data = delegateToViewImplementation(abi.encodeWithSignature(\"borrowRatePerBlock()\"));\n        return abi.decode(data, (uint));\n    }\n\n    /**\n     * @notice Returns the current per-block supply interest rate for this cToken\n     * @return The supply interest rate per block, scaled by 1e18\n     */\n    function supplyRatePerBlock() override external view returns (uint) {\n        bytes memory data = delegateToViewImplementation(abi.encodeWithSignature(\"supplyRatePerBlock()\"));\n        return abi.decode(data, (uint));\n    }\n\n    /**\n     * @notice Returns the current total borrows plus accrued interest\n     * @return The total borrows with interest\n     */\n    function totalBorrowsCurrent() override external returns (uint) {\n        bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"totalBorrowsCurrent()\"));\n        return abi.decode(data, (uint));\n    }\n\n    /**\n     * @notice Accrue interest to updated borrowIndex and then calculate account's borrow balance using the updated borrowIndex\n     * @param account The address whose balance should be calculated after updating borrowIndex\n     * @return The calculated balance\n     */\n    function borrowBalanceCurrent(address account) override external returns (uint) {\n        bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"borrowBalanceCurrent(address)\", account));\n        return abi.decode(data, (uint));\n    }\n\n    /**\n     * @notice Return the borrow balance of account based on stored data\n     * @param account The address whose balance should be calculated\n     * @return The calculated balance\n     */\n    function borrowBalanceStored(address account) override public view returns (uint) {\n        bytes memory data = delegateToViewImplementation(abi.encodeWithSignature(\"borrowBalanceStored(address)\", account));\n        return abi.decode(data, (uint));\n    }\n\n    /**\n     * @notice Accrue interest then return the up-to-date exchange rate\n     * @return Calculated exchange rate scaled by 1e18\n     */\n    function exchangeRateCurrent() override public returns (uint) {\n        bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"exchangeRateCurrent()\"));\n        return abi.decode(data, (uint));\n    }\n\n    /**\n     * @notice Calculates the exchange rate from the underlying to the CToken\n     * @dev This function does not accrue interest before calculating the exchange rate\n     * @return Calculated exchange rate scaled by 1e18\n     */\n    function exchangeRateStored() override public view returns (uint) {\n        bytes memory data = delegateToViewImplementation(abi.encodeWithSignature(\"exchangeRateStored()\"));\n        return abi.decode(data, (uint));\n    }\n\n    /**\n     * @notice Get cash balance of this cToken in the underlying asset\n     * @return The quantity of underlying asset owned by this contract\n     */\n    function getCash() override external view returns (uint) {\n        bytes memory data = delegateToViewImplementation(abi.encodeWithSignature(\"getCash()\"));\n        return abi.decode(data, (uint));\n    }\n\n    /**\n      * @notice Applies accrued interest to total borrows and reserves.\n      * @dev This calculates interest accrued from the last checkpointed block\n      *      up to the current block and writes new checkpoint to storage.\n      */\n    function accrueInterest() override public returns (uint) {\n        bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"accrueInterest()\"));\n        return abi.decode(data, (uint));\n    }\n\n    /**\n     * @notice Transfers collateral tokens (this market) to the liquidator.\n     *         This function can only be called by the Comptroller.\n     * @param liquidator The account receiving seized collateral\n     * @param borrower The account having collateral seized\n     * @param seizeTokens The number of cTokens to seize\n     * @return uint actual seizeTokens\n     */\n    function _seize(address liquidator, address borrower, uint seizeTokens) override external returns (uint) {\n        bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"_seize(address,address,uint256)\", liquidator, borrower, seizeTokens));\n        return abi.decode(data, (uint));\n    }\n\n    /**\n     * @notice A public function to sweep accidental ERC-20 transfers to this contract. Tokens are sent to admin (timelock)\n     * @param token The address of the ERC-20 token to sweep\n     */\n    function sweepToken(EIP20NonStandardInterface token) override external {\n        delegateToImplementation(abi.encodeWithSignature(\"sweepToken(address)\", token));\n    }\n\n\n    /*** Admin Functions ***/\n\n    /**\n      * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n      * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n      * @param newPendingAdmin New pending admin.\n      * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n      */\n    function _setPendingAdmin(address payable newPendingAdmin) override external returns (uint) {\n        bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"_setPendingAdmin(address)\", newPendingAdmin));\n        return abi.decode(data, (uint));\n    }\n\n    /**\n      * @notice Sets a new comptroller for the market\n      * @dev Admin function to set a new comptroller\n      * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n      */\n    function _setComptroller(ComptrollerInterface newComptroller) override public returns (uint) {\n        bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"_setComptroller(address)\", newComptroller));\n        return abi.decode(data, (uint));\n    }\n\n    /**\n      * @notice Sets protocolSeizeShareMantissa\n      * @dev Admin function to set protocolSeizeShareMantissa\n      * @param newProtocolSeizeShareMantissa New protocolSeizeShareMantissa scaled by 1e18\n      * @return uint 0=success, otherwise a failure. (See ErrorReporter for details)\n      */\n    function _setProtocolSeizeShare(uint newProtocolSeizeShareMantissa) override external returns (uint) {\n        bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"_setProtocolSeizeShare(uint256)\", newProtocolSeizeShareMantissa));\n        return abi.decode(data, (uint));\n    }\n\n    /**\n      * @notice accrues interest and sets a new reserve factor for the protocol using _setReserveFactorFresh\n      * @dev Admin function to accrue interest and set a new reserve factor\n      * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n      */\n    function _setReserveFactor(uint newReserveFactorMantissa) override external returns (uint) {\n        bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"_setReserveFactor(uint256)\", newReserveFactorMantissa));\n        return abi.decode(data, (uint));\n    }\n\n    /**\n      * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\n      * @dev Admin function for pending admin to accept role and update admin\n      * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n      */\n    function _acceptAdmin() override external returns (uint) {\n        bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"_acceptAdmin()\"));\n        return abi.decode(data, (uint));\n    }\n\n    /**\n     * @notice Accrues interest and adds reserves by transferring from admin\n     * @param addAmount Amount of reserves to add\n     * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n     */\n    function _addReserves(uint addAmount) override external returns (uint) {\n        bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"_addReserves(uint256)\", addAmount));\n        return abi.decode(data, (uint));\n    }\n\n    /**\n     * @notice Accrues interest and reduces reserves by transferring to admin\n     * @param reduceAmount Amount of reduction to reserves\n     * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n     */\n    function _reduceReserves(uint reduceAmount) override external returns (uint) {\n        bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"_reduceReserves(uint256)\", reduceAmount));\n        return abi.decode(data, (uint));\n    }\n\n    /**\n     * @notice Accrues interest and updates the interest rate model using _setInterestRateModelFresh\n     * @dev Admin function to accrue interest and update the interest rate model\n     * @param newInterestRateModel the new interest rate model to use\n     * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n     */\n    function _setInterestRateModel(InterestRateModel newInterestRateModel) override public returns (uint) {\n        bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"_setInterestRateModel(address)\", newInterestRateModel));\n        return abi.decode(data, (uint));\n    }\n\n    /**\n     * @notice Internal method to delegate execution to another contract\n     * @dev It returns to the external caller whatever the implementation returns or forwards reverts\n     * @param callee The contract to delegatecall\n     * @param data The raw data to delegatecall\n     * @return The returned bytes from the delegatecall\n     */\n    function delegateTo(address callee, bytes memory data) internal returns (bytes memory) {\n        (bool success, bytes memory returnData) = callee.delegatecall(data);\n        assembly {\n            if eq(success, 0) {\n                revert(add(returnData, 0x20), returndatasize())\n            }\n        }\n        return returnData;\n    }\n\n    /**\n     * @notice Delegates execution to the implementation contract\n     * @dev It returns to the external caller whatever the implementation returns or forwards reverts\n     * @param data The raw data to delegatecall\n     * @return The returned bytes from the delegatecall\n     */\n    function delegateToImplementation(bytes memory data) public returns (bytes memory) {\n        return delegateTo(implementation, data);\n    }\n\n    /**\n     * @notice Delegates execution to an implementation contract\n     * @dev It returns to the external caller whatever the implementation returns or forwards reverts\n     *  There are an additional 2 prefix uints from the wrapper returndata, which we ignore since we make an extra hop.\n     * @param data The raw data to delegatecall\n     * @return The returned bytes from the delegatecall\n     */\n    function delegateToViewImplementation(bytes memory data) public view returns (bytes memory) {\n        (bool success, bytes memory returnData) = address(this).staticcall(abi.encodeWithSignature(\"delegateToImplementation(bytes)\", data));\n        assembly {\n            if eq(success, 0) {\n                revert(add(returnData, 0x20), returndatasize())\n            }\n        }\n        return abi.decode(returnData, (bytes));\n    }\n\n    /**\n     * @notice Delegates execution to an implementation contract\n     * @dev It returns to the external caller whatever the implementation returns or forwards reverts\n     */\n    fallback() external payable {\n        if (msg.value != 0) {\n            revert CannotReceiveValueGtZero();\n        }\n\n        // delegate all other functions to current implementation\n        (bool success, ) = implementation.delegatecall(msg.data);\n\n        assembly {\n            let free_mem_ptr := mload(0x40)\n            returndatacopy(free_mem_ptr, 0, returndatasize())\n\n            switch success\n            case 0 { revert(free_mem_ptr, returndatasize()) }\n            default { return(free_mem_ptr, returndatasize()) }\n        }\n    }\n}\n"
      },
      "contracts/CTokenInterfaces.sol": {
        "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.23;\n\nimport \"contracts/ComptrollerInterface.sol\";\nimport \"contracts/InterestRateModel.sol\";\nimport \"contracts/EIP20NonStandardInterface.sol\";\nimport \"contracts/ErrorReporter.sol\";\n\ncontract CTokenStorage {\n    /**\n     * @dev Guard variable for re-entrancy checks\n     */\n    bool internal _notEntered;\n\n    /**\n     * @notice EIP-20 token name for this token\n     */\n    string public name;\n\n    /**\n     * @notice EIP-20 token symbol for this token\n     */\n    string public symbol;\n\n    /**\n     * @notice EIP-20 token decimals for this token\n     */\n    uint8 public decimals;\n\n    // Maximum borrow rate that can ever be applied (.0005% / block)\n    uint internal constant borrowRateMaxMantissa = 0.0005e16;\n\n    // Maximum fraction of interest that can be set aside for reserves\n    uint internal constant reserveFactorMaxMantissa = 1e18;\n\n    // Maximum protocol seize share that can be set\n    uint internal constant protocolSeizeShareMaxMantissa = 20e16;\n\n    /**\n     * @notice Administrator for this contract\n     */\n    address payable public admin;\n\n    /**\n     * @notice Pending administrator for this contract\n     */\n    address payable public pendingAdmin;\n\n    /**\n     * @notice Contract which oversees inter-cToken operations\n     */\n    ComptrollerInterface public comptroller;\n\n    /**\n     * @notice Model which tells what the current interest rate should be\n     */\n    InterestRateModel public interestRateModel;\n\n    // Initial exchange rate used when minting the first CTokens (used when totalSupply = 0)\n    uint internal initialExchangeRateMantissa;\n\n    /**\n     * @notice Fraction of interest currently set aside for reserves\n     */\n    uint public reserveFactorMantissa;\n\n    /**\n     * @notice Block number that interest was last accrued at\n     */\n    uint public accrualBlockNumber;\n\n    /**\n     * @notice Accumulator of the total earned interest rate since the opening of the market\n     */\n    uint public borrowIndex;\n\n    /**\n     * @notice Total amount of outstanding borrows of the underlying in this market\n     */\n    uint public totalBorrows;\n\n    /**\n     * @notice Total amount of reserves of the underlying held in this market\n     */\n    uint public totalReserves;\n\n    /**\n     * @notice Total number of tokens in circulation\n     */\n    uint public totalSupply;\n\n    // Official record of token balances for each account\n    mapping (address => uint) internal accountTokens;\n\n    // Approved token transfer amounts on behalf of others\n    mapping (address => mapping (address => uint)) internal transferAllowances;\n\n    /**\n     * @notice Container for borrow balance information\n     * @member principal Total balance (with accrued interest), after applying the most recent balance-changing action\n     * @member interestIndex Global borrowIndex as of the most recent balance-changing action\n     * @member interestAccrued Total interest accrued for markets that track it separately from borrow balance\n     */\n    struct BorrowSnapshot {\n        uint principal;\n        uint interestIndex;\n        uint interestAccrued;\n    }\n\n    // Mapping of account addresses to outstanding borrow balances\n    mapping(address => BorrowSnapshot) internal accountBorrows;\n\n    /**\n     * @notice Share of seized collateral that is added to reserves\n     */\n    uint public protocolSeizeShareMantissa = 2.8e16; //2.8%\n\n    /**\n     * @notice MarketType enum\n     */\n    enum MarketType {\n        UNDEFINED_MARKET,\n        ERC20_MARKET,\n        ERC721_MARKET,\n        ERC20_INTEREST_MARKET\n    }\n\n    /**\n     * @notice Indicates a token market type\n     */\n    MarketType public marketType;\n}\n\nabstract contract CTokenInterface is CTokenStorage {\n    /**\n     * @notice Indicator that this is a CToken contract (for inspection)\n     */\n    bool public constant isCToken = true;\n\n\n    /*** Market Events ***/\n\n    /**\n     * @notice Event emitted when interest is accrued\n     */\n    event AccrueInterest(uint cashPrior, uint interestAccumulated, uint borrowIndex, uint totalBorrows);\n\n    /**\n     * @notice Event emitted when tokens are minted\n     */\n    event Mint(address minter, uint mintAmount, uint mintTokens);\n\n    /**\n     * @notice Event emitted when tokens are redeemed\n     */\n    event Redeem(address redeemer, uint redeemAmount, uint redeemTokens);\n\n    /**\n     * @notice Event emitted when underlying is borrowed\n     */\n    event Borrow(address borrower, uint borrowAmount, uint accountBorrows, uint totalBorrows);\n\n    /**\n     * @notice Event emitted when a borrow is repaid\n     */\n    event RepayBorrow(address payer, address borrower, uint repayAmount, uint accountBorrows, uint totalBorrows);\n\n    /**\n     * @notice Event emitted when a borrow is liquidated\n     */\n    event LiquidateBorrow(address liquidator, address borrower, uint repayAmount);\n\n\n    /*** Admin Events ***/\n\n    /**\n     * @notice Event emitted when pendingAdmin is changed\n     */\n    event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\n\n    /**\n     * @notice Event emitted when pendingAdmin is accepted, which means admin is updated\n     */\n    event NewAdmin(address oldAdmin, address newAdmin);\n\n    /**\n     * @notice Event emitted when comptroller is changed\n     */\n    event NewComptroller(ComptrollerInterface oldComptroller, ComptrollerInterface newComptroller);\n\n    /**\n     * @notice Event emitted when interestRateModel is changed\n     */\n    event NewMarketInterestRateModel(InterestRateModel oldInterestRateModel, InterestRateModel newInterestRateModel);\n\n    /**\n     * @notice Event emitted when the seize share is changed\n     */\n    event NewProtocolSeizeShare(uint oldProtocolSeizeShareMantissa, uint newProtocolSeizeShareMantissa);\n\n    /**\n     * @notice Event emitted when the reserve factor is changed\n     */\n    event NewReserveFactor(uint oldReserveFactorMantissa, uint newReserveFactorMantissa);\n\n    /**\n     * @notice Event emitted when the reserves are added\n     */\n    event ReservesAdded(address benefactor, uint addAmount, uint newTotalReserves);\n\n    /**\n     * @notice Event emitted when the reserves are reduced\n     */\n    event ReservesReduced(address admin, uint reduceAmount, uint newTotalReserves);\n\n    /**\n     * @notice EIP20 Transfer event\n     */\n    event Transfer(address indexed from, address indexed to, uint amount);\n\n    /**\n     * @notice EIP20 Approval event\n     */\n    event Approval(address indexed owner, address indexed spender, uint amount);\n\n\n    /*** User Interface ***/\n\n    function transfer(address dst, uint amount) virtual external returns (bool);\n    function transferFrom(address src, address dst, uint amount) virtual external returns (bool);\n    function approve(address spender, uint amount) virtual external returns (bool);\n    function allowance(address owner, address spender) virtual external view returns (uint);\n    function balanceOf(address owner) virtual external view returns (uint);\n    function balanceOfUnderlying(address owner) virtual external returns (uint);\n    function getAccountSnapshot(address account) virtual external view returns (uint, uint, uint, uint, uint);\n    function borrowRatePerBlock() virtual external view returns (uint);\n    function supplyRatePerBlock() virtual external view returns (uint);\n    function totalBorrowsCurrent() virtual external returns (uint);\n    function borrowBalanceCurrent(address account) virtual external returns (uint);\n    function borrowBalanceStored(address account) virtual external view returns (uint);\n    function exchangeRateCurrent() virtual external returns (uint);\n    function exchangeRateStored() virtual external view returns (uint);\n    function getCash() virtual external view returns (uint);\n    function accrueInterest() virtual external returns (uint);\n    function _seize(address liquidator, address borrower, uint seizeTokens) virtual external returns (uint);\n    function sweepToken(EIP20NonStandardInterface token) virtual external;\n\n\n    /*** Admin Functions ***/\n\n    function _setPendingAdmin(address payable newPendingAdmin) virtual external returns (uint);\n    function _acceptAdmin() virtual external returns (uint);\n    function _setComptroller(ComptrollerInterface newComptroller) virtual external returns (uint);\n    function _setProtocolSeizeShare(uint newProtocolSeizeShareMantissa) virtual external returns (uint);\n    function _setReserveFactor(uint newReserveFactorMantissa) virtual external returns (uint);\n    function _reduceReserves(uint reduceAmount) virtual external returns (uint);\n    function _setInterestRateModel(InterestRateModel newInterestRateModel) virtual external returns (uint);\n}\n\ncontract CErc20Storage {\n    /**\n     * @notice Underlying asset for this CToken\n     */\n    address public underlying;\n}\n\nabstract contract CErc20Interface is CErc20Storage {\n\n    /*** User Interface ***/\n\n    function mint(uint mintAmount) virtual external returns (uint);\n    function redeem(uint redeemTokens) virtual external returns (uint);\n    function redeemUnderlying(uint redeemAmount) virtual external returns (uint);\n    function borrow(uint borrowAmount) virtual external returns (uint);\n    function repayBorrow(uint repayAmount) virtual external returns (uint);\n    function repayBorrowBehalf(address borrower, uint repayAmount) virtual external returns (uint);\n    function _liquidateBorrow(address liquidator, address borrower, uint repayAmount) virtual external returns (uint);\n\n    /*** Admin Functions ***/\n\n    function _addReserves(uint addAmount) virtual external returns (uint);\n}\n\ninterface IWeth {\n    function transferFrom(address src, address dst, uint wad) external;\n    function withdraw(uint256 wad) external;\n}\n\nabstract contract CEtherInterface is CErc20Storage {\n\n    /*** User Interface ***/\n\n    function mint() virtual external payable;\n    function redeem(uint redeemTokens) virtual external returns (uint);\n    function redeemUnderlying(uint redeemAmount) virtual external returns (uint);\n    function borrow(uint borrowAmount) virtual external returns (uint);\n    function repayBorrow() virtual external payable;\n    function repayBorrowBehalf(address borrower) virtual external payable;\n    function _liquidateBorrow(address liquidator, address borrower, uint repayAmount) virtual external returns (uint);\n\n    /*** Admin Functions ***/\n\n    function _addReserves() virtual external payable returns (uint);\n}\n\ncontract CDelegationStorage {\n    /**\n     * @notice Implementation address for this contract\n     */\n    address public implementation;\n}\n\nabstract contract CDelegatorInterface is CDelegationStorage {\n    /**\n     * @notice Emitted when implementation is changed\n     */\n    event NewImplementation(address oldImplementation, address newImplementation);\n\n    error CannotReceiveValueGtZero();\n\n    /**\n     * @notice Called by the admin to update the implementation of the delegator\n     * @param implementation_ The address of the new implementation for delegation\n     * @param allowResign Flag to indicate whether to call _resignImplementation on the old implementation\n     * @param becomeImplementationData The encoded bytes data to be passed to _becomeImplementation\n     */\n    function _setImplementation(address implementation_, bool allowResign, bytes memory becomeImplementationData) virtual external;\n}\n\nabstract contract CDelegateInterface is CDelegationStorage {\n    /**\n     * @notice Called by the delegator on a delegate to initialize it for duty\n     * @dev Should revert if any issues arise which make it unfit for delegation\n     * @param data The encoded bytes data for any initialization\n     */\n    function _becomeImplementation(bytes memory data) virtual external;\n\n    /**\n     * @notice Called by the delegator on a delegate to forfeit its responsibility\n     */\n    function _resignImplementation() virtual external;\n}\n"
      },
      "contracts/ComptrollerInterface.sol": {
        "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.23;\n\nabstract contract ComptrollerInterface {\n    /// @notice Indicator that this is a Comptroller contract (for inspection)\n    bool public constant isComptroller = true;\n\n    /*** Assets You Are In ***/\n\n    function autoEnterMarkets(address account) virtual external;\n    function autoExitMarkets(address account) virtual external;\n    function enterMarkets(address[] calldata cTokens) virtual external returns (uint[] memory);\n    function exitMarket(address cToken) virtual external returns (uint);\n    function redeemAllInterest(address lender, address[] memory cTokens) virtual external returns (uint[] memory);\n\n    /*** Policy Hooks ***/\n\n    function mintAllowed(address cToken, address minter, uint mintAmount) virtual external returns (uint);\n\n    function redeemAllowed(address cToken, address redeemer, uint redeemTokens) virtual external returns (uint);\n\n    function borrowAllowed(address cToken, address borrower, uint borrowAmount) virtual external returns (uint);\n\n    function repayBorrowAllowed(\n        address cToken,\n        address payer,\n        address borrower,\n        uint repayAmount) virtual external returns (uint);\n\n    function collectInterestAllowed(\n        address cTokenInterestMarket,\n        address cTokenSupplyMarket,\n        address lender,\n        uint interestAmount) virtual external returns (uint);\n\n    function payInterestAllowed(\n        address cTokenInterestMarket,\n        address cTokenBorrowMarket,\n        address payer,\n        uint payTokens) virtual external returns (uint);\n\n    function transferAllowed(address cToken, address src, address dst, uint transferTokens) virtual external returns (uint);\n\n    function isListed(address cToken) virtual external view returns (bool);\n\n    function getAssetsExchangeRate(address cTokenA, address cTokenB) virtual external view returns (uint);\n\n    function _checkEoaOrWL(address msgSender) virtual external view returns (bool);\n\n    /*** Liquidity/Liquidation Calculations ***/\n\n    struct Liquidatables {\n        address cToken; // token to liquidate\n        uint amount;    // non-NFT markets\n        uint[] nftIds;  // NFT markets\n    }\n\n    function topUpInterestShortfall(address borrower, uint maxTopUpTokens, address cTokenCollateral) virtual external returns (uint[2] memory);\n\n    function batchLiquidateBorrow(address borrower, Liquidatables[] memory liquidatables, address[] memory cTokenCollaterals, uint minSeizedValue) virtual external returns (uint[][2] memory results);\n\n    function liquidateCalculateSeizeTokensNormed(address cTokenCollateral, uint normedRepayAmount) virtual public view returns (uint);\n\n    function interestMarket() virtual external view returns (address);\n}\n"
      },
      "contracts/InterestRateModel.sol": {
        "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.23;\n\n/**\n  * @title Compound's InterestRateModel Interface\n  * @author Compound\n  */\nabstract contract InterestRateModel {\n    /// @notice Indicator that this is an InterestRateModel contract (for inspection)\n    bool public constant isInterestRateModel = true;\n\n    /**\n      * @notice Calculates the current borrow interest rate per block\n      * @param cash The total amount of cash the market has\n      * @param borrows The total amount of borrows the market has outstanding\n      * @param reserves The total amount of reserves the market has\n      * @return The borrow rate per block (as a percentage, and scaled by 1e18)\n      */\n    function getBorrowRate(uint cash, uint borrows, uint reserves) virtual public view returns (uint);\n\n    /**\n      * @notice Calculates the current supply interest rate per block\n      * @param cash The total amount of cash the market has\n      * @param borrows The total amount of borrows the market has outstanding\n      * @param reserves The total amount of reserves the market has\n      * @param reserveFactorMantissa The current reserve factor the market has\n      * @return The supply rate per block (as a percentage, and scaled by 1e18)\n      */\n    function getSupplyRate(uint cash, uint borrows, uint reserves, uint reserveFactorMantissa) virtual public view returns (uint);\n\n    /**\n     * @notice Calculates the current borrow and supply rate per block\n     * @param cash The amount of cash in the market\n     * @param borrows The amount of borrows in the market\n     * @param reserves The amount of reserves in the market\n     * @param reserveFactorMantissa The current reserve factor for the market\n     * @return (uint, uint) The borrow rate percentage per block as a mantissa (scaled by BASE),\n     *         supply rate percentage per block as a mantissa (scaled by BASE)\n     */\n    function getMarketRates(uint cash, uint borrows, uint reserves, uint reserveFactorMantissa) virtual public view returns (uint, uint) {\n      return (getBorrowRate(cash, borrows, reserves), getSupplyRate(cash, borrows, reserves, reserveFactorMantissa));\n    }\n}\n"
      },
      "contracts/EIP20NonStandardInterface.sol": {
        "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.23;\n\n/**\n * @title EIP20NonStandardInterface\n * @dev Version of ERC20 with no return values for `transfer` and `transferFrom`\n *  See https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca\n */\ninterface EIP20NonStandardInterface {\n\n    /**\n     * @notice Get the total number of tokens in circulation\n     * @return The supply of tokens\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @notice Gets the balance of the specified address\n     * @param owner The address from which the balance will be retrieved\n     * @return balance The balance\n     */\n    function balanceOf(address owner) external view returns (uint256 balance);\n\n    ///\n    /// !!!!!!!!!!!!!!\n    /// !!! NOTICE !!! `transfer` does not return a value, in violation of the ERC-20 specification\n    /// !!!!!!!!!!!!!!\n    ///\n\n    /**\n      * @notice Transfer `amount` tokens from `msg.sender` to `dst`\n      * @param dst The address of the destination account\n      * @param amount The number of tokens to transfer\n      */\n    function transfer(address dst, uint256 amount) external;\n\n    ///\n    /// !!!!!!!!!!!!!!\n    /// !!! NOTICE !!! `transferFrom` does not return a value, in violation of the ERC-20 specification\n    /// !!!!!!!!!!!!!!\n    ///\n\n    /**\n      * @notice Transfer `amount` tokens from `src` to `dst`\n      * @param src The address of the source account\n      * @param dst The address of the destination account\n      * @param amount The number of tokens to transfer\n      */\n    function transferFrom(address src, address dst, uint256 amount) external;\n\n    /**\n      * @notice Approve `spender` to transfer up to `amount` from `src`\n      * @dev This will overwrite the approval amount for `spender`\n      *  and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve)\n      * @param spender The address of the account which may transfer tokens\n      * @param amount The number of tokens that are approved\n      * @return success Whether or not the approval succeeded\n      */\n    function approve(address spender, uint256 amount) external returns (bool success);\n\n    /**\n      * @notice Get the current allowance from `owner` for `spender`\n      * @param owner The address of the account which owns the tokens to be spent\n      * @param spender The address of the account which may transfer tokens\n      * @return remaining The number of tokens allowed to be spent\n      */\n    function allowance(address owner, address spender) external view returns (uint256 remaining);\n\n    event Transfer(address indexed from, address indexed to, uint256 amount);\n    event Approval(address indexed owner, address indexed spender, uint256 amount);\n}\n"
      },
      "contracts/ErrorReporter.sol": {
        "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.23;\n\ncontract ComptrollerErrorReporter {\n    enum Error {\n        NO_ERROR,\n        UNAUTHORIZED,\n        COMPTROLLER_MISMATCH,\n        INSUFFICIENT_SHORTFALL,\n        INSUFFICIENT_LIQUIDITY,\n        INVALID_CLOSE_FACTOR,\n        INVALID_COLLATERAL_FACTOR,\n        INVALID_LIQUIDATION_INCENTIVE,\n        MARKET_NOT_ENTERED, // no longer possible\n        MARKET_NOT_LISTED,\n        MARKET_ALREADY_LISTED,\n        MATH_ERROR,\n        NONZERO_BORROW_BALANCE,\n        PRICE_ERROR,\n        REJECTION,\n        SNAPSHOT_ERROR,\n        TOO_MANY_ASSETS,\n        TOO_MUCH_REPAY,\n        INVALID_MARKET_TYPE,\n        TOO_LITTLE_INTEREST_RESERVE,\n        NONZERO_INTEREST_BALANCE,\n        LIQUIDATE_SEIZE_TOO_LITTLE\n    }\n\n    enum FailureInfo {\n        ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\n        ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,\n        EXIT_MARKET_BALANCE_OWED,\n        EXIT_MARKET_REJECTION,\n        SET_CLOSE_FACTOR_OWNER_CHECK,\n        SET_CLOSE_FACTOR_VALIDATION,\n        SET_COLLATERAL_FACTOR_OWNER_CHECK,\n        SET_COLLATERAL_FACTOR_NO_EXISTS,\n        SET_COLLATERAL_FACTOR_VALIDATION,\n        SET_COLLATERAL_FACTOR_WITHOUT_PRICE,\n        SET_IMPLEMENTATION_OWNER_CHECK,\n        SET_LIQUIDATION_INCENTIVE_OWNER_CHECK,\n        SET_LIQUIDATION_INCENTIVE_VALIDATION,\n        SET_MAX_ASSETS_OWNER_CHECK,\n        SET_PENDING_ADMIN_OWNER_CHECK,\n        SET_PENDING_IMPLEMENTATION_OWNER_CHECK,\n        SET_PRICE_ORACLE_OWNER_CHECK,\n        SUPPORT_MARKET_EXISTS,\n        SUPPORT_MARKET_OWNER_CHECK,\n        SET_PAUSE_GUARDIAN_OWNER_CHECK\n    }\n\n    /**\n      * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\n      * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\n      **/\n    event Failure(uint error, uint info, uint detail);\n\n    error Unauthorized();\n    error InitializationFailed();\n\n    error GetAccountSnapshotFailed(uint256 errorCode);\n\n    error SeizePaused();\n    error MintPaused();\n    error BorrowPaused();\n    error CollectInterestPaused();\n    error PayInterestPaused();\n    error TransferPaused();\n\n    error InsufficientShortfall(uint errorCode, uint value);\n    error InvalidTopUpLimit();\n    error TopUpLimitExceeded();\n    error TopUpZero();\n    error SeizeFailed();\n    error TopUpFailed();\n    error LiquidateError();\n    error LiquidateSeizeTooLittle();\n    error LiquidateSeizeTooMuch();\n    error LiquidateSeizeBellowMinValue(uint minSeizedValue, uint liquidatedValueTotal);\n    error ExcessRefundFailed();\n    error BorrowCapReached();\n    error MarketAlreadyAdded();\n    error InvalidInput();\n    error OnlyAdminCanUnpause();\n    error ChangeNotAuthorized();\n\n    error MarketNotListed();\n    error SameMarket();\n    error WrongMarketType();\n    error PriceError();\n    error ComptrollerMismatch();\n    error InvalidMarket();\n\n    /**\n      * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\n      */\n    function fail(Error err, FailureInfo info) internal returns (uint) {\n        emit Failure(uint(err), uint(info), 0);\n\n        return uint(err);\n    }\n\n    /**\n      * @dev use this when reporting an opaque error from an upgradeable collaborator contract\n      */\n    function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\n        emit Failure(uint(err), uint(info), opaqueError);\n\n        return uint(err);\n    }\n}\n\ncontract TokenErrorReporter {\n    uint public constant NO_ERROR = 0; // support legacy return codes\n\n    error Unauthorized();\n    error Unsupported();\n\n    error AlreadyInitialized();\n    error InitializeExchangeRateInvalid();\n    error InitializeSetComptrollerFailed(uint256 errorCode);\n    error InitializeSetInterestRateModelFailed(uint256 errorCode);\n    error InitializeMarketTypeNotSet();\n    error InitializeInvalidMarketType();\n    error EnsureNonEmptyAmountTooSmall();\n\n    error TransferComptrollerRejection(uint256 errorCode);\n    error TransferNotAllowed();\n    error TransferNotEnough();\n    error TransferTooMuch();\n    error TransferInvalidAmount();\n\n    error TransferInFailed();\n    error InsufficientBalanceAfterTransfer();\n    error TransferOutFailed();\n    error TransferFailed();\n    error NftAmountTooHigh();\n    error NftNotFound(uint256 nftId);\n\n    error MintComptrollerRejection(uint256 errorCode);\n    error MintFreshnessCheck();\n\n    error RedeemComptrollerRejection(uint256 errorCode);\n    error RedeemFreshnessCheck();\n    error RedeemTransferOutNotPossible();\n    error RedeemInvalidInputs();\n    error RedeemTokensIsZero();\n\n    error BorrowComptrollerRejection(uint256 errorCode);\n    error BorrowFreshnessCheck();\n    error BorrowCashNotAvailable();\n\n    error RepayBorrowComptrollerRejection(uint256 errorCode);\n    error RepayBorrowFreshnessCheck();\n    error RepayTooHigh();\n\n    error LiquidateComptrollerRejection(uint256 errorCode);\n    error LiquidateFreshnessCheck();\n    error LiquidateCollateralFreshnessCheck();\n    error LiquidateAccrueBorrowInterestFailed(uint256 errorCode);\n    error LiquidateAccrueCollateralInterestFailed(uint256 errorCode);\n    error LiquidateLiquidatorIsBorrower();\n    error LiquidateCloseAmountIsZero();\n    error LiquidateCloseAmountIsUintMax();\n    error LiquidateRepayBorrowFreshFailed(uint256 errorCode);\n\n    error LiquidateSeizeComptrollerRejection(uint256 errorCode);\n    error LiquidateSeizeLiquidatorIsBorrower();\n\n    error AcceptAdminPendingAdminCheck();\n\n    error SetComptrollerOwnerCheck();\n    error SetPendingAdminOwnerCheck();\n\n    error SetReserveFactorAdminCheck();\n    error SetReserveFactorFreshCheck();\n    error SetReserveFactorBoundsCheck();\n\n    error AddReservesFactorFreshCheck(uint256 actualAddAmount);\n\n    error ReduceReservesAdminCheck();\n    error ReduceReservesFreshCheck();\n    error ReduceReservesCashNotAvailable();\n    error ReduceReservesCashValidation();\n\n    error SetInterestRateModelOwnerCheck();\n    error SetInterestRateModelFreshCheck();\n\n    error SetProtocolSeizeShareAdminCheck();\n    error SetProtocolSeizeShareTooHigh();\n\n    error BorrowRateIsAbsurdlyHigh(uint borrowRateMantissa);\n\n    error InvalidComptrollerAddress(address comptrollerAddress);\n    error InvalidRateModelAddress(address interestRateModelAddress);\n\n    error Reentry();\n\n    error CannotSweepUnderlying();\n\n    error CollectInterestFailed();\n    error CollectInterestNotAllowed();\n    error PayInterestNotAllowed();\n    error InsufficientBalance();\n    error PayInterestError();\n\n    error SenderMismatch();\n    error ValueMismatch();\n\n    error PriceError();\n}\n"
      }
    },
    "settings": {
      "evmVersion": "shanghai",
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "libraries": {
        "CErc20Delegator.sol": {}
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      }
    }
  }}