/
CompoundAllocationStrategy.sol
62 lines (52 loc) · 2.45 KB
/
CompoundAllocationStrategy.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
pragma solidity ^0.5.8;
import {IAllocationStrategy} from "./IAllocationStrategy.sol";
import {Ownable} from "openzeppelin-solidity/contracts/ownership/Ownable.sol";
import {IERC20} from "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
import {CErc20Interface} from "../compound/contracts/CErc20Interface.sol";
contract CompoundAllocationStrategy is IAllocationStrategy, Ownable {
CErc20Interface private cToken;
IERC20 private token;
constructor(CErc20Interface cToken_) public {
cToken = cToken_;
token = IERC20(cToken.underlying());
}
/// @dev ISavingStrategy.underlying implementation
function underlying() external view returns (address) {
return cToken.underlying();
}
/// @dev ISavingStrategy.exchangeRateStored implementation
function exchangeRateStored() external view returns (uint256) {
return cToken.exchangeRateStored();
}
/// @dev ISavingStrategy.accrueInterest implementation
function accrueInterest() external returns (bool) {
return cToken.accrueInterest() == 0;
}
/// @dev ISavingStrategy.investUnderlying implementation
function investUnderlying(uint256 investAmount) external onlyOwner returns (uint256) {
token.transferFrom(msg.sender, address(this), investAmount);
token.approve(address(cToken), investAmount);
uint256 cTotalBefore = cToken.totalSupply();
// TODO should we handle mint failure?
require(cToken.mint(investAmount) == 0, "mint failed");
uint256 cTotalAfter = cToken.totalSupply();
uint256 cCreatedAmount;
if (cTotalAfter > cTotalBefore) {
cCreatedAmount = cTotalAfter - cTotalBefore;
} // else can there be case that we mint but we get less cTokens!?\
return cCreatedAmount;
}
/// @dev ISavingStrategy.redeemUnderlying implementation
function redeemUnderlying(uint256 redeemAmount) external onlyOwner returns (uint256) {
uint256 cTotalBefore = cToken.totalSupply();
// TODO should we handle redeem failure?
require(cToken.redeemUnderlying(redeemAmount) == 0, "redeemUnderlying failed");
uint256 cTotalAfter = cToken.totalSupply();
uint256 cBurnedAmount;
if (cTotalAfter < cTotalBefore) {
cBurnedAmount = cTotalBefore - cTotalAfter;
} // else can there be case that we end up with more cTokens ?!
token.transfer(msg.sender, redeemAmount);
return cBurnedAmount;
}
}