@@ -4,29 +4,34 @@ import "./../../Checkpoint/ICheckpoint.sol";
44import "../../TransferManager/ITransferManager.sol " ;
55import "../../../interfaces/ISecurityToken.sol " ;
66import "openzeppelin-solidity/contracts/math/SafeMath.sol " ;
7+ import "../../../libraries/BokkyPooBahsDateTimeLibrary.sol " ;
78
89/**
910 * @title Burn module for burning tokens and keeping track of burnt amounts
1011 */
1112contract ScheduledCheckpoint is ICheckpoint , ITransferManager {
1213 using SafeMath for uint256 ;
1314
15+ enum TimeUnit {SECONDS, DAYS, WEEKS, MONTHS, YEARS}
16+
1417 struct Schedule {
1518 bytes32 name;
1619 uint256 startTime;
1720 uint256 nextTime;
1821 uint256 interval;
22+ TimeUnit timeUnit;
1923 uint256 index;
2024 uint256 [] checkpointIds;
2125 uint256 [] timestamps;
2226 uint256 [] periods;
27+ uint256 totalPeriods;
2328 }
2429
2530 bytes32 [] public names;
2631
2732 mapping (bytes32 => Schedule) public schedules;
2833
29- event AddSchedule (bytes32 _name , uint256 _startTime , uint256 _interval , uint256 _timestamp );
34+ event AddSchedule (bytes32 _name , uint256 _startTime , uint256 _interval , TimeUnit _timeUint , uint256 _timestamp );
3035 event RemoveSchedule (bytes32 _name , uint256 _timestamp );
3136
3237 /**
@@ -51,17 +56,19 @@ contract ScheduledCheckpoint is ICheckpoint, ITransferManager {
5156 * @param _name name of the new schedule (must be unused)
5257 * @param _startTime start time of the schedule (first checkpoint)
5358 * @param _interval interval at which checkpoints should be created
59+ * @param _timeUnit unit of time at which checkpoints should be created
5460 */
55- function addSchedule (bytes32 _name , uint256 _startTime , uint256 _interval ) external onlyOwner {
61+ function addSchedule (bytes32 _name , uint256 _startTime , uint256 _interval , TimeUnit _timeUnit ) external onlyOwner {
5662 require (_startTime > now , "Start time must be in the future " );
5763 require (schedules[_name].name == bytes32 (0 ), "Name already in use " );
5864 schedules[_name].name = _name;
5965 schedules[_name].startTime = _startTime;
6066 schedules[_name].nextTime = _startTime;
6167 schedules[_name].interval = _interval;
68+ schedules[_name].timeUnit = _timeUnit;
6269 schedules[_name].index = names.length ;
6370 names.push (_name);
64- emit AddSchedule (_name, _startTime, _interval, now );
71+ emit AddSchedule (_name, _startTime, _interval, _timeUnit, now );
6572 }
6673
6774 /**
@@ -99,15 +106,18 @@ contract ScheduledCheckpoint is ICheckpoint, ITransferManager {
99106 * @notice gets schedule details
100107 * @param _name name of the schedule
101108 */
102- function getSchedule (bytes32 _name ) view external returns (bytes32 , uint256 , uint256 , uint256 , uint256 [], uint256 [], uint256 []) {
109+ function getSchedule (bytes32 _name ) view external returns (bytes32 , uint256 , uint256 , uint256 , TimeUnit, uint256 [], uint256 [], uint256 [], uint256 ) {
110+ Schedule storage schedule = schedules[_name];
103111 return (
104- schedules[_name].name,
105- schedules[_name].startTime,
106- schedules[_name].nextTime,
107- schedules[_name].interval,
108- schedules[_name].checkpointIds,
109- schedules[_name].timestamps,
110- schedules[_name].periods
112+ schedule.name,
113+ schedule.startTime,
114+ schedule.nextTime,
115+ schedule.interval,
116+ schedule.timeUnit,
117+ schedule.checkpointIds,
118+ schedule.timestamps,
119+ schedule.periods,
120+ schedule.totalPeriods
111121 );
112122 }
113123
@@ -123,10 +133,27 @@ contract ScheduledCheckpoint is ICheckpoint, ITransferManager {
123133 Schedule storage schedule = schedules[_name];
124134 if (schedule.nextTime <= now ) {
125135 uint256 checkpointId = ISecurityToken (securityToken).createCheckpoint ();
126- uint256 periods = now .sub (schedule.nextTime).div (schedule.interval).add (1 );
127- schedule.timestamps.push (schedule.nextTime);
128- schedule.nextTime = periods.mul (schedule.interval).add (schedule.nextTime);
129136 schedule.checkpointIds.push (checkpointId);
137+ schedule.timestamps.push (schedule.nextTime);
138+ uint256 periods;
139+ if (schedule.timeUnit == TimeUnit.SECONDS ) {
140+ periods = now .sub (schedule.nextTime).div (schedule.interval).add (1 );
141+ schedule.nextTime = periods.mul (schedule.interval).add (schedule.nextTime);
142+ } else if (schedule.timeUnit == TimeUnit.DAYS ) {
143+ periods = BokkyPooBahsDateTimeLibrary.diffDays (schedule.nextTime, now ).div (schedule.interval).add (1 );
144+ schedule.nextTime = BokkyPooBahsDateTimeLibrary.addDays (schedule.nextTime, periods.mul (schedule.interval));
145+ } else if (schedule.timeUnit == TimeUnit.WEEKS ) {
146+ periods = BokkyPooBahsDateTimeLibrary.diffDays (schedule.nextTime, now ).div (7 ).div (schedule.interval).add (1 );
147+ schedule.nextTime = BokkyPooBahsDateTimeLibrary.addDays (schedule.nextTime, periods.mul (schedule.interval).mul (7 ));
148+ } else if (schedule.timeUnit == TimeUnit.MONTHS ) {
149+ periods = BokkyPooBahsDateTimeLibrary.diffMonths (schedule.nextTime, now ).div (schedule.interval).add (1 );
150+ uint256 totalPeriods = schedule.totalPeriods.add (periods);
151+ schedule.nextTime = BokkyPooBahsDateTimeLibrary.addMonths (schedule.startTime, totalPeriods.mul (schedule.interval));
152+ } else if (schedule.timeUnit == TimeUnit.YEARS ) {
153+ periods = BokkyPooBahsDateTimeLibrary.diffYears (schedule.nextTime, now ).div (schedule.interval).add (1 );
154+ schedule.nextTime = BokkyPooBahsDateTimeLibrary.addYears (schedule.nextTime, periods.mul (schedule.interval));
155+ }
156+ schedule.totalPeriods = schedule.totalPeriods.add (periods);
130157 schedule.periods.push (periods);
131158 }
132159 }
0 commit comments