|
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