---
tags: AIS
---
# Nextlend doc
```solidity
contract cToken {
// To construct cToken which contains lending logic
// @param name - name of cToken
// @param symbol - symbol of cToken
// @param decimals - decimals of cToken
// @param underlying - underlying token address
// @param initialExchangeRateMantissa - initial value of mantiss(TODO: describe more)
constructor(string memory name, string memory symbol, uint8 decimals, address underlying, uint256 initialExchangeRateMantissa);
// To connect another CToken Together
// @param address - address of another cToken that need to be added to market
// @return success status which always be true
function addToMarket(address CTokenAddress) external returns(bool);
// To disconnect another CToken from market
// @param address - address of another cToken that need to be removed from market
// @return success status which always be true
function removeFromMarket(address CTokenAddress) external returns(bool);
// To get market list
// @return market list
function readMarket() external view returns(address [] memory)
// Set token for incentive reward
// @param address - token address to be used as incentive
// @return success status
function setCompAddr(address newCompAddr) external returns(bool)
// Mint some token to contract
// @param mintAmount - amount of token to mint which have to be smaller or equal to aproval
// @return - sucess status or exceptions
function mint(uint256 mintAmount) external returns (bool)
// Redeem some amount of token
// @param redeemTokens - amount to redeem
// @return - success status
function redeem(uint256 redeemTokens) external returns (bool){
require(checkApproveCToken(msg.sender,redeemTokens));
uint256 underlyingToken = redeemTokens.div(getExchangeRate());
require(checkUnderlyingToken(underlyingToken));
require(checkAmountCToken(msg.sender,redeemTokens));
require(
getAllLiquidity(msg.sender).add((balances[msg.sender].sub(redeemTokens)).mul(getPrice()))*80/100 >= getAllBorrow(msg.sender)
);
tokenContract.transfer(msg.sender,underlyingToken);
calculateComp_redeem(balances[msg.sender]);
balances[msg.sender] = balances[msg.sender].sub(redeemTokens);
totalSupply_ = totalSupply_.sub(redeemTokens);
return true;
}
function redeemUnderlying(uint256 redeemTokens) external returns (bool){
require(checkApprove(msg.sender,redeemTokens));
uint256 cTokenAmount = redeemTokens.mul(getExchangeRate());
require(checkUnderlyingToken(redeemTokens));
require(checkAmountCToken(msg.sender,cTokenAmount));
tokenContract.transfer(msg.sender,redeemTokens);
calculateComp_redeem(balances[msg.sender]);
balances[msg.sender] = balances[msg.sender].sub(cTokenAmount);
totalSupply_ = totalSupply_.sub(cTokenAmount);
return true;
}
function calculateComp_mint(uint256 mintAmount) internal returns(bool){
uint256 CompAmount = calculateComp(startBlock[msg.sender],mintAmount);
Compbalances[msg.sender] = Compbalances[msg.sender].add(CompAmount);
uint currentblock = block.number;
startBlock[msg.sender] = currentblock;
return true;
}
function calculateComp_redeem(uint256 redeemAmount) internal returns(bool){
CompContract.transfer(msg.sender,(calculateComp(startBlock[msg.sender],redeemAmount)).div(1e18));
Compbalances[msg.sender] = Compbalances[msg.sender].sub(calculateComp(startBlock[msg.sender],redeemAmount));
startBlock[msg.sender] = block.number;
return true;
}
// To claim reward without withdrawing
function ClaimComp() external returns (bool){
if (balances[msg.sender]!=0){
calculateComp_redeem(balances[msg.sender]);
}
else{
if (borrowBalance[msg.sender]!=0){
calculateComp_repay(borrowBalance[msg.sender]);
}
}
return true;
}
// To get claimable reward
function getAvailableComp(address account) external view returns(uint256){
if (balances[account]!=0){
return (calculateComp(startBlock[account],balances[account])).div(1e18);
}
else{
if (borrowBalance[account]!=0){
return (calculateComp(borrowStartBlock[account],borrowBalance[account].mul(50))).div(1e18);
}
else{
return 0;
}
}
}
function setCToken(address CTokenAddress) external{
pairCToken_ = CTokenAddress;
CTokenContract = cTokenInterface(CTokenAddress);
}
// Borrow money form CToken
function borrow(uint256 borrowAmount) external returns (bool){
require(balances[msg.sender]==0);
require(
getAllLiquidity(msg.sender)*80/100 >= getAllBorrow(msg.sender).add((borrowBalance[msg.sender].add(borrowAmount)).mul(getPrice()*50))
);
tokenContract.transfer(msg.sender,borrowAmount);
borrowBalance[msg.sender] = borrowBalance[msg.sender].add(borrowAmount);
calculateComp_borrow(borrowAmount);
return true;
}
// Repay money to CToken
function repayBorrow(uint256 repayAmount) external returns (bool){
require(AllowRepayBorrow(msg.sender,repayAmount));
tokenContract.transferFrom(msg.sender,address(this),repayAmount);
calculateComp_repay(repayAmount);
borrowBalance[msg.sender] = borrowBalance[msg.sender].sub(repayAmount);
return true;
}
function calculateComp_borrow(uint256 borrowAmount) internal returns(bool){
uint256 CompAmount = calculateComp(borrowStartBlock[msg.sender],borrowAmount.mul(50));
borrowCompbalances[msg.sender] = borrowCompbalances[msg.sender].add(CompAmount);
uint currentblock = block.number;
borrowStartBlock[msg.sender] = currentblock;
return true;
}
function calculateComp_repay(uint256 repayAmount) internal returns(bool){
CompContract.transfer(msg.sender,(calculateComp(borrowStartBlock[msg.sender],repayAmount.mul(50))).div(1e18));
borrowCompbalances[msg.sender] = borrowCompbalances[msg.sender].sub(calculateComp(borrowStartBlock[msg.sender],repayAmount.mul(50)));
borrowStartBlock[msg.sender] = block.number;
return true;
}
function getAllLiquidity(address account) internal view returns(uint256){
cTokenInterface ctokenContract;
uint256 TotalLiquidity;
for (uint i = 0;i < MarketList.length;i++){
ctokenContract = cTokenInterface(MarketList[i]);
TotalLiquidity = TotalLiquidity.add(ctokenContract.liquidityOf(account));
}
return TotalLiquidity;
}
function getAllBorrow(address account) internal view returns(uint256){
cTokenInterface ctokenContract;
uint256 TotalBorrow;
for (uint i = 0;i < MarketList.length;i++){
ctokenContract = cTokenInterface(MarketList[i]);
TotalBorrow = TotalBorrow.add(ctokenContract.borrowOf(account));
}
return TotalBorrow;
}
function AllowRepayBorrow(address account, uint256 repayAmount) internal view returns(bool){
if (repayAmount > borrowBalance[account]){
return false;
}
else{
return true;
}
}
// check & set OraclePriceFeed
function setOraclePrice(address OracleAddress) external returns(address){
require(msg.sender == admin_);
OraclePriceFeed_ = OracleAddress;
}
function checkOraclePriceFeed() internal view returns(bool){
if (OraclePriceFeed_ == address(0)){
return false;
}
else{
return true;
}
}
// Set fixed price for CToken
function setPrice(uint index) external {
require(msg.sender == admin_);
//WBTC
if (index == 1){
price_ = 48000 * 1e9 / 50 ;
}
//WETH
else if (index == 2){
price_ = 3800 * 1e9 / 50;
}
//NXC
else if (index == 3){
price_ = 3 * 1e9 / 50;
}
//NXN
else if (index == 4){
price_ = 0.03 * 1e9 / 50;
}
//USDT
else{
price_ = 1 * 1e9 / 50;
}
}
function getPrice() public override view returns(uint256){
// This is price for CToken.
if (!checkOraclePriceFeed()){
return price_;
}
else{
oraclePricefeedInterface oraclePriceContract = oraclePricefeedInterface(OraclePriceFeed_);
return oraclePriceContract.getPrice();
}
}
function admin() external view returns (address){
return admin_;
}
// Set Comp distribution speed
function setCompSpeed(uint256 CompSpeed) external{
require(msg.sender == admin_);
CompSpeed_ = CompSpeed;
}
function getCompSpeed() external view returns(uint256){
return CompSpeed_;
}
function check(address account) external view returns(uint256){
return calculateComp(startBlock[account],balances[account]).div(1e18);
}
function getAmountNXC(uint256 blocks,uint256 amount) external view returns(uint256){
return amount.mul(getPrice()).mul(CompSpeed_).mul(blocks).div(1e9);
}
function getBlock() external view returns(uint256){
return block.number;
}
function calculateComp(uint initialblock,uint256 tokenAmount) internal view returns(uint256){
uint256 currentblock = block.number;
uint256 lengthPeriod = currentblock.sub(initialblock);
uint256 rate = (tokenAmount.mul(getPrice())).mul(CompSpeed_);
uint256 CompAmount = lengthPeriod.mul(rate);
return CompAmount;
}
event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
event Transfer(address indexed from, address indexed to, uint tokens);
mapping(address => uint256) balances;
mapping(address => mapping (address => uint256)) allowed;
mapping(address => uint256) Compbalances;
mapping(address => uint) startBlock;
mapping(address => uint) borrowStartBlock;
mapping(address => uint256) borrowCompbalances;
mapping(address => uint256) liquidity;
mapping(address => uint256) borrowBalance;
function borrowOf(address borrower) public override view returns (uint256){
return (borrowBalance[borrower].mul(getPrice()*50));
}
function liquidityOf(address account) public override view returns (uint256){
return (balances[account].mul(getPrice()));
}
function totalSupply() public override view returns (uint256) {
return totalSupply_;
}
function balanceOf(address tokenOwner) public override view returns (uint256) {
return balances[tokenOwner];
}
function transfer(address receiver, uint256 numTokens) public override returns (bool) {
require(numTokens <= balances[msg.sender]);
balances[msg.sender] = balances[msg.sender].sub(numTokens);
balances[receiver] = balances[receiver].add(numTokens);
emit Transfer(msg.sender, receiver, numTokens);
return true;
}
function approve(address delegate, uint256 numTokens) public override returns (bool) {
allowed[msg.sender][delegate] = numTokens;
emit Approval(msg.sender, delegate, numTokens);
return true;
}
function allowance(address owner, address delegate) public override view returns (uint) {
return allowed[owner][delegate];
}
function transferFrom(address owner, address buyer, uint256 numTokens) public override returns (bool) {
require(numTokens <= balances[owner]);
require(numTokens <= allowed[owner][msg.sender]);
balances[owner] = balances[owner].sub(numTokens);
allowed[owner][msg.sender] = allowed[owner][msg.sender].sub(numTokens);
balances[buyer] = balances[buyer].add(numTokens);
emit Transfer(owner, buyer, numTokens);
return true;
}
}
```