dsa-connectors/contracts/mainnet/connectors/refinance/helpers/compound.sol
2021-06-25 01:25:04 +05:30

160 lines
4.9 KiB
Solidity

pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
import { protocolHelpers } from "../helpers.sol";
import {
ComptrollerInterface,
CTokenInterface,
CompoundMappingInterface,
CETHInterface
} from "../interfaces.sol";
import { TokenInterface } from "../../../common/interfaces.sol";
contract CompoundHelpers is protocolHelpers {
struct CompoundBorrowData {
uint length;
uint fee;
Protocol target;
CTokenInterface[] ctokens;
TokenInterface[] tokens;
uint[] amts;
uint[] rateModes;
}
function _compEnterMarkets(uint length, CTokenInterface[] memory ctokens) internal {
ComptrollerInterface troller = ComptrollerInterface(getComptrollerAddress);
address[] memory _cTokens = new address[](length);
for (uint i = 0; i < length; i++) {
_cTokens[i] = address(ctokens[i]);
}
troller.enterMarkets(_cTokens);
}
function _compBorrowOne(
uint fee,
CTokenInterface ctoken,
TokenInterface token,
uint amt,
Protocol target,
uint rateMode
) internal returns (uint) {
if (amt > 0) {
address _token = address(token) == wethAddr ? ethAddr : address(token);
if (amt == uint(-1)) {
amt = getMaxBorrow(target, address(token), ctoken, rateMode);
}
(uint feeAmt, uint _amt) = calculateFee(amt, fee, true);
require(ctoken.borrow(_amt) == 0, "borrow-failed-collateral?");
transferFees(_token, feeAmt);
}
return amt;
}
function _compBorrow(
CompoundBorrowData memory data
) internal returns (uint[] memory) {
uint[] memory finalAmts = new uint[](data.length);
for (uint i = 0; i < data.length; i++) {
finalAmts[i] = _compBorrowOne(
data.fee,
data.ctokens[i],
data.tokens[i],
data.amts[i],
data.target,
data.rateModes[i]
);
}
return finalAmts;
}
function _compDepositOne(uint fee, CTokenInterface ctoken, TokenInterface token, uint amt) internal {
if (amt > 0) {
address _token = address(token) == wethAddr ? ethAddr : address(token);
(uint feeAmt, uint _amt) = calculateFee(amt, fee, false);
if (_token != ethAddr) {
approve(token, address(ctoken), _amt);
require(ctoken.mint(_amt) == 0, "deposit-failed");
} else {
CETHInterface(address(ctoken)).mint{value:_amt}();
}
transferFees(_token, feeAmt);
}
}
function _compDeposit(
uint length,
uint fee,
CTokenInterface[] memory ctokens,
TokenInterface[] memory tokens,
uint[] memory amts
) internal {
for (uint i = 0; i < length; i++) {
_compDepositOne(fee, ctokens[i], tokens[i], amts[i]);
}
}
function _compWithdrawOne(CTokenInterface ctoken, TokenInterface token, uint amt) internal returns (uint) {
if (amt > 0) {
if (amt == uint(-1)) {
bool isEth = address(token) == wethAddr;
uint initalBal = isEth ? address(this).balance : token.balanceOf(address(this));
require(ctoken.redeem(ctoken.balanceOf(address(this))) == 0, "withdraw-failed");
uint finalBal = isEth ? address(this).balance : token.balanceOf(address(this));
amt = sub(finalBal, initalBal);
} else {
require(ctoken.redeemUnderlying(amt) == 0, "withdraw-failed");
}
}
return amt;
}
function _compWithdraw(
uint length,
CTokenInterface[] memory ctokens,
TokenInterface[] memory tokens,
uint[] memory amts
) internal returns(uint[] memory) {
uint[] memory finalAmts = new uint[](length);
for (uint i = 0; i < length; i++) {
finalAmts[i] = _compWithdrawOne(ctokens[i], tokens[i], amts[i]);
}
return finalAmts;
}
function _compPaybackOne(CTokenInterface ctoken, TokenInterface token, uint amt) internal returns (uint) {
if (amt > 0) {
if (amt == uint(-1)) {
amt = ctoken.borrowBalanceCurrent(address(this));
}
if (address(token) != wethAddr) {
approve(token, address(ctoken), amt);
require(ctoken.repayBorrow(amt) == 0, "repay-failed.");
} else {
CETHInterface(address(ctoken)).repayBorrow{value:amt}();
}
}
return amt;
}
function _compPayback(
uint length,
CTokenInterface[] memory ctokens,
TokenInterface[] memory tokens,
uint[] memory amts
) internal {
for (uint i = 0; i < length; i++) {
_compPaybackOne(ctokens[i], tokens[i], amts[i]);
}
}
}