-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathPoolStore.sol
185 lines (147 loc) · 6.79 KB
/
PoolStore.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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.17;
import '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';
import './Roles.sol';
/// @title PoolStore
/// @notice Persistent storage for Pool.sol
contract PoolStore is Roles {
// Libraries
using SafeERC20 for IERC20;
// Constants
uint256 public constant BPS_DIVIDER = 10000;
uint256 public constant MAX_POOL_WITHDRAWAL_FEE = 500; // in bps = 5%
// State variables
uint256 public feeShare = 500;
uint256 public bufferPayoutPeriod = 7 days;
mapping(address => uint256) private clpSupply; // asset => clp supply
mapping(address => uint256) private balances; // asset => balance
mapping(address => mapping(address => uint256)) private userClpBalances; // asset => account => clp amount
mapping(address => uint256) private bufferBalances; // asset => balance
mapping(address => uint256) private lastPaid; // asset => timestamp
mapping(address => uint256) private withdrawalFees; // asset => bps
constructor(RoleStore rs) Roles(rs) {}
/// @notice Set pool fee
/// @dev Only callable by governance
/// @param bps fee share in bps
function setFeeShare(uint256 bps) external onlyGov {
require(bps < BPS_DIVIDER, '!bps');
feeShare = bps;
}
/// @notice Set buffer payout period
/// @dev Only callable by governance
/// @param period Buffer payout period in seconds, default is 7 days (604800 seconds)
function setBufferPayoutPeriod(uint256 period) external onlyGov {
require(period > 0, '!period');
bufferPayoutPeriod = period;
}
/// @notice Set pool withdrawal fee
/// @dev Only callable by governance
/// @param asset Pool asset, e.g. address(0) for ETH
/// @param bps Withdrawal fee in bps
function setWithdrawalFee(address asset, uint256 bps) external onlyGov {
require(bps <= MAX_POOL_WITHDRAWAL_FEE, '!pool-withdrawal-fee');
withdrawalFees[asset] = bps;
}
/// @notice Increments pool balance
/// @dev Only callable by other protocol contracts
function incrementBalance(address asset, uint256 amount) external onlyContract {
balances[asset] += amount;
}
/// @notice Decrements pool balance
/// @dev Only callable by other protocol contracts
function decrementBalance(address asset, uint256 amount) external onlyContract {
balances[asset] = balances[asset] <= amount ? 0 : balances[asset] - amount;
}
/// @notice Increments buffer balance
/// @dev Only callable by other protocol contracts
function incrementBufferBalance(address asset, uint256 amount) external onlyContract {
bufferBalances[asset] += amount;
}
/// @notice Decrements buffer balance
/// @dev Only callable by other protocol contracts
function decrementBufferBalance(address asset, uint256 amount) external onlyContract {
bufferBalances[asset] = bufferBalances[asset] <= amount ? 0 : bufferBalances[asset] - amount;
}
/// @notice Updates `lastPaid`
/// @dev Only callable by other protocol contracts
function setLastPaid(address asset, uint256 timestamp) external onlyContract {
lastPaid[asset] = timestamp;
}
/// @notice Increments `clpSupply` and `userClpBalances`
/// @dev Only callable by other protocol contracts
function incrementUserClpBalance(address asset, address user, uint256 amount) external onlyContract {
clpSupply[asset] += amount;
unchecked {
// Overflow not possible: balance + amount is at most clpSupply + amount, which is checked above.
userClpBalances[asset][user] += amount;
}
}
/// @notice Decrements `clpSupply` and `userClpBalances`
/// @dev Only callable by other protocol contracts
function decrementUserClpBalance(address asset, address user, uint256 amount) external onlyContract {
clpSupply[asset] = clpSupply[asset] <= amount ? 0 : clpSupply[asset] - amount;
userClpBalances[asset][user] = userClpBalances[asset][user] <= amount
? 0
: userClpBalances[asset][user] - amount;
}
/// @notice Returns withdrawal fee of `asset` from pool
function getWithdrawalFee(address asset) external view returns (uint256) {
return withdrawalFees[asset];
}
/// @notice Returns the sum of buffer and pool balance of `asset`
function getAvailable(address asset) external view returns (uint256) {
return balances[asset] + bufferBalances[asset];
}
/// @notice Returns amount of `asset` in pool
function getBalance(address asset) external view returns (uint256) {
return balances[asset];
}
/// @notice Returns amount of `asset` in buffer
function getBufferBalance(address asset) external view returns (uint256) {
return bufferBalances[asset];
}
/// @notice Returns pool balances of `_assets`
function getBalances(address[] calldata _assets) external view returns (uint256[] memory) {
uint256 length = _assets.length;
uint256[] memory _balances = new uint256[](length);
for (uint256 i = 0; i < length; i++) {
_balances[i] = balances[_assets[i]];
}
return _balances;
}
/// @notice Returns buffer balances of `_assets`
function getBufferBalances(address[] calldata _assets) external view returns (uint256[] memory) {
uint256 length = _assets.length;
uint256[] memory _balances = new uint256[](length);
for (uint256 i = 0; i < length; i++) {
_balances[i] = bufferBalances[_assets[i]];
}
return _balances;
}
/// @notice Returns last time pool was paid
function getLastPaid(address asset) external view returns (uint256) {
return lastPaid[asset];
}
/// @notice Returns `_assets` balance of `account`
function getUserBalances(address[] calldata _assets, address account) external view returns (uint256[] memory) {
uint256 length = _assets.length;
uint256[] memory _balances = new uint256[](length);
for (uint256 i = 0; i < length; i++) {
_balances[i] = getUserBalance(_assets[i], account);
}
return _balances;
}
/// @notice Returns `asset` balance of `account`
function getUserBalance(address asset, address account) public view returns (uint256) {
if (clpSupply[asset] == 0) return 0;
return (userClpBalances[asset][account] * balances[asset]) / clpSupply[asset];
}
/// @notice Returns total amount of CLP for `asset`
function getClpSupply(address asset) public view returns (uint256) {
return clpSupply[asset];
}
/// @notice Returns amount of CLP of `account` for `asset`
function getUserClpBalance(address asset, address account) public view returns (uint256) {
return userClpBalances[asset][account];
}
}