Smart Contract

LinearRelease

A.123cb47fe122f6e3.LinearRelease

Deployed

1d ago
Feb 26, 2026, 09:44:38 PM UTC

Dependents

0 imports
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