-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathMemberHelpers.sol
More file actions
143 lines (118 loc) · 5.4 KB
/
Copy pathMemberHelpers.sol
File metadata and controls
143 lines (118 loc) · 5.4 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
// SPDX-License-Identifier: MIT
pragma solidity =0.8.0;
import "./Members.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "./../IAuditToken.sol";
import "./IValidations.sol";
/**
* @title MemberHelpers
* Additional function for Members
*/
contract MemberHelpers is AccessControl {
using SafeMath for uint256;
using SafeERC20 for IERC20;
bytes32 public constant CONTROLLER_ROLE = keccak256("CONTROLLER_ROLE");
address public auditToken; //AUDT token
Members members; // Members contract
IValidations public validations; // Validation interface
mapping(address => uint256) public deposits; //track deposits per user
uint256 public minContribution = 5e21;
uint256 public maxContribution = 25e21;
uint256 public totalStaked;
event LogDepositReceived(address indexed from, uint256 amount);
event LogDepositRedeemed(address indexed from, uint256 amount);
event LogIncreaseDeposit(address user, uint256 amount);
event LogDecreaseDeposit(address user, uint256 amount);
constructor(address _members, address _auditToken) {
require(_members != address(0),"MemberHelpers:constructor - Member address can't be 0");
require(_auditToken != address(0), "MemberHelpers:setCohort - Cohort address can't be 0");
members = Members(_members);
auditToken = _auditToken;
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
}
/// @dev check if caller is a controller
modifier isController(string memory source) {
string memory msgError = string(abi.encodePacked("MemberHelpers(isController - Modifier):", source, "- Caller is not a controller"));
require(hasRole(CONTROLLER_ROLE, msg.sender),msgError);
_;
}
/// @dev check if user is validator
modifier isValidator(string memory source) {
string memory msgError = string(abi.encodePacked("NodeOperations(Modifier):", source, "- You are not a validator"));
require( members.userMap(msg.sender, Members.UserType(1)), msgError);
_;
}
function returnDepositAmount(address user) public view returns (uint256) {
return deposits[user];
}
function increaseDeposit(address user, uint256 amount) public isController("increaseDeposit") {
deposits[user] = deposits[user].add(amount);
emit LogIncreaseDeposit(user, amount);
}
function decreaseDeposit(address user, uint256 amount) public isController("decreaseDepoist") {
deposits[user] = deposits[user].sub(amount);
emit LogDecreaseDeposit(user, amount);
}
/**
* @dev Function to accept contribution to staking
* @param amount number of AUDT tokens sent to contract for staking
*/
function stake(uint256 amount) public {
require(amount > 0, "MemberHelpers:stake - Amount can't be 0");
if (members.userMap(msg.sender, Members.UserType(1))) {
require(
amount + deposits[msg.sender] >= minContribution,
"MemberHelpers:stake - Minimum contribution amount is 5000 AUDT tokens"
);
require(
amount + deposits[msg.sender] <= maxContribution,
"MemberHelpers:stake - Maximum contribution amount is 25000 AUDT tokens"
);
}
require(
members.userMap(msg.sender, Members.UserType(0)) ||
members.userMap(msg.sender, Members.UserType(1)) ||
members.userMap(msg.sender, Members.UserType(2)),
"Staking:stake - User has been not registered as a validator or enterprise."
);
IERC20(auditToken).safeTransferFrom(msg.sender, address(this), amount);
deposits[msg.sender] = deposits[msg.sender].add(amount);
totalStaked = totalStaked.add(amount);
emit LogDepositReceived(msg.sender, amount);
}
/**
* @dev Function to redeem contribution.
* @param amount number of tokens being redeemed
*/
function redeem(uint256 amount) public {
if (members.userMap(msg.sender, Members.UserType(0))) {
uint256 outstandingVal = validations.outstandingValidations(msg.sender);
if (outstandingVal > 0)
// div(1e4) to adjust for four decimal points
require(
deposits[msg.sender].sub(
members
.enterpriseMatch()
.mul(members.amountTokensPerValidation())
.mul(outstandingVal)
.div(1e4)
) >= amount,
"MemberHelpers:redeem - Your deposit will be too low to fullfil your outstanding payments."
);
}
deposits[msg.sender] = deposits[msg.sender].sub(amount);
totalStaked = totalStaked.sub(amount);
IERC20(auditToken).safeTransfer(msg.sender, amount);
emit LogDepositRedeemed(msg.sender, amount);
}
/**
* @dev to be called by administrator to set Validation address
* @param _validations validation contract address
*/
function setValidation(address _validations) public isController("setValidation") {
require( _validations != address(0), "MemberHelpers:setValidation - Validation address can't be 0");
validations = IValidations(_validations);
}
}