WOOP in Binance Smart Chain
TOKEN WOONKLY POWER - WOOP ( BEP-20)
SOURCE CODE SMART CONTRACT " WOONKLY POWER "
1
/**
2
*Submitted for verification at BscScan.com on 2020-11-25
3
*/
4
5
pragma solidity ^0.5.16;
6
7
contract Owned {
8
9
address public owner;
10
11
event OwnershipTransferred(address indexed _from, address indexed _to);
12
13
constructor() public {
14
owner = msg.sender;
15
}
16
17
modifier onlyOwner {
18
require(msg.sender == owner, "Should be owner");
19
_;
20
}
21
22
function transferOwnership(address newOwner) public onlyOwner {
23
owner = newOwner;
24
emit OwnershipTransferred(owner, newOwner);
25
}
26
}
27
28
contract Tokenlock is Owned {
29
/// @notice Indicates if token is locked
30
uint8 isLocked = 0;
31
32
event Freezed();
33
event UnFreezed();
34
35
modifier validLock {
36
require(isLocked == 0, "Token is locked");
37
_;
38
}
39
40
function freeze() public onlyOwner {
41
isLocked = 1;
42
43
emit Freezed();
44
}
45
46
function unfreeze() public onlyOwner {
47
isLocked = 0;
48
49
emit UnFreezed();
50
}
51
}
52
53
contract WOOP is Tokenlock {
54
/// @notice BEP-20 token name for this token
55
string public constant name = "Woonkly Power";
56
57
/// @notice BEP-20 token symbol for this token
58
string public constant symbol = "WOOP";
59
60
/// @notice BEP-20 token decimals for this token
61
uint8 public constant decimals = 18;
62
63
/// @notice Total number of tokens in circulation
64
uint public constant totalSupply = 1000000000e18; // 1 mil million WTSTsts
65
66
/// @notice Allowance amounts on behalf of others
67
mapping (address => mapping (address => uint96)) internal allowances;
68
69
/// @notice Official record of token balances for each account
70
mapping (address => uint96) internal balances;
71
72
/// @notice A record of each accounts delegate
73
mapping (address => address) public delegates;
74
75
/// @notice A checkpoint for marking number of votes from a given block
76
struct Checkpoint {
77
uint32 fromBlock;
78
uint96 votes;
79
}
80
81
/// @notice A record of votes checkpoints for each account, by index
82
mapping (address => mapping (uint32 => Checkpoint)) public checkpoints;
83
84
/// @notice The number of checkpoints for each account
85
mapping (address => uint32) public numCheckpoints;
86
87
/// @notice The EIP-712 typehash for the contract's domain
88
bytes32 public constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)");
89
90
/// @notice The EIP-712 typehash for the delegation struct used by the contract
91
bytes32 public constant DELEGATION_TYPEHASH = keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)");
92
93
/// @notice A record of states for signing / validating signatures
94
mapping (address => uint) public nonces;
95
96
/// @notice An event thats emitted when an account changes its delegate
97
event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);
98
99
/// @notice An event thats emitted when a delegate account's vote balance changes
100
event DelegateVotesChanged(address indexed delegate, uint previousBalance, uint newBalance);
101
102
/// @notice The standard BEP-20 transfer event
103
event Transfer(address indexed from, address indexed to, uint256 amount);
104
105
/// @notice The standard BEP-20 approval event
106
event Approval(address indexed owner, address indexed spender, uint256 amount);
107
108
/**
109
* @notice Construct a new WOOP token
110
* @param account The initial account to grant all the tokens
111
*/
112
constructor(address account) public {
113
balances[account] = uint96(totalSupply);
114
emit Transfer(address(0), account, totalSupply);
115
}
116
117
/**
118
* @notice Get the number of tokens `spender` is approved to spend on behalf of `account`
119
* @param account The address of the account holding the funds
120
* @param spender The address of the account spending the funds
121
* @return The number of tokens approved
122
*/
123
function allowance(address account, address spender) external view returns (uint) {
124
return allowances[account][spender];
125
}
126
127
/**
128
* @notice Approve `spender` to transfer up to `amount` from `src`
129
* @dev This will overwrite the approval amount for `spender`
130
* @param spender The address of the account which may transfer tokens
131
* @param rawAmount The number of tokens that are approved (2^256-1 means infinite)
132
* @return Whether or not the approval succeeded
133
*/
134
function approve(address spender, uint rawAmount) external validLock returns (bool) {
135
uint96 amount;
136
if (rawAmount == uint(-1)) {
137
amount = uint96(-1);
138
} else {
139
amount = safe96(rawAmount, "WOP::approve: amount exceeds 96 bits");
140
}
141
142
allowances[msg.sender][spender] = amount;
143
144
emit Approval(msg.sender, spender, amount);
145
return true;
146
}
147
148
/**
149
* @notice Get the number of tokens held by the `account`
150
* @param account The address of the account to get the balance of
151
* @return The number of tokens held
152
*/
153
function balanceOf(address account) external view returns (uint) {
154
return balances[account];
155
}
156
157
/**
158
* @notice Transfer `amount` tokens from `msg.sender` to `dst`
159
* @param dst The address of the destination account
160
* @param rawAmount The number of tokens to transfer
161
* @return Whether or not the transfer succeeded
162
*/
163
function transfer(address dst, uint rawAmount) external validLock returns (bool) {
164
uint96 amount = safe96(rawAmount, "WOP::transfer: amount exceeds 96 bits");
165
_transferTokens(msg.sender, dst, amount);
166
return true;
167
}
168
169
/**
170
* @notice Transfer `amount` tokens from `src` to `dst`
171
* @param src The address of the source account
172
* @param dst The address of the destination account
173
* @param rawAmount The number of tokens to transfer
174
* @return Whether or not the transfer succeeded
175
*/
176
function transferFrom(address src, address dst, uint rawAmount) external validLock returns (bool) {
177
address spender = msg.sender;
178
uint96 spenderAllowance = allowances[src][spender];
179
uint96 amount = safe96(rawAmount, "WOP::approve: amount exceeds 96 bits");
180
181
if (spender != src && spenderAllowance != uint96(-1)) {
182
uint96 newAllowance = sub96(spenderAllowance, amount, "WOP::transferFrom: transfer amount exceeds spender allowance");
183
allowances[src][spender] = newAllowance;
184
185
emit Approval(src, spender, newAllowance);
186
}
187
188
_transferTokens(src, dst, amount);
189
return true;
190
}
191
192
/**
193
* @notice Delegate votes from `msg.sender` to `delegatee`
194
* @param delegatee The address to delegate votes to
195
*/
196
function delegate(address delegatee) public validLock {
197
return _delegate(msg.sender, delegatee);
198
}
199
200
/**
201
* @notice Delegates votes from signatory to `delegatee`
202
* @param delegatee The address to delegate votes to
203
* @param nonce The contract state required to match the signature
204
* @param expiry The time at which to expire the signature
205
* @param v The recovery byte of the signature
206
* @param r Half of the ECDSA signature pair
207
* @param s Half of the ECDSA signature pair
208
*/
209
function delegateBySig(address delegatee, uint nonce, uint expiry, uint8 v, bytes32 r, bytes32 s) public validLock {
210
bytes32 domainSeparator = keccak256(abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name)), getChainId(), address(this)));
211
bytes32 structHash = keccak256(abi.encode(DELEGATION_TYPEHASH, delegatee, nonce, expiry));
212
bytes32 digest = keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
213
address signatory = ecrecover(digest, v, r, s);
214
require(signatory != address(0), "WOP::delegateBySig: invalid signature");
215
require(nonce == nonces[signatory]++, "WOP::delegateBySig: invalid nonce");
216
require(now <= expiry, "WOP::delegateBySig: signature expired");
217
return _delegate(signatory, delegatee);
218
}
219
220
/**
221
* @notice Gets the current votes balance for `account`
222
* @param account The address to get votes balance
223
* @return The number of current votes for `account`
224
*/
225
function getCurrentVotes(address account) external view returns (uint96) {
226
uint32 nCheckpoints = numCheckpoints[account];
227
return nCheckpoints > 0 ? checkpoints[account][nCheckpoints - 1].votes : 0;
228
}
229
230
/**
231
* @notice Determine the prior number of votes for an account as of a block number
232
* @dev Block number must be a finalized block or else this function will revert to prevent misinformation.
233
* @param account The address of the account to check
234
* @param blockNumber The block number to get the vote balance at
235
* @return The number of votes the account had as of the given block
236
*/
237
function getPriorVotes(address account, uint blockNumber) public view returns (uint96) {
238
require(blockNumber < block.number, "WOP::getPriorVotes: not yet determined");
239
240
uint32 nCheckpoints = numCheckpoints[account];
241
if (nCheckpoints == 0) {
242
return 0;
243
}
244
245
// First check most recent balance
246
if (checkpoints[account][nCheckpoints - 1].fromBlock <= blockNumber) {
247
return checkpoints[account][nCheckpoints - 1].votes;
248
}
249
250
// Next check implicit zero balance
251
if (checkpoints[account][0].fromBlock > blockNumber) {
252
return 0;
253
}
254
255
uint32 lower = 0;
256
uint32 upper = nCheckpoints - 1;
257
while (upper > lower) {
258
uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow
259
Checkpoint memory cp = checkpoints[account][center];
260
if (cp.fromBlock == blockNumber) {
261
return cp.votes;
262
} else if (cp.fromBlock < blockNumber) {
263
lower = center;
264
} else {
265
upper = center - 1;
266
}
267
}
268
return checkpoints[account][lower].votes;
269
}
270
271
function _delegate(address delegator, address delegatee) internal {
272
address currentDelegate = delegates[delegator];
273
uint96 delegatorBalance = balances[delegator];
274
delegates[delegator] = delegatee;
275
276
emit DelegateChanged(delegator, currentDelegate, delegatee);
277
278
_moveDelegates(currentDelegate, delegatee, delegatorBalance);
279
}
280
281
function _transferTokens(address src, address dst, uint96 amount) internal {
282
require(src != address(0), "WOP::_transferTokens: cannot transfer from the zero address");
283
require(dst != address(0), "WOP::_transferTokens: cannot transfer to the zero address");
284
285
balances[src] = sub96(balances[src], amount, "WOP::_transferTokens: transfer amount exceeds balance");
286
balances[dst] = add96(balances[dst], amount, "WOP::_transferTokens: transfer amount overflows");
287
emit Transfer(src, dst, amount);
288
289
_moveDelegates(delegates[src], delegates[dst], amount);
290
}
291
292
function _moveDelegates(address srcRep, address dstRep, uint96 amount) internal {
293
if (srcRep != dstRep && amount > 0) {
294
if (srcRep != address(0)) {
295
uint32 srcRepNum = numCheckpoints[srcRep];
296
uint96 srcRepOld = srcRepNum > 0 ? checkpoints[srcRep][srcRepNum - 1].votes : 0;
297
uint96 srcRepNew = sub96(srcRepOld, amount, "WOP::_moveVotes: vote amount underflows");
298
_writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew);
299
}
300
301
if (dstRep != address(0)) {
302
uint32 dstRepNum = numCheckpoints[dstRep];
303
uint96 dstRepOld = dstRepNum > 0 ? checkpoints[dstRep][dstRepNum - 1].votes : 0;
304
uint96 dstRepNew = add96(dstRepOld, amount, "WOP::_moveVotes: vote amount overflows");
305
_writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew);
306
}
307
}
308
}
309
310
function _writeCheckpoint(address delegatee, uint32 nCheckpoints, uint96 oldVotes, uint96 newVotes) internal {
311
uint32 blockNumber = safe32(block.number, "WOP::_writeCheckpoint: block number exceeds 32 bits");
312
313
if (nCheckpoints > 0 && checkpoints[delegatee][nCheckpoints - 1].fromBlock == blockNumber) {
314
checkpoints[delegatee][nCheckpoints - 1].votes = newVotes;
315
} else {
316
checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumber, newVotes);
317
numCheckpoints[delegatee] = nCheckpoints + 1;
318
}
319
320
emit DelegateVotesChanged(delegatee, oldVotes, newVotes);
321
}
322
323
function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {
324
require(n < 2**32, errorMessage);
325
return uint32(n);
326
}
327
328
function safe96(uint n, string memory errorMessage) internal pure returns (uint96) {
329
require(n < 2**96, errorMessage);
330
return uint96(n);
331
}
332
333
function add96(uint96 a, uint96 b, string memory errorMessage) internal pure returns (uint96) {
334
uint96 c = a + b;
335
require(c >= a, errorMessage);
336
return c;
337
}
338
339
function sub96(uint96 a, uint96 b, string memory errorMessage) internal pure returns (uint96) {
340
require(b <= a, errorMessage);
341
return a - b;
342
}
343
344
function getChainId() internal pure returns (uint) {
345
uint256 chainId;
346
assembly { chainId := chainid() }
347
return chainId;
348
}
349
}
Copied!
Last modified 4mo ago
Copy link