-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDistribution.sol
More file actions
157 lines (135 loc) · 5.61 KB
/
Distribution.sol
File metadata and controls
157 lines (135 loc) · 5.61 KB
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
156
157
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol";
import "@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol";
import '@openzeppelin/contracts-upgradeable/access/extensions/AccessControlEnumerableUpgradeable.sol';
import './lib/TransferHelper.sol';
contract Distribution is EIP712Upgradeable, ReentrancyGuardUpgradeable, AccessControlEnumerableUpgradeable {
// Subsequent upgrades do not use enumeration
uint8 public constant TYPE_AIRDROP = 0;
uint8 public constant TYPE_GOVERNANCE = 1;
uint8 public constant TYPE_REWARDS = 2;
uint8 public constant TYPE_SALARY = 3;
uint8 public constant TYPE_BOUNTY = 4;
bytes32 public constant OPERATOR_ROLE = keccak256("DISTRIBUTION_OPERATOR_ROLE");
event DistributionEvent(address indexed operator, address indexed token, address indexed user, uint256 amount, uint8 distType);
constructor() {
_disableInitializers();
}
function initialize(address admin) public initializer {
__ReentrancyGuard_init();
__AccessControlEnumerable_init();
__EIP712_init("Distribution", "1.0.0");
_grantRole(DEFAULT_ADMIN_ROLE, admin);
_grantRole(OPERATOR_ROLE, admin);
}
function airdrop(
address token,
address[] calldata users,
uint256[] calldata amount
) external nonReentrant onlyRole(OPERATOR_ROLE) {
require(users.length == amount.length, "Users and amounts length mismatch");
if (token == address(0)) {
_distributionETH(users, amount, TYPE_AIRDROP);
} else {
_distributionToken(token, users, amount, TYPE_AIRDROP);
}
}
function governance(
address token,
address[] calldata users,
uint256[] calldata amount
) external nonReentrant onlyRole(OPERATOR_ROLE) {
require(users.length == amount.length, "Users and amounts length mismatch");
if (token == address(0)) {
_distributionETH(users, amount, TYPE_GOVERNANCE);
} else {
_distributionToken(token, users, amount, TYPE_GOVERNANCE);
}
}
function Rewards(
address token,
address[] calldata users,
uint256[] calldata amount
) external nonReentrant onlyRole(OPERATOR_ROLE) {
require(users.length == amount.length, "Users and amounts length mismatch");
if (token == address(0)) {
_distributionETH(users, amount, TYPE_REWARDS);
} else {
_distributionToken(token, users, amount, TYPE_REWARDS);
}
}
function Salary(
address token,
address[] calldata users,
uint256[] calldata amount
) external nonReentrant onlyRole(OPERATOR_ROLE) {
require(users.length == amount.length, "Users and amounts length mismatch");
if (token == address(0)) {
_distributionETH(users, amount, TYPE_SALARY);
} else {
_distributionToken(token, users, amount, TYPE_SALARY);
}
}
function Bounty(
address token,
address[] calldata users,
uint256[] calldata amount
) external nonReentrant onlyRole(OPERATOR_ROLE) {
require(users.length == amount.length, "Users and amounts length mismatch");
if (token == address(0)) {
_distributionETH(users, amount, TYPE_BOUNTY);
} else {
_distributionToken(token, users, amount, TYPE_BOUNTY);
}
}
function _distributionToken(address _token, address[] calldata _users, uint256[] calldata _amount, uint8 _distType) internal {
for (uint i = 0; i < _users.length;) {
TransferHelper.safeTransfer(_token, _users[i], _amount[i]);
emit DistributionEvent(msg.sender, _token, _users[i], _amount[i], _distType);
unchecked {
i++;
}
}
}
function _distributionSameToken(address _token, address[] calldata _users, uint256 _amount, uint8 _distType) internal {
for (uint i = 0; i < _users.length;) {
TransferHelper.safeTransfer(_token, _users[i], _amount);
emit DistributionEvent(msg.sender, _token, _users[i], _amount, _distType);
unchecked {
i++;
}
}
}
function _distributionETH(address[] calldata _users, uint256[] calldata _amount, uint8 _distType) internal {
for (uint i = 0; i < _users.length;) {
TransferHelper.safeTransferXOC(_users[i], _amount[i]);
emit DistributionEvent(msg.sender, address(0), _users[i], _amount[i], _distType);
unchecked {
i++;
}
}
}
function _distributionSameETH(address[] calldata _users, uint256 _amount, uint8 _distType) internal {
for (uint i = 0; i < _users.length;) {
TransferHelper.safeTransferXOC(_users[i], _amount);
emit DistributionEvent(msg.sender, address(0), _users[i], _amount, _distType);
unchecked {
i++;
}
}
}
function withdrawToken(
address token,
address recipient,
uint256 amount
) external onlyRole(DEFAULT_ADMIN_ROLE) {
TransferHelper.safeTransfer(token, recipient, amount);
}
function withdrawETH(address payable recipient, uint256 amount) external onlyRole(DEFAULT_ADMIN_ROLE) {
TransferHelper.safeTransferXOC(recipient, amount);
}
receive() external payable {}
}