@@ -10,10 +10,13 @@ import "../../LockKeeper.sol";
10
10
11
11
contract TokenPool is Initializable , AccessControl , IOnBlockListener {
12
12
13
- struct Config {
13
+ struct MainConfig {
14
14
IERC20 token;
15
15
string name;
16
16
address rewardToken;
17
+ }
18
+
19
+ struct LimitsConfig {
17
20
uint rewardTokenPrice; // The coefficient to calculate the reward token amount
18
21
uint minStakeValue;
19
22
uint fastUnstakePenalty;
@@ -42,7 +45,8 @@ contract TokenPool is Initializable, AccessControl, IOnBlockListener {
42
45
RewardsBank rewardsBank;
43
46
LockKeeper lockKeeper;
44
47
45
- Config public config;
48
+ MainConfig public mainConfig; // immutable
49
+ LimitsConfig public limitsConfig; // mutable
46
50
Info public info;
47
51
48
52
mapping (address => Staker) public stakers;
@@ -51,21 +55,19 @@ contract TokenPool is Initializable, AccessControl, IOnBlockListener {
51
55
52
56
event Deactivated ();
53
57
event Activated ();
54
- event MinStakeValueChanged (uint minStakeValue );
55
- event InterestRateChanged (uint interest , uint interestRate );
56
- event LockPeriodChanged (uint period );
57
- event RewardTokenPriceChanged (uint price );
58
- event FastUnstakePenaltyChanged (uint penalty );
58
+ event LimitsConfigChanged (LimitsConfig limitsConfig );
59
59
event StakeChanged (address indexed user , uint amount );
60
60
event Claim (address indexed user , uint amount );
61
61
event Interest (uint amount );
62
62
event UnstakeLocked (address indexed user , uint amount , uint unlockTime , uint creationTime );
63
63
event UnstakeFast (address indexed user , uint amount , uint penalty );
64
64
65
- function initialize (RewardsBank bank_ , LockKeeper keeper_ , Config calldata config_ ) public initializer {
65
+ function initialize (RewardsBank bank_ , LockKeeper keeper_ , MainConfig calldata mainConfig_ , LimitsConfig calldata limitsConfig_ ) public initializer {
66
+ //TODO: Should validate input params
66
67
rewardsBank = bank_;
67
68
lockKeeper = keeper_;
68
- config = config_;
69
+ mainConfig = mainConfig_;
70
+ limitsConfig = limitsConfig_;
69
71
70
72
info.lastInterestUpdate = block .timestamp ;
71
73
@@ -76,6 +78,12 @@ contract TokenPool is Initializable, AccessControl, IOnBlockListener {
76
78
77
79
// OWNER METHODS
78
80
81
+ function setLimitsConfig (LimitsConfig calldata _limitsConfig ) public onlyRole (DEFAULT_ADMIN_ROLE) {
82
+ //TODO: Validate input params
83
+ limitsConfig = _limitsConfig;
84
+ emit LimitsConfigChanged (_limitsConfig);
85
+ }
86
+
79
87
function activate () public onlyRole (DEFAULT_ADMIN_ROLE) {
80
88
require (! active, "Pool is already active " );
81
89
active = true ;
@@ -88,39 +96,12 @@ contract TokenPool is Initializable, AccessControl, IOnBlockListener {
88
96
emit Deactivated ();
89
97
}
90
98
91
- function setMinStakeValue (uint value ) public onlyRole (DEFAULT_ADMIN_ROLE) {
92
- config.minStakeValue = value;
93
- emit MinStakeValueChanged (value);
94
- }
95
-
96
- function setInterest (uint _interest , uint _interestRate ) public onlyRole (DEFAULT_ADMIN_ROLE) {
97
- _addInterest ();
98
- config.interest = _interest;
99
- config.interestRate = _interestRate;
100
- emit InterestRateChanged (config.interest, config.interestRate);
101
- }
102
-
103
- function setLockPeriod (uint period ) public onlyRole (DEFAULT_ADMIN_ROLE) {
104
- config.lockPeriod = period;
105
- emit LockPeriodChanged (period);
106
- }
107
-
108
- function setRewardTokenPrice (uint price ) public onlyRole (DEFAULT_ADMIN_ROLE) {
109
- config.rewardTokenPrice = price;
110
- emit RewardTokenPriceChanged (price);
111
- }
112
-
113
- function setFastUnstakePenalty (uint penalty ) public onlyRole (DEFAULT_ADMIN_ROLE) {
114
- config.fastUnstakePenalty = penalty;
115
- emit FastUnstakePenaltyChanged (penalty);
116
- }
117
-
118
99
// PUBLIC METHODS
119
100
120
101
function stake (uint amount ) public {
121
102
require (active, "Pool is not active " );
122
- require (amount >= config .minStakeValue, "Pool: stake value is too low " );
123
- require (config .token.transferFrom (msg .sender , address (this ), amount), "Transfer failed " );
103
+ require (amount >= limitsConfig .minStakeValue, "Pool: stake value is too low " );
104
+ require (mainConfig .token.transferFrom (msg .sender , address (this ), amount), "Transfer failed " );
124
105
125
106
_stake (msg .sender , amount);
126
107
@@ -137,17 +118,17 @@ contract TokenPool is Initializable, AccessControl, IOnBlockListener {
137
118
if (lockKeeper.getLock (stakers[msg .sender ].lockedWithdrawal).totalClaims > 0 ) // prev lock exists
138
119
canceledAmount = lockKeeper.cancelLock (stakers[msg .sender ].lockedWithdrawal);
139
120
140
- config .token.approve (address (lockKeeper), amount + canceledAmount);
121
+ mainConfig .token.approve (address (lockKeeper), amount + canceledAmount);
141
122
142
123
// lock funds
143
124
stakers[msg .sender ].lockedWithdrawal = lockKeeper.lockSingle (
144
- msg .sender , address (config .token), uint64 (block .timestamp + config .lockPeriod), amount + canceledAmount,
145
- string (abi.encodePacked ("TokenStaking unstake: " , _addressToString (address (config .token))))
125
+ msg .sender , address (mainConfig .token), uint64 (block .timestamp + limitsConfig .lockPeriod), amount + canceledAmount,
126
+ string (abi.encodePacked ("TokenStaking unstake: " , _addressToString (address (mainConfig .token))))
146
127
);
147
128
148
129
_claimRewards (msg .sender );
149
130
150
- emit UnstakeLocked (msg .sender , amount + canceledAmount, block .timestamp + config .lockPeriod, block .timestamp );
131
+ emit UnstakeLocked (msg .sender , amount + canceledAmount, block .timestamp + limitsConfig .lockPeriod, block .timestamp );
151
132
emit StakeChanged (msg .sender , stakers[msg .sender ].stake);
152
133
}
153
134
@@ -156,8 +137,8 @@ contract TokenPool is Initializable, AccessControl, IOnBlockListener {
156
137
157
138
_unstake (msg .sender , amount);
158
139
159
- uint penalty = amount * config .fastUnstakePenalty / BILLION;
160
- SafeERC20.safeTransfer (config .token, msg .sender , amount - penalty);
140
+ uint penalty = amount * limitsConfig .fastUnstakePenalty / BILLION;
141
+ SafeERC20.safeTransfer (mainConfig .token, msg .sender , amount - penalty);
161
142
162
143
_claimRewards (msg .sender );
163
144
@@ -176,8 +157,12 @@ contract TokenPool is Initializable, AccessControl, IOnBlockListener {
176
157
177
158
// VIEW METHODS
178
159
179
- function getConfig () public view returns (Config memory ) {
180
- return config;
160
+ function getMainConfig () public view returns (MainConfig memory ) {
161
+ return mainConfig;
162
+ }
163
+
164
+ function getLimitsConfig () public view returns (LimitsConfig memory ) {
165
+ return limitsConfig;
181
166
}
182
167
183
168
function getInfo () public view returns (Info memory ) {
@@ -208,9 +193,9 @@ contract TokenPool is Initializable, AccessControl, IOnBlockListener {
208
193
}
209
194
210
195
function _addInterest () internal {
211
- if (info.lastInterestUpdate + config .interestRate > block .timestamp ) return ;
196
+ if (info.lastInterestUpdate + limitsConfig .interestRate > block .timestamp ) return ;
212
197
uint timePassed = block .timestamp - info.lastInterestUpdate;
213
- uint newRewards = info.totalStake * config .interest * timePassed / BILLION / config .interestRate;
198
+ uint newRewards = info.totalStake * limitsConfig .interest * timePassed / BILLION / limitsConfig .interestRate;
214
199
215
200
info.totalRewards += newRewards;
216
201
info.lastInterestUpdate = block .timestamp ;
@@ -251,8 +236,8 @@ contract TokenPool is Initializable, AccessControl, IOnBlockListener {
251
236
252
237
stakers[user].claimableRewards = 0 ;
253
238
254
- uint rewardTokenAmount = amount * config .rewardTokenPrice;
255
- rewardsBank.withdrawErc20 (config .rewardToken, payable (user), rewardTokenAmount);
239
+ uint rewardTokenAmount = amount * limitsConfig .rewardTokenPrice;
240
+ rewardsBank.withdrawErc20 (mainConfig .rewardToken, payable (user), rewardTokenAmount);
256
241
emit Claim (user, rewardTokenAmount);
257
242
}
258
243
0 commit comments