From a930de0d75129227fac3c63b57ae757f765116e0 Mon Sep 17 00:00:00 2001 From: 1mile <1milehood@gmail.com> Date: Sat, 28 Dec 2019 13:00:50 +0100 Subject: [PATCH 1/9] added view to whiteListMember and blackListMember function --- contract.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contract.sol b/contract.sol index 95ec7b8..a98d549 100644 --- a/contract.sol +++ b/contract.sol @@ -56,14 +56,14 @@ contract TokenReward { return true; } - function whiteListMember(address __member) public OnlyAdminOrOwner returns(bool) { + function whiteListMember(address __member) public view OnlyAdminOrOwner returns(bool) { Member memory memberStruct = members[__member]; memberStruct.isWhitelisted = true; return true; } - function blackListMember(address __member) public OnlyAdminOrOwner returns(bool) { + function blackListMember(address __member) public view OnlyAdminOrOwner returns(bool) { Member memory memberStruct = members[__member]; memberStruct.isWhitelisted = false; return true; From 42e676f896ed51b1cacb353ba35753f09eacc2c1 Mon Sep 17 00:00:00 2001 From: nonseodion <38128301+nonseodion@users.noreply.github.com> Date: Sun, 29 Dec 2019 09:22:26 +0100 Subject: [PATCH 2/9] Contract.sol update with bug fixes, gas optimisation 1. Placed same value types close to reduce gas consumption in `Member` struct. 2. Added a `whitelist` event. 3. Changed the data location of `memberStruct` in `rateMember`, `blacklistMember` and `whitelistMember` to storage to make changes to `__memberStruct` take effect. --- contract.sol | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/contract.sol b/contract.sol index 95ec7b8..cb099a4 100644 --- a/contract.sol +++ b/contract.sol @@ -2,10 +2,10 @@ pragma solidity >=0.5.0 < 0.6.0; contract TokenReward { struct Member { - uint8 rating; string name; bool isWhitelisted; uint8 accumulatedPoints; + uint8 rating; } address owner; @@ -15,6 +15,7 @@ contract TokenReward { mapping(address => uint ) public balances; event NewMember(string _name); + event Whitelisted(address indexed _member, string _name); event Blacklisted(address indexed _member, string _name); event NewReward(address indexed _member, uint reward); event NewRating(address indexed _ratedBy, address indexed _memberRated, uint rating); @@ -57,15 +58,19 @@ contract TokenReward { } function whiteListMember(address __member) public OnlyAdminOrOwner returns(bool) { - Member memory memberStruct = members[__member]; + Member storage memberStruct = members[__member]; memberStruct.isWhitelisted = true; + + emit Whitelisted(__member, memberStruct.name); return true; } function blackListMember(address __member) public OnlyAdminOrOwner returns(bool) { - Member memory memberStruct = members[__member]; + Member storage memberStruct = members[__member]; memberStruct.isWhitelisted = false; + + emit Blacklisted(__member, memberStruct.name); return true; } @@ -76,7 +81,7 @@ contract TokenReward { } function rateMember(address __membertorate) public IsWhitelisted(__membertorate) returns(bool) { - Member memory __memberStruct = members[__membertorate]; + Member storage __memberStruct = members[__membertorate]; uint8 ratingPoint; require(admins[msg.sender] || isWhitelisted(msg.sender), "You're not qualified to rate any member"); if (admins[msg.sender]) { @@ -118,6 +123,3 @@ contract TokenReward { } } - - - From e9e033ab21e5a4ac5c0dcfe7078d243f8d584abf Mon Sep 17 00:00:00 2001 From: Jaylukmann Date: Sun, 29 Dec 2019 15:21:05 +0100 Subject: [PATCH 3/9] commented the codes,changed the order of state mutability and visibility on the iswhitelisted and calculateReward functions.Lastly,added onlyAdminOrOwner modifier to the rateMember functions --- contract.sol | 78 ++++++++++++++++++++++++++++------------------------ 1 file changed, 42 insertions(+), 36 deletions(-) diff --git a/contract.sol b/contract.sol index 95ec7b8..b6a6b35 100644 --- a/contract.sol +++ b/contract.sol @@ -7,45 +7,46 @@ contract TokenReward { bool isWhitelisted; uint8 accumulatedPoints; } - - address owner; - mapping(address => Member) public members; - mapping(address => uint ) public reward; - mapping(address => bool ) public admins; - mapping(address => uint ) public balances; - - event NewMember(string _name); - event Blacklisted(address indexed _member, string _name); - event NewReward(address indexed _member, uint reward); - event NewRating(address indexed _ratedBy, address indexed _memberRated, uint rating); - + //Mappings + address owner;//Our state variable + mapping(address => Member) public members;//each Member has an address + mapping(address => uint ) public reward;//captures the reward in uint of each address + mapping(address => bool ) public admins;//captures the addresses that are admins or not + mapping(address => uint ) public balances;//captures the balances in uint of each address + //Events + event NewMember(string _name);//Trigers when a new name is added + event Blacklisted(address indexed _member, string _name);//trigers new blacklisting + event NewReward(address indexed _member, uint reward);//trigers new reward and the member + event NewRating(address indexed _ratedBy, address indexed _memberRated, uint rating);//trigers new rating + //Modifiers modifier OnlyOwner() { require(msg.sender == owner, "Only contract owner is allowed to call this function"); - _; + _;//This allows only the owner to make changes } modifier OnlyAdminOrOwner() { require(admins[msg.sender] == true, "Only admins or contract owner is allowed to call this function"); - _; + _;//This allows only admin or owner to make changes } modifier IsWhitelisted(address __member) { - Member memory memberStruct = members[__member]; + Member memory memberStruct = members[__member];//Any member that is whitelisted is now called memberStruct require(memberStruct.isWhitelisted == true, "This address is not whitelisted"); - _; - } + _;//This allows only whitelisted member to make changes + } - constructor () public { + constructor () public {//Only the owner of the contract will call this owner = msg.sender; admins[msg.sender] = true; } - + + //This function helps to add a new Admin and can be called only by the owner function addAdmin(address __newAdmin) public OnlyOwner returns(bool) { admins[__newAdmin] = true; - return true; + return true; } - + //This adds a new member and can be called only by admins and the owner function AddMember(address __member, string memory __memberName) public OnlyAdminOrOwner returns(bool) { Member memory __memberStruct; __memberStruct.name = __memberName; @@ -54,40 +55,40 @@ contract TokenReward { emit NewMember(__memberName); return true; - } - - function whiteListMember(address __member) public OnlyAdminOrOwner returns(bool) { + } + //This function whitelist a member and can be called only by admins and the owner + function whiteListMember(address __member) public view OnlyAdminOrOwner returns(bool) { Member memory memberStruct = members[__member]; memberStruct.isWhitelisted = true; return true; } - - function blackListMember(address __member) public OnlyAdminOrOwner returns(bool) { + //This function blcacklist a member and can be called only by admins and the owner + function blackListMember(address __member) public view OnlyAdminOrOwner returns(bool) { Member memory memberStruct = members[__member]; memberStruct.isWhitelisted = false; return true; } - - function isWhitelisted(address __member) view internal returns(bool) { + // This function checks if a member is whitelisted or not + function isWhitelisted(address __member)internal view returns(bool) { Member memory memberStruct = members[__member]; return memberStruct.isWhitelisted; } - - function rateMember(address __membertorate) public IsWhitelisted(__membertorate) returns(bool) { + //This function rate a member and can be called by admins,owners,and whitelisted members + function rateMember(address __membertorate) public OnlyAdminOrOwner 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; } - if (members[__membertorate].rating == 5) { + if (members[__membertorate].rating == 5) { ratingPoint = 2; } else { - ratingPoint = 1; + ratingPoint = 1; } - __memberStruct.accumulatedPoints = __memberStruct.accumulatedPoints + ratingPoint; + __memberStruct.accumulatedPoints = __memberStruct.accumulatedPoints + ratingPoint; (uint8 __memberPoint, uint8 __starRating) = calculateReward(__memberStruct.accumulatedPoints, __memberStruct.rating); __memberStruct.accumulatedPoints = __memberPoint; @@ -96,15 +97,15 @@ contract TokenReward { emit NewRating(msg.sender, __membertorate, ratingPoint); return true; } - + //This function rewards members 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 calculateReward(uint8 __pointsScored, uint8 __starRating) pure internal returns(uint8, uint8) { + //This function helps calculate the members' reward base on point scored and star rating + function calculateReward(uint8 __pointsScored, uint8 __starRating) internal pure returns(uint8, uint8) { if (__pointsScored < 10 ) { return (__pointsScored, __starRating); } @@ -121,3 +122,8 @@ contract TokenReward { + + + + + From cae037d5f9c943e72fb576c3e8c5d41144797524 Mon Sep 17 00:00:00 2001 From: nonseodion <38128301+nonseodion@users.noreply.github.com> Date: Mon, 30 Dec 2019 08:48:12 +0000 Subject: [PATCH 4/9] Removed `onlyAdminOrOwner` from rateMember --- contract.sol | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/contract.sol b/contract.sol index 09efd73..6dfea50 100644 --- a/contract.sol +++ b/contract.sol @@ -67,7 +67,7 @@ contract TokenReward { } - //This function blcacklist a member and can be called only by admins and the owner + //This function blacklist a member and can be called only by admins and the owner function blackListMember(address __member) public view OnlyAdminOrOwner returns(bool) { Member storage memberStruct = members[__member]; memberStruct.isWhitelisted = false; @@ -81,8 +81,8 @@ contract TokenReward { Member memory memberStruct = members[__member]; return memberStruct.isWhitelisted; } - //This function rate a member and can be called by admins,owners,and whitelisted members - function rateMember(address __membertorate) public OnlyAdminOrOwner IsWhitelisted(__membertorate) returns(bool) { + //This function rate a member and can be called by whitelisted members + function rateMember(address __membertorate) public IsWhitelisted(__membertorate) returns(bool) { Member storage __memberStruct = members[__membertorate]; uint8 ratingPoint; require(admins[msg.sender] || isWhitelisted(msg.sender), "You're not qualified to rate any member"); @@ -122,4 +122,4 @@ contract TokenReward { } return (__pointremained, __starRating); } -} \ No newline at end of file +} From 92fca15130f182bf178ea337a63f61d18f743e01 Mon Sep 17 00:00:00 2001 From: Hendobox Date: Tue, 31 Dec 2019 17:19:05 +0100 Subject: [PATCH 5/9] From the token's description, no more than 2 tokens can be rewarded at a time. Added the option for admins to send rewards lower than 2 to encourage participants with decent effort --- contract.sol | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/contract.sol b/contract.sol index 6dfea50..e3bb5e0 100644 --- a/contract.sol +++ b/contract.sol @@ -104,10 +104,11 @@ contract TokenReward { return true; } //This function rewards members - function rewardMember(address __memberToReward) public OnlyAdminOrOwner returns(bool) { + function rewardMember(address __memberToReward, uint8 __rewardAmount) 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; + require(__rewardAmount <= 2, "Not more than 2 tokens can be rewarded"); + balances[__memberToReward] = balances[__memberToReward] + __rewardAmount; return true; } //This function helps calculate the members' reward base on point scored and star rating From f159867c87d105f98494d18bc190739a209e09de Mon Sep 17 00:00:00 2001 From: Hendobox Date: Tue, 31 Dec 2019 17:54:35 +0100 Subject: [PATCH 6/9] From the token's description, no more than 2 tokens can be rewarded at a time. There should be an option for admins to send lesser rewards for decent attempts from participants --- contract.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contract.sol b/contract.sol index e3bb5e0..50fd5cf 100644 --- a/contract.sol +++ b/contract.sol @@ -7,7 +7,7 @@ contract TokenReward { uint8 accumulatedPoints; uint8 rating; } - //Mappings + //Mapping address owner;//Our state variable mapping(address => Member) public members;//each Member has an address mapping(address => uint ) public reward;//captures the reward in uint of each address From c0afc66a843ba33af2d819e16682d2fffb8d17e6 Mon Sep 17 00:00:00 2001 From: Hendobox Date: Tue, 31 Dec 2019 18:05:01 +0100 Subject: [PATCH 7/9] From the token's description, no more than 2 tokens can be rewarded at a time. There should be an option for admins to send lesser rewards for decent attempts from participants --- contract.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contract.sol b/contract.sol index 50fd5cf..e3bb5e0 100644 --- a/contract.sol +++ b/contract.sol @@ -7,7 +7,7 @@ contract TokenReward { uint8 accumulatedPoints; uint8 rating; } - //Mapping + //Mappings address owner;//Our state variable mapping(address => Member) public members;//each Member has an address mapping(address => uint ) public reward;//captures the reward in uint of each address From c53c68021196af509899aca3bd3262d661178244 Mon Sep 17 00:00:00 2001 From: Hendobox <50964581+Hendobox@users.noreply.github.com> Date: Tue, 31 Dec 2019 18:08:14 +0100 Subject: [PATCH 8/9] Delete contract.sol --- contract.sol | 126 --------------------------------------------------- 1 file changed, 126 deletions(-) delete mode 100644 contract.sol diff --git a/contract.sol b/contract.sol deleted file mode 100644 index e3bb5e0..0000000 --- a/contract.sol +++ /dev/null @@ -1,126 +0,0 @@ -pragma solidity >=0.5.0 < 0.6.0; -contract TokenReward { - - struct Member { - string name; - bool isWhitelisted; - uint8 accumulatedPoints; - uint8 rating; - } - //Mappings - address owner;//Our state variable - mapping(address => Member) public members;//each Member has an address - mapping(address => uint ) public reward;//captures the reward in uint of each address - mapping(address => bool ) public admins;//captures the addresses that are admins or not - mapping(address => uint ) public balances;//captures the balances in uint of each address - //Events - event NewMember(string _name);//Trigers when a new name is added - event Whitelisted(address indexed _member, string _name); - event Blacklisted(address indexed _member, string _name);//trigers new blacklisting - event NewReward(address indexed _member, uint reward);//trigers new reward and the member - event NewRating(address indexed _ratedBy, address indexed _memberRated, uint rating);//trigers new rating - //Modifiers - modifier OnlyOwner() { - require(msg.sender == owner, "Only contract owner is allowed to call this function"); - _;//This allows only the owner to make changes - } - - modifier OnlyAdminOrOwner() { - require(admins[msg.sender] == true, "Only admins or contract owner is allowed to call this function"); - _;//This allows only admin or owner to make changes - } - - modifier IsWhitelisted(address __member) { - Member memory memberStruct = members[__member];//Any member that is whitelisted is now called memberStruct - require(memberStruct.isWhitelisted == true, "This address is not whitelisted"); - _;//This allows only whitelisted member to make changes - } - - constructor () public {//Only the owner of the contract will call this - owner = msg.sender; - admins[msg.sender] = true; - } - - //This function helps to add a new Admin and can be called only by the owner - function addAdmin(address __newAdmin) public OnlyOwner returns(bool) { - admins[__newAdmin] = true; - return true; - } - - //This adds a new member and can be called only by admins and the owner - function AddMember(address __member, string memory __memberName) public OnlyAdminOrOwner returns(bool) { - Member memory __memberStruct; - __memberStruct.name = __memberName; - __memberStruct.isWhitelisted = true; - members[__member] = __memberStruct; - - emit NewMember(__memberName); - return true; - } - //This function whitelist a member and can be called only by admins and the owner - function whiteListMember(address __member) public view OnlyAdminOrOwner returns(bool) { - Member storage memberStruct = members[__member]; - memberStruct.isWhitelisted = true; - - emit Whitelisted(__member, memberStruct.name); - return true; - } - - - //This function blacklist a member and can be called only by admins and the owner - function blackListMember(address __member) public view OnlyAdminOrOwner returns(bool) { - Member storage memberStruct = members[__member]; - memberStruct.isWhitelisted = false; - - emit Blacklisted(__member, memberStruct.name); - return true; - } - - // This function checks if a member is whitelisted or not - function isWhitelisted(address __member)internal view returns(bool) { - Member memory memberStruct = members[__member]; - return memberStruct.isWhitelisted; - } - //This function rate a member and can be called by whitelisted members - function rateMember(address __membertorate) public IsWhitelisted(__membertorate) returns(bool) { - Member storage __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; - } - 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; - - emit NewRating(msg.sender, __membertorate, ratingPoint); - return true; - } - //This function rewards members - function rewardMember(address __memberToReward, uint8 __rewardAmount) 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"); - require(__rewardAmount <= 2, "Not more than 2 tokens can be rewarded"); - balances[__memberToReward] = balances[__memberToReward] + __rewardAmount; - return true; - } - //This function helps calculate the members' reward base on point scored and star rating - function calculateReward(uint8 __pointsScored, uint8 __starRating) internal pure returns(uint8, uint8) { - if (__pointsScored < 10 ) { - return (__pointsScored, __starRating); - } - uint8 __pointremained = __pointsScored % uint8(15); - if (__starRating < 5) { - uint8 currentStarRating = __starRating + uint8(1); - return (__pointremained, currentStarRating); - } - return (__pointremained, __starRating); - } -} From 76445be1ba82b34093255d56d90058c884071cb0 Mon Sep 17 00:00:00 2001 From: Hendobox Date: Tue, 31 Dec 2019 18:18:35 +0100 Subject: [PATCH 9/9] From the token's description, no more than 2 tokens can be rewarded at a time. There should be an option for admins to send lesser rewards for decent attempts from participants --- contract.sol | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 contract.sol diff --git a/contract.sol b/contract.sol new file mode 100644 index 0000000..f137a72 --- /dev/null +++ b/contract.sol @@ -0,0 +1,126 @@ +pragma solidity >=0.5.0 < 0.6.0; +contract TokenReward { + + struct Member { + string name; + bool isWhitelisted; + uint8 accumulatedPoints; + uint8 rating; + } + //Mappings + address owner;//Our state variable + mapping(address => Member) public members;//each Member has an address + mapping(address => uint ) public reward;//captures the reward in uint of each address + mapping(address => bool ) public admins;//captures the addresses that are admins or not + mapping(address => uint ) public balances;//captures the balances in uint of each address + //Events + event NewMember(string _name);//Trigers when a new name is added + event Whitelisted(address indexed _member, string _name); + event Blacklisted(address indexed _member, string _name);//trigers new blacklisting + event NewReward(address indexed _member, uint reward);//trigers new reward and the member + event NewRating(address indexed _ratedBy, address indexed _memberRated, uint rating);//trigers new rating + //Modifiers + modifier OnlyOwner() { + require(msg.sender == owner, "Only contract owner is allowed to call this function"); + _;//This allows only the owner to make changes + } + + modifier OnlyAdminOrOwner() { + require(admins[msg.sender] == true, "Only admins or contract owner is allowed to call this function"); + _;//This allows only admin or owner to make changes + } + + modifier IsWhitelisted(address __member) { + Member memory memberStruct = members[__member];//Any member that is whitelisted is now called memberStruct + require(memberStruct.isWhitelisted == true, "This address is not whitelisted"); + _;//This allows only whitelisted member to make changes + } + + constructor () public {//Only the owner of the contract will call this + owner = msg.sender; + admins[msg.sender] = true; + } + + //This function helps to add a new Admin and can be called only by the owner + function addAdmin(address __newAdmin) public OnlyOwner returns(bool) { + admins[__newAdmin] = true; + return true; + } + + //This adds a new member and can be called only by admins and the owner + function AddMember(address __member, string memory __memberName) public OnlyAdminOrOwner returns(bool) { + Member memory __memberStruct; + __memberStruct.name = __memberName; + __memberStruct.isWhitelisted = true; + members[__member] = __memberStruct; + + emit NewMember(__memberName); + return true; + } + //This function whitelist a member and can be called only by admins and the owner + function whiteListMember(address __member) public view OnlyAdminOrOwner returns(bool) { + Member storage memberStruct = members[__member]; + memberStruct.isWhitelisted = true; + + emit Whitelisted(__member, memberStruct.name); + return true; + } + + + //This function blacklist a member and can be called only by admins and the owner + function blackListMember(address __member) public view OnlyAdminOrOwner returns(bool) { + Member storage memberStruct = members[__member]; + memberStruct.isWhitelisted = false; + + emit Blacklisted(__member, memberStruct.name); + return true; + } + + // This function checks if a member is whitelisted or not + function isWhitelisted(address __member)internal view returns(bool) { + Member memory memberStruct = members[__member]; + return memberStruct.isWhitelisted; + } + //This function rate a member and can be called by whitelisted members + function rateMember(address __membertorate) public IsWhitelisted(__membertorate) returns(bool) { + Member storage __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; + } + 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; + + emit NewRating(msg.sender, __membertorate, ratingPoint); + return true; + } + //This function rewards members + function rewardMember(address __memberToReward, uint8 __rewardAmount) 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"); + require(__rewardAmount <= 2, "Not more than 2 tokens can be rewarded"); + balances[__memberToReward] = balances[__memberToReward] + __rewardAmount; + return true; + } + //This function helps calculate the members' reward base on point scored and star rating + function calculateReward(uint8 __pointsScored, uint8 __starRating) internal pure returns(uint8, uint8) { + if (__pointsScored < 10 ) { + return (__pointsScored, __starRating); + } + uint8 __pointremained = __pointsScored % uint8(15); + if (__starRating < 5) { + uint8 currentStarRating = __starRating + uint8(1); + return (__pointremained, currentStarRating); + } + return (__pointremained, __starRating); + } +}