-
Notifications
You must be signed in to change notification settings - Fork 0
/
AzbitReservedTokenLock.sol
155 lines (121 loc) · 3.58 KB
/
AzbitReservedTokenLock.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/**
* @author https://github.com/Dmitx
*/
pragma solidity ^0.4.24;
import "./AzbitTokenInterface.sol";
import "./math/SafeMath.sol";
import "./AzbitPriceTicker.sol";
/**
* @title AzbitReservedTokenLock
* @dev Smart contract for reserved tokens
*/
contract AzbitReservedTokenLock is AzbitPriceTicker {
using SafeMath for uint256;
// ** EVENTS **
// Event for token withdrawal logging
event TokenWithdrawn(address indexed to, uint256 value);
// ** PUBLIC STATE VARIABLES **
// Azbit token
AzbitTokenInterface public azbitToken;
// Address for tokens withdrawal
address public withdrawalAddress;
// Number of withdrawn tokens
uint256 public withdrawnTokens;
// Lockout period after token purchase
uint256 public constant lockPeriod = 5 * 365 days; // 5 years
// ** CONSTRUCTOR **
/**
* @dev Constructor of AzbitReservedTokenLock Contract
*
* @param tokenAddress address of AzbitToken
* @param tokenPrice initial price of AzbitToken in USD cents
* @param beneficiary address for tokens withdrawal
*/
constructor(
address tokenAddress,
uint256 tokenPrice,
address beneficiary
)
public
payable
AzbitPriceTicker(tokenPrice)
{
require(beneficiary != address(0), "Address cannot be 0x0");
_setToken(tokenAddress);
withdrawalAddress = beneficiary;
}
// ** EXTERNAL FUNCTIONS **
// Withdrawal tokens from this contract to withdrawalAddress
function withdrawTokens()
external
{
// amount for withdrawal
uint256 amount = releasableAmount();
require(amount > 0, "no tokens for withdrawal");
// update state
withdrawnTokens = withdrawnTokens.add(amount);
// withdrawal to withdrawalAddress
require(azbitToken.transfer(withdrawalAddress, amount), "tokens are not transferred");
emit TokenWithdrawn(withdrawalAddress, amount);
}
// ** PUBLIC VIEW FUNCTIONS **
/**
* @return total tokens of this contract.
*/
function contractTokenBalance()
public
view
returns(uint256 amount)
{
return azbitToken.balanceOf(this);
}
/**
* @dev Gets unlocked percent of tokens
* @return percentage of unlocked tokens
*/
function getUnlockedPercent()
public
view
returns(uint256 percentage)
{
return _rateUnlockedPercent();
}
/**
* @dev Calculates the amount that has already available but hasn't been withdrawn yet
* @return The amount of tokens
*/
function releasableAmount()
public
view
returns (uint256 amount)
{
return contractTokenBalance().add(withdrawnTokens)
.mul(getUnlockedPercent()).div(100)
.sub(withdrawnTokens);
}
// ** PRIVATE HELPER FUNCTIONS **
// Helper: Get percent of tokens unlocked with an increased rate
function _rateUnlockedPercent()
internal
view
returns(uint256 percentage)
{
if (_x5Count > _count) {
return 100;
} else if (_x4Count > _count) {
return 75;
} else if (_x3Count > _count) {
return 50;
} else if (_x2Count > _count) {
return 25;
}
return 0;
}
// Helper: Set the address of azbitToken Token
function _setToken(address tokenAddress)
internal
{
azbitToken = AzbitTokenInterface(tokenAddress);
require(contractTokenBalance() >= 0, "The token being added is not ERC20 token");
}
}