diff --git a/ExternalStorage.sol b/ExternalStorage.sol new file mode 100644 index 0000000..9665b08 --- /dev/null +++ b/ExternalStorage.sol @@ -0,0 +1,16 @@ +pragma solidity >=0.5.0 < 0.6.0; + +contract ExternalStorage { + + mapping(address => Member) public members; + mapping(address => bool ) public admins; + mapping(address => uint ) public balanceOf; + + struct Member { + string name; + bool isWhitelisted; + uint8 rating; + uint8 accumulatedPoints; + uint memberId; + } +} \ No newline at end of file diff --git a/contract.sol b/contract.sol index 95ec7b8..ce5b151 100644 --- a/contract.sol +++ b/contract.sol @@ -1,23 +1,34 @@ + pragma solidity >=0.5.0 < 0.6.0; -contract TokenReward { + +import "./ExternalStorage.sol"; + +contract TokenReward is ExternalStorage { - struct Member { - uint8 rating; - string name; - bool isWhitelisted; - uint8 accumulatedPoints; - } + string public symbol = "5ND"; + string public tokenName = "500NgDev"; + string public standard = "500NgDev Token v1.0"; + + uint private membersIds = 0; - address owner; - mapping(address => Member) public members; - mapping(address => uint ) public reward; - mapping(address => bool ) public admins; - mapping(address => uint ) public balances; + uint public tokenTotalSupply; + - event NewMember(string _name); + event NewMember(string _name, uint tagId); event Blacklisted(address indexed _member, string _name); - event NewReward(address indexed _member, uint reward); + event CNewMemeberReward(address indexed __memberToReward, uint _toId, uint _value); + event CNewMemRewardFromMem(address indexed _from, uint _fromId, address indexed _to, uint _toId, uint _value); event NewRating(address indexed _ratedBy, address indexed _memberRated, uint rating); + event Transfer(address _from, address _to, uint _memberId); + + address owner; + + constructor(uint256 _initialSupply) public { + owner = msg.sender; + admins[msg.sender] = true; + balanceOf[msg.sender] = _initialSupply; + tokenTotalSupply = _initialSupply; + } modifier OnlyOwner() { require(msg.sender == owner, "Only contract owner is allowed to call this function"); @@ -30,82 +41,72 @@ contract TokenReward { } modifier IsWhitelisted(address __member) { - Member memory memberStruct = members[__member]; - require(memberStruct.isWhitelisted == true, "This address is not whitelisted"); + require(members[__member].isWhitelisted == true, "This address is not whitelisted"); _; } - - constructor () public { - owner = msg.sender; - admins[msg.sender] = true; - } - + function addAdmin(address __newAdmin) public OnlyOwner returns(bool) { admins[__newAdmin] = true; return true; } - function AddMember(address __member, string memory __memberName) public OnlyAdminOrOwner returns(bool) { - Member memory __memberStruct; - __memberStruct.name = __memberName; - __memberStruct.isWhitelisted = true; - members[__member] = __memberStruct; + members[__member].name = __memberName; + members[__member].isWhitelisted = true; + membersIds += 1; - emit NewMember(__memberName); + members[__member].memberId = membersIds; + uint tagId = membersIds; + + emit NewMember(__memberName, tagId); return true; } function whiteListMember(address __member) public OnlyAdminOrOwner returns(bool) { - Member memory memberStruct = members[__member]; - memberStruct.isWhitelisted = true; + members[__member].isWhitelisted = true; return true; } function blackListMember(address __member) public OnlyAdminOrOwner returns(bool) { - Member memory memberStruct = members[__member]; - memberStruct.isWhitelisted = false; + members[__member].isWhitelisted = false; return true; } function isWhitelisted(address __member) view internal returns(bool) { - Member memory memberStruct = members[__member]; - return memberStruct.isWhitelisted; + return members[__member].isWhitelisted; } - + function rateMember(address __membertorate) public IsWhitelisted(__membertorate) returns(bool) { - Member memory __memberStruct = members[__membertorate]; uint8 ratingPoint; require(admins[msg.sender] || isWhitelisted(msg.sender), "You're not qualified to rate any member"); + if (admins[msg.sender]) { - ratingPoint = 3; + ratingPoint = 3; } - if (members[__membertorate].rating == 5) { + else if (members[__membertorate].rating == 5) { ratingPoint = 2; } else { ratingPoint = 1; } - __memberStruct.accumulatedPoints = __memberStruct.accumulatedPoints + ratingPoint; - (uint8 __memberPoint, uint8 __starRating) = calculateReward(__memberStruct.accumulatedPoints, __memberStruct.rating); - __memberStruct.accumulatedPoints = __memberPoint; - __memberStruct.rating = __starRating; + members[__membertorate].accumulatedPoints = members[__membertorate].accumulatedPoints + ratingPoint; + + (uint8 __memberPoint, uint8 __starRating) = calculateReward( members[__membertorate].accumulatedPoints, members[__membertorate].rating); + members[__membertorate].accumulatedPoints = __memberPoint; + members[__membertorate].rating = __starRating; emit NewRating(msg.sender, __membertorate, ratingPoint); return true; } - function rewardMember(address __memberToReward) public OnlyAdminOrOwner returns(bool) { - require(admins[__memberToReward] == false, "admins cannot be rewarded tokens"); - require(members[__memberToReward].rating >= 3, "member do not have a proven track record"); - balances[__memberToReward] = balances[__memberToReward] + 2; - return true; + function rewardMember() internal view OnlyAdminOrOwner returns(bool) { + return true; } function calculateReward(uint8 __pointsScored, uint8 __starRating) pure internal returns(uint8, uint8) { - if (__pointsScored < 10 ) { + if (__pointsScored < 15 ) { return (__pointsScored, __starRating); } uint8 __pointremained = __pointsScored % uint8(15); @@ -113,11 +114,38 @@ contract TokenReward { uint8 currentStarRating = __starRating + uint8(1); return (__pointremained, currentStarRating); } - return (__pointremained, __starRating - ); + return (__pointremained, __starRating); } -} - - - + + function memberToRewardMember(address _from, address _to) internal view IsWhitelisted(_from) returns(bool) { + require(isWhitelisted(msg.sender)); + require(_to != address(this)); + } + + function cRewardMember(address __memberToReward, uint _memberId, uint256 _value) public payable OnlyAdminOrOwner returns (bool success) { + require(_value != uint256(0)); + require(admins[__memberToReward] == false, "admins cannot be rewarded tokens"); + require(members[__memberToReward].rating >= 3, "member do not have a proven track record"); + require(members[__memberToReward].memberId == _memberId); + balanceOf[__memberToReward] = balanceOf[__memberToReward] + _value; + balanceOf[msg.sender] = balanceOf[msg.sender] - _value; + emit CNewMemeberReward( __memberToReward, _memberId, _value); + return true; + } + + function cMemberToRewardMember(address _from, uint _fromId, address _to, uint _toId, uint256 _value) public payable IsWhitelisted(_from) IsWhitelisted(_to) returns (bool success) { + require(_value != uint256(0)); + require(isWhitelisted(msg.sender)); + require(members[_to].rating >= 1, "member must have up to 1 rating"); + require(members[_from].memberId == _fromId); + require(members[_to].memberId == _toId); + require(balanceOf[_from] >= _value); + balanceOf[_from] = balanceOf[_from] - _value; + balanceOf[_to] = balanceOf[_to] + _value; + + emit CNewMemRewardFromMem( _from, _fromId, _to, _toId, _value); + return true; + } + +} \ No newline at end of file