This repository has been archived by the owner on Jun 28, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 47
/
Copy pathWorkshopVault.sol
141 lines (117 loc) · 4.73 KB
/
WorkshopVault.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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.19;
import "openzeppelin/token/ERC20/extensions/ERC4626.sol";
import "evc/interfaces/IEthereumVaultConnector.sol";
import "evc/interfaces/IVault.sol";
import "./IWorkshopVault.sol";
contract WorkshopVault is ERC4626, IVault, IWorkshopVault {
IEVC internal immutable evc;
constructor(
IEVC _evc,
IERC20 _asset,
string memory _name,
string memory _symbol
) ERC4626(_asset) ERC20(_name, _symbol) {
evc = _evc;
}
// [ASSIGNMENT]: what is the purpose of this modifier?
modifier callThroughEVC() {
if (msg.sender == address(evc)) {
_;
} else {
bytes memory result = evc.call(address(this), msg.sender, 0, msg.data);
assembly {
return(add(32, result), mload(result))
}
}
}
// [ASSIGNMENT]: why the account status check might not be necessary in certain situations?
// [ASSIGNMENT]: is the vault status check always necessary? why?
modifier withChecks(address account) {
_;
if (account == address(0)) {
evc.requireVaultStatusCheck();
} else {
evc.requireAccountAndVaultStatusCheck(account);
}
}
// [ASSIGNMENT]: can this function be used to authenticate the account for the sake of the borrow-related
// operations? why?
// [ASSIGNMENT]: if the answer to the above is "no", how this function could be modified to allow safe borrowing?
function _msgSender() internal view virtual override returns (address) {
if (msg.sender == address(evc)) {
(address onBehalfOfAccount,) = evc.getCurrentOnBehalfOfAccount(address(0));
return onBehalfOfAccount;
} else {
return msg.sender;
}
}
// IVault
// [ASSIGNMENT]: why this function is necessary? is it safe to unconditionally disable the controller?
function disableController() external {
evc.disableController(_msgSender());
}
// [ASSIGNMENT]: provide a couple use cases for this function
function checkAccountStatus(
address account,
address[] calldata collaterals
) public virtual returns (bytes4 magicValue) {
require(msg.sender == address(evc), "only evc can call this");
require(evc.areChecksInProgress(), "can only be called when checks in progress");
// some custom logic evaluating the account health
return IVault.checkAccountStatus.selector;
}
// [ASSIGNMENT]: provide a couple use cases for this function
function checkVaultStatus() public virtual returns (bytes4 magicValue) {
require(msg.sender == address(evc), "only evc can call this");
require(evc.areChecksInProgress(), "can only be called when checks in progress");
// some custom logic evaluating the vault health
// [ASSIGNMENT]: what can be done if the vault status check needs access to the initial state of the vault in
// order to evaluate the vault health?
return IVault.checkVaultStatus.selector;
}
function deposit(
uint256 assets,
address receiver
) public virtual override callThroughEVC withChecks(address(0)) returns (uint256 shares) {
return super.deposit(assets, receiver);
}
function mint(
uint256 shares,
address receiver
) public virtual override callThroughEVC withChecks(address(0)) returns (uint256 assets) {
return super.mint(shares, receiver);
}
function withdraw(
uint256 assets,
address receiver,
address owner
) public virtual override callThroughEVC withChecks(owner) returns (uint256 shares) {
return super.withdraw(assets, receiver, owner);
}
function redeem(
uint256 shares,
address receiver,
address owner
) public virtual override callThroughEVC withChecks(owner) returns (uint256 assets) {
return super.redeem(shares, receiver, owner);
}
function transfer(
address to,
uint256 value
) public virtual override (ERC20, IERC20) callThroughEVC withChecks(_msgSender()) returns (bool) {
return super.transfer(to, value);
}
function transferFrom(
address from,
address to,
uint256 value
) public virtual override (ERC20, IERC20) callThroughEVC withChecks(from) returns (bool) {
return super.transferFrom(from, to, value);
}
// IWorkshopVault
function borrow(uint256 assets, address receiver) external {}
function repay(uint256 assets, address receiver) external {}
function pullDebt(address from, uint256 assets) external returns (bool) {}
function liquidate(address violator, address collateral) external {}
}