|
16 | 16 | // |
17 | 17 | // You should have received a copy of the GNU Affero General Public License |
18 | 18 | // along with this program. If not, see <https://www.gnu.org/licenses/>. |
19 | | -pragma solidity ^0.6.11; |
| 19 | +pragma solidity ^0.6.12; |
20 | 20 | pragma experimental ABIEncoderV2; |
21 | 21 |
|
22 | 22 | import { CollateralOpts } from "./CollateralOpts.sol"; |
23 | 23 |
|
24 | | - |
25 | 24 | interface Initializable { |
26 | 25 | function init(bytes32) external; |
27 | 26 | } |
@@ -147,29 +146,28 @@ library DssExecLib { |
147 | 146 | uint256 constant internal BPS_ONE_HUNDRED_PCT = 100 * BPS_ONE_PCT; |
148 | 147 | uint256 constant internal RATES_ONE_HUNDRED_PCT = 1000000021979553151239153027; |
149 | 148 |
|
150 | | - |
151 | 149 | /**********************/ |
152 | 150 | /*** Math Functions ***/ |
153 | 151 | /**********************/ |
154 | | - function add(uint x, uint y) internal pure returns (uint z) { |
| 152 | + function add(uint256 x, uint256 y) internal pure returns (uint256 z) { |
155 | 153 | require((z = x + y) >= x); |
156 | 154 | } |
157 | | - function sub(uint x, uint y) internal pure returns (uint z) { |
| 155 | + function sub(uint256 x, uint256 y) internal pure returns (uint256 z) { |
158 | 156 | require((z = x - y) <= x); |
159 | 157 | } |
160 | | - function mul(uint x, uint y) internal pure returns (uint z) { |
| 158 | + function mul(uint256 x, uint256 y) internal pure returns (uint256 z) { |
161 | 159 | require(y == 0 || (z = x * y) / y == x); |
162 | 160 | } |
163 | | - function wmul(uint x, uint y) internal pure returns (uint z) { |
| 161 | + function wmul(uint256 x, uint256 y) internal pure returns (uint256 z) { |
164 | 162 | z = add(mul(x, y), WAD / 2) / WAD; |
165 | 163 | } |
166 | | - function rmul(uint x, uint y) internal pure returns (uint z) { |
| 164 | + function rmul(uint256 x, uint256 y) internal pure returns (uint256 z) { |
167 | 165 | z = add(mul(x, y), RAY / 2) / RAY; |
168 | 166 | } |
169 | | - function wdiv(uint x, uint y) internal pure returns (uint z) { |
| 167 | + function wdiv(uint256 x, uint256 y) internal pure returns (uint256 z) { |
170 | 168 | z = add(mul(x, WAD), y / 2) / y; |
171 | 169 | } |
172 | | - function rdiv(uint x, uint y) internal pure returns (uint z) { |
| 170 | + function rdiv(uint256 x, uint256 y) internal pure returns (uint256 z) { |
173 | 171 | z = add(mul(x, RAY), y / 2) / y; |
174 | 172 | } |
175 | 173 |
|
@@ -272,6 +270,61 @@ library DssExecLib { |
272 | 270 | DssVat(vat()).nope(_usr); |
273 | 271 | } |
274 | 272 |
|
| 273 | + /******************************/ |
| 274 | + /*** OfficeHours Management ***/ |
| 275 | + /******************************/ |
| 276 | + |
| 277 | + /** |
| 278 | + @dev Returns true if a time is within office hours range |
| 279 | + @param _ts The timestamp to check, usually block.timestamp |
| 280 | + @param _officeHours true if office hours is enabled. |
| 281 | + @return true if time is in castable range |
| 282 | + */ |
| 283 | + function canCast(uint40 _ts, bool _officeHours) public pure returns (bool) { |
| 284 | + if (_officeHours) { |
| 285 | + uint256 day = (_ts / 1 days + 3) % 7; |
| 286 | + if (day >= 5) { return false; } // Can only be cast on a weekday |
| 287 | + uint256 hour = _ts / 1 hours % 24; |
| 288 | + if (hour < 14 || hour >= 21) { return false; } // Outside office hours |
| 289 | + } |
| 290 | + return true; |
| 291 | + } |
| 292 | + |
| 293 | + /** |
| 294 | + @dev Calculate the next available cast time in epoch seconds |
| 295 | + @param _eta The scheduled time of the spell plus the pause delay |
| 296 | + @param _ts The current timestamp, usually block.timestamp |
| 297 | + @param _officeHours true if office hours is enabled. |
| 298 | + @return castTime The next available cast timestamp |
| 299 | + */ |
| 300 | + function nextCastTime(uint40 _eta, uint40 _ts, bool _officeHours) public pure returns (uint256 castTime) { |
| 301 | + require(_eta != 0); // "DssExecLib/invalid eta" |
| 302 | + require(_ts != 0); // "DssExecLib/invalid ts" |
| 303 | + castTime = _ts > _eta ? _ts : _eta; // Any day at XX:YY |
| 304 | + |
| 305 | + if (_officeHours) { |
| 306 | + uint256 day = (castTime / 1 days + 3) % 7; |
| 307 | + uint256 hour = castTime / 1 hours % 24; |
| 308 | + uint256 minute = castTime / 1 minutes % 60; |
| 309 | + uint256 second = castTime % 60; |
| 310 | + |
| 311 | + if (day >= 5) { |
| 312 | + castTime += (6 - day) * 1 days; // Go to Sunday XX:YY |
| 313 | + castTime += (24 - hour + 14) * 1 hours; // Go to 14:YY UTC Monday |
| 314 | + castTime -= minute * 1 minutes + second; // Go to 14:00 UTC |
| 315 | + } else { |
| 316 | + if (hour >= 21) { |
| 317 | + if (day == 4) castTime += 2 days; // If Friday, fast forward to Sunday XX:YY |
| 318 | + castTime += (24 - hour + 14) * 1 hours; // Go to 14:YY UTC next day |
| 319 | + castTime -= minute * 1 minutes + second; // Go to 14:00 UTC |
| 320 | + } else if (hour < 14) { |
| 321 | + castTime += (14 - hour) * 1 hours; // Go to 14:YY UTC same day |
| 322 | + castTime -= minute * 1 minutes + second; // Go to 14:00 UTC |
| 323 | + } |
| 324 | + } |
| 325 | + } |
| 326 | + } |
| 327 | + |
275 | 328 | /**************************/ |
276 | 329 | /*** Accumulating Rates ***/ |
277 | 330 | /**************************/ |
|
0 commit comments