tokenbridge-contracts/contracts/upgradeable_contracts/erc20_to_native/CompoundConnector.sol

102 lines
3.6 KiB
Solidity

pragma solidity 0.4.24;
import "./InterestConnector.sol";
import "../../interfaces/ICToken.sol";
import "../../interfaces/IComptroller.sol";
/**
* @title CompoundConnector
* @dev This contract allows to partially invest locked Dai tokens into Compound protocol.
*/
contract CompoundConnector is InterestConnector {
uint256 internal constant SUCCESS = 0;
/**
* @dev Tells the address of the DAI token in the Ethereum Mainnet.
*/
function daiToken() public pure returns (ERC20) {
return ERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F);
}
/**
* @dev Tells the address of the cDAI token in the Ethereum Mainnet.
*/
function cDaiToken() public pure returns (ICToken) {
return ICToken(0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643);
}
/**
* @dev Tells the address of the Comptroller contract in the Ethereum Mainnet.
*/
function comptroller() public pure returns (IComptroller) {
return IComptroller(0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B);
}
/**
* @dev Tells the address of the COMP token in the Ethereum Mainnet.
*/
function compToken() public pure returns (ERC20) {
return ERC20(0xc00e94Cb662C3520282E6f5717214004A7f26888);
}
/**
* @dev Tells the current earned interest amount.
* @param _token address of the underlying token contract.
* @return total amount of interest that can be withdrawn now.
*/
function interestAmount(address _token) public view returns (uint256) {
uint256 underlyingBalance = cDaiToken().balanceOfUnderlying(address(this));
// 1 DAI is reserved for possible truncation/round errors
uint256 invested = investedAmount(_token) + 1 ether;
return underlyingBalance > invested ? underlyingBalance - invested : 0;
}
/**
* @dev Tells if interest earning is supported for the specific token contract.
* @param _token address of the token contract.
* @return true, if interest earning is supported.
*/
function _isInterestSupported(address _token) internal pure returns (bool) {
return _token == address(daiToken());
}
/**
* @dev Invests the given amount of tokens to the Compound protocol.
* Converts _amount of TOKENs into X cTOKENs.
* @param _token address of the token contract.
* @param _amount amount of tokens to invest.
*/
function _invest(address _token, uint256 _amount) internal {
(_token);
daiToken().approve(address(cDaiToken()), _amount);
require(cDaiToken().mint(_amount) == SUCCESS);
}
/**
* @dev Withdraws at least the given amount of tokens from the Compound protocol.
* Converts X cTOKENs into _amount of TOKENs.
* @param _token address of the token contract.
* @param _amount minimal amount of tokens to withdraw.
*/
function _withdrawTokens(address _token, uint256 _amount) internal {
(_token);
require(cDaiToken().redeemUnderlying(_amount) == SUCCESS);
}
/**
* @dev Claims Comp token and transfers it to the associated interest receiver.
*/
function claimCompAndPay() external onlyEOA {
address[] memory holders = new address[](1);
holders[0] = address(this);
address[] memory markets = new address[](1);
markets[0] = address(cDaiToken());
comptroller().claimComp(holders, markets, false, true);
address comp = address(compToken());
uint256 interest = _selfBalance(comp);
require(interest >= minInterestPaid(comp));
_transferInterest(comp, interest);
}
}