/
SupplyVaultUpgradeable.sol
117 lines (98 loc) · 4.18 KB
/
SupplyVaultUpgradeable.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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// SPDX-License-Identifier: GNU AGPLv3
pragma solidity ^0.8.0;
import "@contracts/compound/interfaces/compound/ICompound.sol";
import "@contracts/compound/interfaces/IMorpho.sol";
import {ERC20, SafeTransferLib} from "@solmate/utils/SafeTransferLib.sol";
import "@contracts/compound/libraries/CompoundMath.sol";
import "@contracts/compound/libraries/Types.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "../ERC4626UpgradeableSafe.sol";
/// @title SupplyVaultUpgradeable.
/// @author Morpho Labs.
/// @custom:contact security@morpho.xyz
/// @notice ERC4626-upgradeable Tokenized Vault abstract implementation for Morpho-Compound.
abstract contract SupplyVaultUpgradeable is ERC4626UpgradeableSafe, OwnableUpgradeable {
using SafeTransferLib for ERC20;
using CompoundMath for uint256;
/// STORAGE ///
IMorpho public morpho; // The main Morpho contract.
IComptroller public comptroller; // The Comptroller contract.
address public poolToken; // The pool token corresponding to the market to supply to through this vault.
ERC20 public comp;
/// UPGRADE ///
/// @dev Initializes the vault.
/// @param _morpho The address of the main Morpho contract.
/// @param _poolToken The address of the pool token corresponding to the market to supply through this vault.
/// @param _name The name of the ERC20 token associated to this tokenized vault.
/// @param _symbol The symbol of the ERC20 token associated to this tokenized vault.
/// @param _initialDeposit The amount of the initial deposit used to prevent pricePerShare manipulation.
function __SupplyVaultUpgradeable_init(
address _morpho,
address _poolToken,
string calldata _name,
string calldata _symbol,
uint256 _initialDeposit
) internal onlyInitializing returns (bool isEth, address wEth) {
ERC20 underlyingToken;
(isEth, wEth, underlyingToken) = __SupplyVaultUpgradeable_init_unchained(
_morpho,
_poolToken
);
__Ownable_init();
__ERC20_init(_name, _symbol);
__ERC4626UpgradeableSafe_init(ERC20Upgradeable(address(underlyingToken)), _initialDeposit);
}
/// @dev Initializes the vault whithout initializing parent contracts (avoid the double initialization problem).
/// @param _morpho The address of the main Morpho contract.
/// @param _poolToken The address of the pool token corresponding to the market to supply through this vault.
function __SupplyVaultUpgradeable_init_unchained(address _morpho, address _poolToken)
internal
onlyInitializing
returns (
bool isEth,
address wEth,
ERC20 underlyingToken
)
{
morpho = IMorpho(_morpho);
poolToken = _poolToken;
comptroller = morpho.comptroller();
comp = ERC20(comptroller.getCompAddress());
isEth = _poolToken == morpho.cEth();
wEth = morpho.wEth();
underlyingToken = ERC20(isEth ? wEth : ICToken(_poolToken).underlying());
underlyingToken.safeApprove(_morpho, type(uint256).max);
}
/// PUBLIC ///
function totalAssets() public view override returns (uint256) {
IMorpho morphoMem = morpho;
address poolTokenMem = poolToken;
Types.SupplyBalance memory supplyBalance = morphoMem.supplyBalanceInOf(
poolTokenMem,
address(this)
);
return
supplyBalance.onPool.mul(ICToken(poolTokenMem).exchangeRateStored()) +
supplyBalance.inP2P.mul(morphoMem.p2pSupplyIndex(poolTokenMem));
}
/// INTERNAL ///
function _deposit(
address _caller,
address _receiver,
uint256 _assets,
uint256 _shares
) internal virtual override {
super._deposit(_caller, _receiver, _assets, _shares);
morpho.supply(poolToken, address(this), _assets);
}
function _withdraw(
address _caller,
address _receiver,
address _owner,
uint256 _assets,
uint256 _shares
) internal virtual override {
morpho.withdraw(poolToken, _assets);
super._withdraw(_caller, _receiver, _owner, _assets, _shares);
}
}