Smart Contract
LinearRelease
A.123cb47fe122f6e3.LinearRelease
1import MoxyData from 0x123cb47fe122f6e3
2
3
4pub contract LinearRelease {
5
6 pub struct LinearSchedule {
7 pub var tgeDate: UFix64
8 pub var totalAmount: UFix64
9 pub var initialAmount: UFix64
10 pub let unlockDate: UFix64
11 pub var unlockAmount: UFix64
12 pub let days: Int
13 pub var dailyAmount: UFix64
14 pub var lastReleaseDate: UFix64
15
16 pub fun setStartDate(timestamp: UFix64) {
17 self.tgeDate = timestamp
18 self.lastReleaseDate = timestamp
19 }
20
21 pub fun updateLastReleaseDate() {
22 self.setLastReleaseDate(timestamp: getCurrentBlock().timestamp)
23 }
24
25 pub fun setLastReleaseDate(timestamp: UFix64) {
26 self.lastReleaseDate = timestamp
27 }
28
29 pub fun splitWith(amount: UFix64): LinearSchedule {
30 pre {
31 amount <= self.totalAmount : "Not enough amount to split linear release"
32 self.totalAmount > 0.0 : "Total amount should be greater than zero"
33 }
34
35 var initialAmount = self.getAmountAtTGEToPay()
36 if (initialAmount > 0.0) {
37 initialAmount = self.initialAmount / self.totalAmount * amount
38 }
39 var unlockAmount = self.getAmountAfterUnlockToPay()
40 if (unlockAmount > 0.0) {
41 unlockAmount = self.unlockAmount / self.totalAmount * amount
42 }
43
44 let totalToRelease = amount - (initialAmount + unlockAmount)
45 let days = Int(self.getDaysRemainingToEnd())
46
47 if (days == 0) {
48 panic("Days is zero")
49 }
50
51 let dailyAmount = totalToRelease / UFix64(days)
52
53 let newLinearRelease = LinearRelease.createLinearSchedule(tgeDate: self.tgeDate, totalAmount: amount,
54 initialAmount: initialAmount, unlockDate: self.unlockDate, unlockAmount: unlockAmount,
55 days: self.days, dailyAmount: dailyAmount)
56
57 newLinearRelease.setLastReleaseDate(timestamp: self.lastReleaseDate)
58
59 // Update current schedule
60 self.initialAmount = self.initialAmount - initialAmount
61 self.unlockAmount = self.unlockAmount - unlockAmount
62 self.totalAmount = self.totalAmount - amount
63 self.dailyAmount = self.dailyAmount - dailyAmount
64
65 return newLinearRelease
66 }
67
68 pub fun getTotalToUnlock(): UFix64 {
69 var total = 0.0
70
71 total = total + self.getAmountAtTGEToPay()
72 total = total + self.getAmountAfterUnlockToPay()
73 total = total + self.getDailyAmountToPay()
74 return total
75 }
76
77 pub fun getDaysRemaining(): UFix64 {
78 /*
79 Returns the remaining days to pay depending the last release paid
80 */
81 let today0000 = MoxyData.getTimestampTo0000(timestamp: getCurrentBlock().timestamp)
82 var last0000 = 0.0
83 if (self.lastReleaseDate < self.unlockDate) {
84 last0000 = MoxyData.getTimestampTo0000(timestamp: self.unlockDate)
85 } else {
86 last0000 = MoxyData.getTimestampTo0000(timestamp: self.lastReleaseDate)
87 }
88
89 if (Fix64(today0000) - Fix64(last0000) < 0.0) {
90 // Unlock date is not reached yet
91 return 0.0
92 }
93
94 if (last0000 >= MoxyData.getTimestampTo0000(timestamp: self.getEndDate())) {
95 // Finish date reached
96 return 0.0
97 }
98
99 return (today0000 - last0000) / 86400.0
100 }
101
102 pub fun getDaysRemainingToEnd(): UFix64 {
103 /*
104 Returns the remaining days to pay depending the last release paid
105 */
106 let end0000 = MoxyData.getTimestampTo0000(timestamp: self.getEndDate())
107 var last0000 = 0.0
108 if (self.lastReleaseDate < self.unlockDate) {
109 last0000 = MoxyData.getTimestampTo0000(timestamp: self.unlockDate)
110 } else {
111 last0000 = MoxyData.getTimestampTo0000(timestamp: self.lastReleaseDate)
112 }
113
114 if (last0000 >= end0000) {
115 // Finish date reached
116 return 0.0
117 }
118
119 return (end0000 - last0000) / 86400.0
120 }
121
122
123 pub fun getEndDate(): UFix64 {
124 // Days starts from unlock date
125 return self.unlockDate + UFix64(self.days * 86400)
126 }
127
128 pub fun getAmountAtTGEToPay(): UFix64 {
129 if (self.lastReleaseDate <= self.tgeDate) {
130 return self.initialAmount
131 }
132 // Returns zero if amount is already paid
133 return 0.0
134 }
135
136 pub fun getAmountAtTGE(): UFix64 {
137 return self.initialAmount
138 }
139
140
141 pub fun getAmountAfterUnlockToPay(): UFix64 {
142 if (MoxyData.getTimestampTo0000(timestamp: self.lastReleaseDate) == MoxyData.getTimestampTo0000(timestamp: self.unlockDate)) {
143 return self.unlockAmount
144 }
145 // Returns zero if amount is already paid
146 return 0.0
147 }
148
149 pub fun getAmountAfterUnlock(): UFix64 {
150 return self.unlockAmount
151 }
152
153 pub fun getDailyAmountToPay(): UFix64 {
154 // First is checked that the locked time has passed
155 if (getCurrentBlock().timestamp < self.unlockDate) {
156 return 0.0
157 }
158 let days = self.getDaysRemaining()
159
160 return self.dailyAmount * days
161 }
162
163 pub fun getDailyAmount(): UFix64 {
164 return self.dailyAmount
165 }
166
167 pub fun getTotalDailyAmount(): UFix64 {
168 return (self.totalAmount - ( self.initialAmount + self.unlockAmount ))
169 }
170
171 pub fun printInfo() {
172 log("************************************************");
173 log("self.totalAmount")
174 log(self.totalAmount)
175 log("self.initialAmount")
176 log(self.initialAmount)
177 log("self.unlockDate")
178 log(self.unlockDate)
179 log("self.unlockAmount")
180 log(self.unlockAmount)
181 log("self.days")
182 log(self.days)
183 log("self.dailyAmount")
184 log(self.dailyAmount)
185 log("************************************************");
186 }
187
188 init(tgeDate: UFix64, totalAmount: UFix64, initialAmount: UFix64, unlockDate: UFix64, unlockAmount: UFix64, days: Int, dailyAmount: UFix64) {
189 self.tgeDate = tgeDate
190 self.totalAmount = totalAmount
191 self.initialAmount = initialAmount
192 self.unlockDate = unlockDate
193 self.unlockAmount = unlockAmount
194 self.days = days
195 self.dailyAmount = dailyAmount
196 self.lastReleaseDate = tgeDate
197 }
198
199 }
200
201 pub fun createLinearSchedule(tgeDate: UFix64, totalAmount: UFix64, initialAmount: UFix64, unlockDate: UFix64, unlockAmount: UFix64, days: Int, dailyAmount: UFix64): LinearSchedule {
202 return LinearSchedule(tgeDate: tgeDate, totalAmount: totalAmount,
203 initialAmount: initialAmount, unlockDate: unlockDate,
204 unlockAmount: unlockAmount, days: days, dailyAmount: dailyAmount)
205 }
206
207
208}
209
210