Science | Compound cToken and related core functions

All assets supported by the DeFi Co., Ltd. Compound are packaged and integrated through cToken smart contracts. Users can provide assets to the agreement by casting tokens (cToken), and then you can earn as long as you hold cToken. Interest, and when you choose to redeem, each cToken can be converted into the corresponding underlying asset.

It can be said that cToken is the main way to interact with the Compound protocol. Each cToken contract creates its own currency market, and when users coin, redeem, borrow, repay, refinance, or transfer cToken, they will use the cToken contract.

Currently, the Compound protocol has two types of cToken: CErc20 and CEther, where CErc20 encapsulates the ERC-20 asset and CEther encapsulates the Ethereum.

4

(7 types of cToken and corresponding contract addresses supported by the current Compound protocol)

In this article, we will understand the core functions of the Compound protocol:

  1. Mint
  2. Redeem (redemption);
  3. Redeem Underlying (redemption of underlying assets);
  4. Borrow (borrowing);
  5. Repay Borrow (repayment of loan);
  6. Repay Borrow Behalf;
  7. Liquidate Borrow (liquidation borrowing);
  8. accident details
  9. Exchange Rate (exchange rate);
  10. Get Cash (Get Cash);
  11. Total Borrow (total borrowing);
  12. Borrow Balance (borrowing balance);
  13. Borrow Rate
  14. Total Supply (total supply);
  15. Supply Balance
  16. Supply Balance Underlying;
  17. Supply Rate
  18. Total Reserves;
  19. Reserve Factor

1. Mint (Mint)

The Mint function is responsible for transferring assets to the money market, which calculates interest based on the current supply rate of the asset. The amount of tokens cast is based on the number of underlying assets provided by the user divided by the current exchange rate.

Mint is equivalent to the supply source of the Compound agreement.

CErc20

function mint(uint mintAmount) returns (uint) 
  1. msg.sender : An account that provides assets and has a cast cToken;
  2. mintAmount : the amount of coinage in units of base assets;
  3. RETURN : return 0 for success, others are error codes;

Before providing an asset, the user must first approve cToken to access their token balance;

CEther

 function mint() payable 
  1. msg.value (payable): the amount to be provided in Ether, in wei;
  2. msg.sender : an account that provides msg.sender and has a cast cToken;
  3. RETURN : No return, restore when an error occurs;

Solidity

 Erc20 underlying = Erc20(0xToken...); // get a handle for the underlying asset contract CErc20 cToken = CErc20(0x3FDA...); // get a handle for the corresponding cToken contract underlying.approve(address(cToken), 100); // approve the transfer assert(cToken.mint(100) == 0); // mint the cTokens and assert there is no error 

Web3 1.0

 const cToken = CEther.at(0x3FDB...); await cToken.methods.mint().send({from: myAccount, value: 50}); 

2, redemption

The redemption function is responsible for transferring the underlying assets from the money market to the user to exchange the previously cast cToken. The base asset redemption amount is calculated by multiplying the number of cTokens by the current exchange rate. The redemption amount must be less than the liquidity of the user's account and the available liquidity of the market.

Redemption is equivalent to the exit function of the Compound protocol.

CErc20 / CEther

 function redeem(uint redeemTokens) returns (uint) 
  1. msg.sender : redemption of funds transfer account;
  2. redeemTokens : the number of cTokens to redeem;
  3. RETURN : Return 0 for success, others are error codes;

Solidity

 CEther cToken = CEther(0x3FDB...); require(cToken.redeem(7) == 0, "something went wrong"); 

Web3 1.0

 const cToken = CErc20.at(0x3FDA...); cToken.methods.redeem(1).send({from: ...}); 

3. Redeem the basic assets

The redemption of the underlying asset function is responsible for transferring the underlying asset from the money market to the user in exchange for the previously cast CToken. The amount redeemed by cToken is the amount of the underlying asset divided by the current exchange rate. The redemption amount must be less than the liquidity of the user's account and the available liquidity of the market.

CErc20 / CEther

 function redeemUnderlying(uint redeemAmount) returns (uint) 
  1. msg.sender : redemption of funds transfer account;
  2. redeemAmount : the amount of the underlying asset to be redeemed;
  3. RETURN : Return 0 for success, others are error codes;

Solidity

 CEther cToken = CEther(0x3FDB...); require(cToken.redeemUnderlying(50) == 0, "something went wrong"); 

Web3 1.0

 const cToken = CErc20.at(0x3FDA...); cToken.methods.redeemUnderlying(10).send({from: ...}); 

4. Borrowing

The borrowing function is responsible for transferring assets from the money market to the user and creating a loan balance that accrues interest based on the borrowing rate of the asset.

The amount of the loan must be less than the user's ability to borrow and the available liquidity of the market. Users must maintain a collateral requirement to avoid liquidation.

Please note that the borrower will receive a basic asset transaction. For CEther, this will be Ethereum, so the borrower must be reimbursable.

CErc20 / CEther

 function borrow(uint borrowAmount) returns (uint) 
  1. msg.sender : loan transfer account;
  2. borrowAmount : the amount of the underlying asset to be borrowed;
  3. RETURN : return 0 for success, others are error codes;

Solidity

 CErc20 cToken = CErc20(0x3FDA...); require(cToken.borrow(100) == 0, "got collateral?"); 

Web3 1.0

 const cToken = CEther.at(0x3FDB...); await cToken.methods.borrow(50).send({from: 0xMyAccount}); 

5. Repayment of loans

The repayment function is responsible for transferring assets to the money market to reduce the user's loan balance.

CErc20

 function repayBorrow(uint repayAmount) returns (uint) 
  1. msg.sender : an account that borrows assets and should repay the loan;
  2. repayAmount : The amount of the loan assets to be repaid, the value -1 (ie 2^256 -1) can be used to repay the full amount;
  3. RETURN : Return 0 for success, others are error codes;

Before providing an asset, the user must first approve cToken to access their token balance;

CEther

 function repayBorrow() payable 
  1. msg.value (payable): The amount of Ether repaid, in wei;
  2. msg.sender : an account that borrows assets and should repay the loan;
  3. RETURN : No return, restore when an error occurs;

Solidity

 CEther cToken = CEther(0x3FDB...); require(cToken.repayBorrow.value(100)() == 0, "transfer approved?"); 

Web3 1.0

 const cToken = CErc20.at(0x3FDA...); cToken.methods.repayBorrow(10000).send({from: ...}); 

6. Reimbursement of Borrow Behalf

The repayment function is responsible for transferring assets to the money market to reduce the user's loan balance.

CErc20

 function repayBorrowBehalf(address borrower, uint repayAmount) returns (uint) 
  1. msg.sender : the account that should be repaid;
  2. borrower : an account that borrows assets to be repaid;
  3. repayAmount : The amount of the loan assets to be repaid, the value -1 (ie 2^256 -1) can be used to repay the full amount;
  4. RETURN : Return 0 for success, others are error codes;

Before providing an asset, the user must first approve cToken to access their token balance;

CEther

 function repayBorrowBehalf(address borrower) payable 
  1. msg.value (payable): The amount of Ether repaid, in wei;
  2. msg.sender : the account that should be repaid;
  3. borrower : an account that borrows assets;
  4. RETURN : No return, restore when an error occurs;

Solidity

 CEther cToken = CEther(0x3FDB...); require(cToken.repayBorrowBehalf.value(100)(0xBorrower) == 0, "transfer approved?"); 

Web3 1.0

 const cToken = CErc20.at(0x3FDA...); await cToken.methods.repayBorrowBehalf(0xBorrower, 10000).send({from: 0xPayer}); 

7. Liquidation of loans

Users with negative account liquidity will be liquidated by other users of the agreement to restore their account liquidity to positive (ie, above collateral requirements). When liquidation occurs, the liquidator may repay part or all of the outstanding loan on behalf of the borrower. In return, the liquidator may obtain the collateral held by the borrower, which is defined as a liquidation incentive.

The liquidator may settle a fixed percentage of any outstanding borrowings of the “liquidation account” (ie, an account below the collateral requirements). Unlike v1, the liquidator must interact with each cToken contract, in which they wish to repay the loan and seize another asset as collateral. When the collateral is seized, the liquidator is transferred to cToken, and they can redeem the collateral as if they had provided the asset themselves. Users must approve each cToken contract before they can transfer funds to the contract before they can be liquidated.

CErc20

 function liquidateBorrow(address borrower, uint amount, address collateral) returns (uint) 
  1. msg.sender : Clearing the borrower's account by repaying the debt and seizing the collateral;
  2. borrower : an account that is liquidated for account liquidity;
  3. repayAmount : the amount of the loan to be repaid in units of the underlying borrowing assets;
  4. cTokenCollateral : The cToken address held by the borrower that the liquidator should seize;
  5. RETURN : Return 0 for success, others are error codes;

Before providing an asset, the user must first approve cToken to access their token balance;

CEther

 function liquidateBorrow(address borrower, address cTokenCollateral) payable 
  1. msg.value (payable): the msg.value to be repaid and converted into collateral, in wei;
  2. msg.sender : used to liquidate the borrower's account by repaying the debt and seizing the collateral;
  3. borrower : an account that is liquidated for account liquidity;
  4. cTokenCollateral : The cToken address that the liquidator should hold as the collateral currently held by the borrower;
  5. RETURN : No return, restore when an error occurs;

Solidity

 CEther cToken = CEther(0x3FDB...); CErc20 cTokenCollateral = CErc20(0x3FDA...); require(cToken.liquidateBorrow.value(100)(0xBorrower, cTokenCollateral) == 0, "borrower underwater??"); 

Web3 1.0

 const cToken = CErc20.at(0x3FDA...); const cTokenCollateral = CEther.at(0x3FDB...); await cToken.methods.liquidateBorrow(0xBorrower, 33, cTokenCollateral).send({from: 0xLiquidator}); 

8, fault information

455556

9, exchange rate

As the market interest increases, each cToken can be converted into a (growth) base asset. The exchange rate between cToken and the underlying asset is equal to:

 exchangeRate = (getCash() + totalBorrows() - totalReserves()) / totalSupply() 

CErc20 / CEther

 function exchangeRateCurrent() returns (uint) 

RETURN : The current exchange rate is an unsigned integer, scaled by 1e18.

Solidity

 CErc20 cToken = CToken(0x3FDA...); uint exchangeRateMantissa = cToken.exchangeRateCurrent(); 

Web3 1.0

 const cToken = CEther.at(0x3FDB...); const exchangeRate = (await cToken.methods.exchangeRateCurrent().call()) / 1e18; 

Hint: Note that calling this function from outside the chain using call and send will not incur the cost of gas.

10, Get Cash

Cash is the balance of the underlying assets owned by the cToken contract. People can check the total amount of cash currently available in this market.

CErc20 / CEther

 function getCash() returns (uint) 

RETURN : The number of underlying assets owned by the contract.

Solidity

 CErc20 cToken = CToken(0x3FDA...); uint cash = cToken.getCash(); 

Web3 1.0

 const cToken = CEther.at(0x3FDB...); const cash = (await cToken.methods.getCash().call()); 

11. Total borrowings

The total amount of borrowing refers to the total amount of the underlying assets currently borrowed by the market, plus the corresponding amount of interest.

CErc20 / CEther

 function totalBorrowsCurrent() returns (uint) 

RETURN : Total amount of base assets borrowed with interest;

Solidity

 CErc20 cToken = CToken(0x3FDA...); uint borrows = cToken.totalBorrowsCurrent(); 

Web3 1.0

 const cToken = CEther.at(0x3FDB...); const borrows = (await cToken.methods.totalBorrowsCurrent().call()); 

12. Loan balance

Users borrowed from the agreement will pay accrued interest based on the current borrowing rate. Interest is calculated cumulatively for each block, and we can use this function to get the current value of the user (with interest) loan balance;

CErc20 / CEther

 function borrowBalanceCurrent(address account) returns (uint) 
  1. account : an account that borrows assets;
  2. RETURN : User's current underlying asset loan balance (including interest);

Solidity

 CErc20 cToken = CToken(0x3FDA...); uint borrows = cToken.borrowBalanceCurrent(msg.caller); 

Web3 1.0

 const cToken = CEther.at(0x3FDB...); const borrows = await cToken.methods.borrowBalanceCurrent(account).call(); 

13. Borrowing interest rate

At any time, people can check the contract to get the current borrowing rate for each block.

CErc20 / CEther

 function borrowRatePerBlock() returns (uint) 

RETURN: The current borrowing rate is an unsigned integer, scaled by 1e18.

Solidity

 CErc20 cToken = CToken(0x3FDA...); uint borrowRateMantissa = cToken.borrowRatePerBlock(); 

Web3 1.0

 const cToken = CEther.at(0x3FDB...); const borrowRate = (await cToken.methods.borrowRatePerBlock().call()) / 1e18; 

14, total supply

The so-called total supply refers to the number of tokens currently circulating in this cToken market. It is part of the cToken contract EIP-20 interface.

CErc20 / CEther

 function totalSupply() returns (uint) 

RETURN : The total number of tokens in the market.

Solidity

 CErc20 cToken = CToken(0x3FDA...); uint tokens = cToken.totalSupply(); 

Web3 1.0

 const cToken = CEther.at(0x3FDB...); const tokens = (await cToken.methods.totalSupply().call()); 

15, supply balance

Users who provide assets to the agreement will receive interest tokens as compensation. At any given time, we can use the exchange rate to check the value of the interest-bearing token. We can also query the number of tokens owned by a particular user, which is part of the cToken contract EIP-20 interface.

CErc20 / CEther

 function balanceOf(address account) returns (uint) 
  1. account : the account for obtaining the token balance;
  2. RETURN : The number of tokens currently owned by the account;

Solidity

 CErc20 cToken = CToken(0x3FDA...); uint tokens = cToken.balanceOf(msg.caller); 

Web3 1.0

 const cToken = CEther.at(0x3FDB...); const tokens = await cToken.methods.balanceOf(account).call(); 

16. Balance of basic assets supply

CToken also has a convenient way to determine the supply balance based on the underlying asset amount (ie, the supply balance multiplied by the exchange rate).

CErc20 / CEther

 function balanceOfUnderlying(address account) returns (uint) 
  1. account : The account for which the balance of the underlying asset is to be obtained;
  2. RETURN : The amount of the underlying asset currently owned by the account;

Solidity

 CErc20 cToken = CToken(0x3FDA...); uint tokens = cToken.balanceOfUnderlying(msg.caller); 

Web3 1.0

 const cToken = CEther.at(0x3FDB...); const tokens = await cToken.methods.balanceOfUnderlying(account).call(); 

17, supply rate

At any time, people can check the contract to get the current supply rate for each block. The supply rate is derived from the borrowing rate, the reserve ratio, and the total borrowings.

CErc20 / CEther

 function supplyRatePerBlock() returns (uint) 

RETURN : The current supply rate is an unsigned integer, scaled by 1e18.

Solidity

 CErc20 cToken = CToken(0x3FDA...); uint supplyRateMantissa = cToken.supplyRatePerBlock(); 

Web3 1.0

 const cToken = CEther.at(0x3FDB...); const supplyRate = (await cToken.methods.supplyRatePerBlock().call()) / 1e18; 

18. Total reserves

The reserve is an interest in the agreement itself to fund its operations. The reserve also forms part of the cash that can be used to lend to borrowers in the market. A small portion of the interest of the borrower is included in the agreement, which is determined by the reserve ratio.

CErc20 / CEther

 function totalReserves() returns (uint) 

RETURN : The total amount of reserves held by the agreement;

Solidity

 CErc20 cToken = CToken(0x3FDA...); uint reserves = cToken.totalReserves(); 

Web3 1.0

 const cToken = CEther.at(0x3FDB...); const reserves = (await cToken.methods.totalReserves().call()); 

19. Reserve rate

The reserve ratio defines a small portion of interest that should be included in the reserve.

CErc20 / CEther

 function reserveFactorMantissa() returns (uint) 

RETURN : The current reserve rate is an unsigned integer, scaled by 1e18.

Solidity

 CErc20 cToken = CToken(0x3FDA...); uint reserveFactorMantissa = cToken.reserveFactorMantissa(); 

Web3 1.0

 const cToken = CEther.at(0x3FDB...); const reserveFactor = (await cToken.methods.reserveFactorMantissa().call()) / 1e18;