-
Notifications
You must be signed in to change notification settings - Fork 8
/
TreasuryCustodian.sol
88 lines (69 loc) · 2.87 KB
/
TreasuryCustodian.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
// SPDX-License-Identifier: AGPL-3.0
pragma solidity 0.8.15;
import {ERC20} from "solmate/tokens/ERC20.sol";
import {OlympusTreasury} from "src/modules/TRSRY.sol";
import "src/Kernel.sol";
// ERRORS
error PolicyStillActive();
error PolicyNotFound();
// Generic contract to allow authorized contracts to interact with treasury
// Use cases include setting and removing approvals, as well as allocating assets for yield
contract TreasuryCustodian is Policy {
/* ========== STATE VARIABLES ========== */
event ApprovalRevoked(address indexed policy_, ERC20[] tokens_);
// Modules
OlympusTreasury internal TRSRY;
/* ========== CONSTRUCTOR ========== */
constructor(Kernel kernel_) Policy(kernel_) {}
/* ========== FRAMEWORK CONFIGURATION ========== */
function configureDependencies() external override returns (Keycode[] memory dependencies) {
dependencies = new Keycode[](1);
dependencies[0] = toKeycode("TRSRY");
TRSRY = OlympusTreasury(getModuleAddress(dependencies[0]));
}
function requestPermissions() external view override returns (Permissions[] memory requests) {
Keycode TRSRY_KEYCODE = TRSRY.KEYCODE();
requests = new Permissions[](2);
requests[0] = Permissions(TRSRY_KEYCODE, TRSRY.setApprovalFor.selector);
requests[1] = Permissions(TRSRY_KEYCODE, TRSRY.setDebt.selector);
}
function grantApproval(
address for_,
ERC20 token_,
uint256 amount_
) external onlyRole("custodian") {
TRSRY.setApprovalFor(for_, token_, amount_);
}
// Anyone can call to revoke a deactivated policy's approvals.
// TODO Currently allows anyone to revoke any approval EXCEPT activated policies.
// TODO must reorg policy storage to be able to check for deactivated policies.
function revokePolicyApprovals(address policy_, ERC20[] memory tokens_) external {
if (Policy(policy_).isActive()) revert PolicyStillActive();
// TODO Make sure `policy_` is an actual policy and not a random address.
uint256 len = tokens_.length;
for (uint256 j; j < len; ) {
TRSRY.setApprovalFor(policy_, tokens_[j], 0);
unchecked {
++j;
}
}
emit ApprovalRevoked(policy_, tokens_);
}
// Debt admin functions for authorized addresses to manipulate debt in special cases
function increaseDebt(
ERC20 token_,
address debtor_,
uint256 amount_
) external onlyRole("custodian") {
uint256 debt = TRSRY.reserveDebt(token_, debtor_);
TRSRY.setDebt(token_, debtor_, debt + amount_);
}
function decreaseDebt(
ERC20 token_,
address debtor_,
uint256 amount_
) external onlyRole("custodian") {
uint256 debt = TRSRY.reserveDebt(token_, debtor_);
TRSRY.setDebt(token_, debtor_, debt - amount_);
}
}