@@ -4,29 +4,34 @@ import "./../../Checkpoint/ICheckpoint.sol";
4
4
import "../../TransferManager/ITransferManager.sol " ;
5
5
import "../../../interfaces/ISecurityToken.sol " ;
6
6
import "openzeppelin-solidity/contracts/math/SafeMath.sol " ;
7
+ import "../../../libraries/BokkyPooBahsDateTimeLibrary.sol " ;
7
8
8
9
/**
9
10
* @title Burn module for burning tokens and keeping track of burnt amounts
10
11
*/
11
12
contract ScheduledCheckpoint is ICheckpoint , ITransferManager {
12
13
using SafeMath for uint256 ;
13
14
15
+ enum TimeUnit {SECONDS, DAYS, WEEKS, MONTHS, YEARS}
16
+
14
17
struct Schedule {
15
18
bytes32 name;
16
19
uint256 startTime;
17
20
uint256 nextTime;
18
21
uint256 interval;
22
+ TimeUnit timeUnit;
19
23
uint256 index;
20
24
uint256 [] checkpointIds;
21
25
uint256 [] timestamps;
22
26
uint256 [] periods;
27
+ uint256 totalPeriods;
23
28
}
24
29
25
30
bytes32 [] public names;
26
31
27
32
mapping (bytes32 => Schedule) public schedules;
28
33
29
- event AddSchedule (bytes32 _name , uint256 _startTime , uint256 _interval , uint256 _timestamp );
34
+ event AddSchedule (bytes32 _name , uint256 _startTime , uint256 _interval , TimeUnit _timeUint , uint256 _timestamp );
30
35
event RemoveSchedule (bytes32 _name , uint256 _timestamp );
31
36
32
37
/**
@@ -51,17 +56,19 @@ contract ScheduledCheckpoint is ICheckpoint, ITransferManager {
51
56
* @param _name name of the new schedule (must be unused)
52
57
* @param _startTime start time of the schedule (first checkpoint)
53
58
* @param _interval interval at which checkpoints should be created
59
+ * @param _timeUnit unit of time at which checkpoints should be created
54
60
*/
55
- function addSchedule (bytes32 _name , uint256 _startTime , uint256 _interval ) external onlyOwner {
61
+ function addSchedule (bytes32 _name , uint256 _startTime , uint256 _interval , TimeUnit _timeUnit ) external onlyOwner {
56
62
require (_startTime > now , "Start time must be in the future " );
57
63
require (schedules[_name].name == bytes32 (0 ), "Name already in use " );
58
64
schedules[_name].name = _name;
59
65
schedules[_name].startTime = _startTime;
60
66
schedules[_name].nextTime = _startTime;
61
67
schedules[_name].interval = _interval;
68
+ schedules[_name].timeUnit = _timeUnit;
62
69
schedules[_name].index = names.length ;
63
70
names.push (_name);
64
- emit AddSchedule (_name, _startTime, _interval, now );
71
+ emit AddSchedule (_name, _startTime, _interval, _timeUnit, now );
65
72
}
66
73
67
74
/**
@@ -99,15 +106,18 @@ contract ScheduledCheckpoint is ICheckpoint, ITransferManager {
99
106
* @notice gets schedule details
100
107
* @param _name name of the schedule
101
108
*/
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];
103
111
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
111
121
);
112
122
}
113
123
@@ -123,10 +133,27 @@ contract ScheduledCheckpoint is ICheckpoint, ITransferManager {
123
133
Schedule storage schedule = schedules[_name];
124
134
if (schedule.nextTime <= now ) {
125
135
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);
129
136
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);
130
157
schedule.periods.push (periods);
131
158
}
132
159
}
0 commit comments