forked from compound-finance/compound-protocol
/
CErc20PluginDelegate.sol
97 lines (79 loc) · 2.74 KB
/
CErc20PluginDelegate.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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
pragma solidity ^0.5.16;
pragma experimental ABIEncoderV2;
import "./CErc20Delegate.sol";
import "./EIP20Interface.sol";
import "./IERC4626.sol";
/**
* @title Rari's CErc20Plugin's Contract
* @notice CToken which outsources token logic to a plugin
* @author Joey Santoro
*
* CErc20PluginDelegate deposits and withdraws from a plugin conract
* It is also capable of delegating reward functionality to a PluginRewardsDistributor
*/
contract CErc20PluginDelegate is CErc20Delegate {
/**
* @notice Plugin address
*/
IERC4626 public plugin;
uint256 constant public PRECISION = 1e18;
/**
* @notice Delegate interface to become the implementation
* @param data The encoded arguments for becoming
*/
function _becomeImplementation(bytes calldata data) external {
require(msg.sender == address(this) || hasAdminRights());
(address _plugin) = abi.decode(
data,
(address)
);
require(_plugin != address(0), "0");
if (address(plugin) != address(0) && plugin.balanceOf(address(this)) != 0) {
plugin.redeem(plugin.balanceOf(address(this)), address(this), address(this));
}
plugin = IERC4626(_plugin);
EIP20Interface(underlying).approve(_plugin, uint256(-1));
uint256 amount = EIP20Interface(underlying).balanceOf(address(this));
if (amount != 0) {
deposit(amount);
}
}
/*** CToken Overrides ***/
/*** Safe Token ***/
/**
* @notice Gets balance of the plugin in terms of the underlying
* @return The quantity of underlying tokens owned by this contract
*/
function getCashPrior() internal view returns (uint256) {
return plugin.previewRedeem(plugin.balanceOf(address(this)));
}
/**
* @notice Transfer the underlying to the cToken and trigger a deposit
* @param from Address to transfer funds from
* @param amount Amount of underlying to transfer
* @return The actual amount that is transferred
*/
function doTransferIn(
address from,
uint256 amount
) internal returns (uint256) {
// Perform the EIP-20 transfer in
require(EIP20Interface(underlying).transferFrom(from, address(this), amount), "send");
deposit(amount);
return amount;
}
function deposit(uint256 amount) internal {
plugin.deposit(amount, address(this));
}
/**
* @notice Transfer the underlying from plugin to destination
* @param to Address to transfer funds to
* @param amount Amount of underlying to transfer
*/
function doTransferOut(
address payable to,
uint256 amount
) internal {
plugin.withdraw(amount, to, address(this));
}
}