diff --git a/destileria2.sol b/destileria2.sol index 89aa3ec40ca3683656ea0517d952aa0c9de5b7bf..d5216826d7824f325271353588cbc746802f25b7 100644 --- a/destileria2.sol +++ b/destileria2.sol @@ -11,11 +11,11 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/ */ -pragma solidity >0.4; +pragma solidity >=0.4; contract destileria2 { - enum UserType { UserOwner, UserDistributor, UserBeneficiary, UserNotFound }; + enum UserType { UserNotFound, UserOwner, UserDistributor, UserBeneficiary } // no hace falte 'indexed' ya que solamente va a haber // un evento de este tipo event deployed(address creator); @@ -42,7 +42,7 @@ contract destileria2 // Last time we did replenishAll, where did we stop? uint256 allstopmarker = 0; - constructor() payable public + constructor() payable { owner = msg.sender; // Because of the problems of using index 0 for real data @@ -60,8 +60,8 @@ contract destileria2 // Make first entry always empty (index 0) userIndex.push(UserEntry({ // This entry can be returned when no matches were found - addr: "0x0000000000000000000000000000000000000000", - userType: UserNotFound, + addr: address(0), + userType: UserType.UserNotFound, topUpLimit: 0, deleted: true })); @@ -77,7 +77,7 @@ contract destileria2 modifier onlyDistributorOrOwner { - require(contains(UserDistributor, msg.sender) || msg.sender == owner); + require(contains(UserType.UserDistributor, msg.sender) || msg.sender == owner); _; } @@ -86,12 +86,12 @@ contract destileria2 if (topuplimit == 0) return false; // User must not exist already - if (getUserType(addr) != UserNotFound) + if (getUserType(addr) != UserType.UserNotFound) return false; - if (topuplimit > getTopUpLimit(UserDistributor, msg.sender) + if (topuplimit > getTopUpLimit(UserType.UserDistributor, msg.sender)) return false; - emit added(msg.sender, addr, UserBeneficiary, topuplimit); - return !insert(UserBeneficiary, addr, topuplimit); + emit added(msg.sender, addr, UserType.UserBeneficiary, topuplimit); + return !insert(UserType.UserBeneficiary, addr, topuplimit); } function addDistributor(address addr, uint256 topuplimit) public onlyOwner returns(bool) @@ -99,28 +99,28 @@ contract destileria2 if (topuplimit == 0) return false; // User must not exist already - if (getUserType(addr) != UserNotFound) + if (getUserType(addr) != UserType.UserNotFound) return false; - emit added(msg.sender, addr, UserDistributor, topuplimit); - return !insert(UserDistributor, addr, topuplimit); + emit added(msg.sender, addr, UserType.UserDistributor, topuplimit); + return !insert(UserType.UserDistributor, addr, topuplimit); } function kick(UserType victimtype, address addr) private returns(bool) { if (!contains(victimtype, addr)) return false; - emit kicked(msg,sender, addr); + emit kicked(msg.sender, addr); return remove(victimtype, addr); } function kickDistributor(address addr) public onlyOwner returns(bool) { - return kick(UserDistributor, addr); + return kick(UserType.UserDistributor, addr); } function kickBeneficiary(address addr) public onlyDistributorOrOwner returns(bool) { - return kick(UserBeneficiary, addr); + return kick(UserType.UserBeneficiary, addr); } function changeLimit(address addr, uint256 topuplimit) public onlyDistributorOrOwner returns(bool) @@ -128,16 +128,16 @@ contract destileria2 uint256 pos = addressToUserEntryIndex[addr]; if (pos == 0) return false; - UserEntry entry = userIndex[pos]; - if (entry.userType != UserDistributor && entry.userType != UserBeneficiary) + UserEntry memory entry = userIndex[pos]; + if (entry.userType != UserType.UserDistributor && entry.userType != UserType.UserBeneficiary) return false; if (msg.sender != owner) { // Only our owner can change limits for Distributors - if (entry.userType == UserDistributor) + if (entry.userType == UserType.UserDistributor) return false; // Distributors must obey the limit - if (topuplimit > getTopUpLimit(UserDistributor, msg.sender) + if (topuplimit > getTopUpLimit(UserType.UserDistributor, msg.sender)) return false; } // all is fine - now we change the limit @@ -148,9 +148,9 @@ contract destileria2 function replenish(address victim, uint256 amount) public payable onlyDistributorOrOwner returns(bool) { - if (getUserType(victim) != UserBeneficiary) + if (getUserType(victim) != UserType.UserBeneficiary) return false; - uint256 topuplimit = getTopUpLimit(UserBeneficiary, victim); + uint256 topuplimit = getTopUpLimit(UserType.UserBeneficiary, victim); // Does the destination account have less than his limit? if (victim.balance + amount > topuplimit) return false; @@ -161,14 +161,14 @@ contract destileria2 if (address(this).balance < amount) return false; // Do the transfer and emit an event - address payable addrpayable = address(uint160(victim)) + address payable addrpayable = address(uint160(victim)); addrpayable.transfer(amount); emit replenished(msg.sender, victim, amount); return true; } // To use this function, you should set gasLimit to at least gasEstimate + 50000 - function replenishList(address[] accs, uint256[] amounts) public payable + function replenishList(address[] calldata accs, uint256[] calldata amounts) public payable { require(accs.length == amounts.length); uint256 i = 0; @@ -178,7 +178,7 @@ contract destileria2 if (accs[i].balance + amounts[i] < accs[i].balance) continue; // Don't allow amounts which will make the balance go above the top up limit. - if (accs[i].balance + amounts[i] < getTopUpLimit(UserBeneficiary, accs[i])) + if (accs[i].balance + amounts[i] < getTopUpLimit(UserType.UserBeneficiary, accs[i])) replenish(accs[i], amounts[i]); i++; } @@ -193,104 +193,106 @@ contract destileria2 if (allstopmarker >= userIndex.length) allstopmarker = 0; // The distributor's topuplimit (for owner this is ignored) - uint256 distlimit = getTopUpLimit(msg.sender); + uint256 distlimit = getTopUpLimit(UserType.UserDistributor, msg.sender); uint256 i = allstopmarker; while (++i != allstopmarker) { // If we get to the end of the list, loop back to the start of it if (i >= userIndex.length) i = 0; - entry = userIndex[i]; + UserEntry memory entry = userIndex[i]; // make sure we skip deleted entries if (entry.deleted) continue; // We only handle Beneficiaries - if (entry.userType != UserBeneficiary) + if (entry.userType != UserType.UserBeneficiary) continue; // + uint256 topuplimit; if (msg.sender == owner || entry.topUpLimit <= distlimit) topuplimit = entry.topUpLimit; else topuplimit = distlimit; // Does the user actually need to get topped up? - if (topuplimit > entry.key.balance) + if (topuplimit > entry.addr.balance) continue; // What's the difference? - uint256 amount = topuplimit - entry.key.balance; - replenish(entry.key, amount); + uint256 amount = topuplimit - entry.addr.balance; + replenish(entry.addr, amount); // Do we have enough ether to send? if (address(this).balance < amount) - continue + continue; // Do the transfer and emit an event - address payable addrpayable = address(uint160(entry.key)) + address payable addrpayable = address(uint160(entry.addr)); addrpayable.transfer(amount); - emit replenished(msg.sender, entry.key, amount); + emit replenished(msg.sender, entry.addr, amount); } return true; } function getDistributorLimit(address addr) public view returns(uint256) { - return getTopUpLimit(UserDistributor, addr); + return getTopUpLimit(UserType.UserDistributor, addr); } function getBeneficiaryLimit(address addr) public view returns(uint256) { - return getTopUpLimit(UserBeneficiary, addr); + return getTopUpLimit(UserType.UserBeneficiary, addr); } function getBeneficiariesCount() public view returns(uint256 count) { - uint256 count = 0; + count = 0; uint256 i = userIndex.length; while (i-- > 0) { if (userIndex[i].deleted) - continue - if (userIndex[i].userType == UserBeneficiary) - count++ + continue; + if (userIndex[i].userType == UserType.UserBeneficiary) + count++; } } function isBeneficiary(address addr) public view returns(bool) { - return contains(UserBeneficiary, addr); + return contains(UserType.UserBeneficiary, addr); } function isDistributor(address addr) public view returns(bool) { - return contains(UserDistributor, addr); + return contains(UserType.UserDistributor, addr); } function insert(UserType victimtype, address addr, uint256 value) private returns(bool replaced) { uint256 pos = addressToUserEntryIndex[addr]; - if(pos > 0 && !userIndex[pos].deleted) + if (pos > 0) { - userIndex[pos].topUpLimit = value; - self.position[addr].value = value; - return true; - } - UserEntry newEntry = UserEntry({ - addr: addr, - userType: victimtype, - topUpLimit: value, - deleted: false - }); - // recycle deleted entries, if possible - if (deletedEntries.length > 0) - { - pos = deletedEntries[deletedEntries.length-1]; - deletedEntries.pop(); - userIndex[pos] = newEntry; + assert(userIndex[pos].addr == addr); + assert(!userIndex[pos].deleted); + replaced = true; } else { - pos = userIndex.length; - userIndex.push( newEntry ); + replaced = false; + if (deletedEntries.length > 0) + { + // recycle deleted entries, if possible + pos = deletedEntries[deletedEntries.length-1]; + deletedEntries.pop(); + } + else + { + pos = userIndex.length; + userIndex.push(); + } } - addressToUserEntryIndex[addr] = pos; - return false; + userIndex[pos].addr = addr; + userIndex[pos].userType = victimtype; + userIndex[pos].topUpLimit = value; + userIndex[pos].deleted = false; + if (!replaced) + addressToUserEntryIndex[addr] = pos; } function remove(UserType victimtype, address addr) private returns(bool success) @@ -306,7 +308,7 @@ contract destileria2 return true; } - function getEntry(address addr) public view returns(UserEntry) + function getEntry(address addr) private view returns(UserEntry memory) { uint256 pos = addressToUserEntryIndex[addr]; // if no match, returns the 0th index, which is our "not found" entry @@ -320,17 +322,17 @@ contract destileria2 return userIndex[pos].userType; } - function getTopUpLimit(UserType victimtype, address addr) public returns(uint256) + function getTopUpLimit(UserType victimtype, address addr) public view returns(uint256) { - UserEntry uentry = getEntry(addr); + UserEntry memory uentry = getEntry(addr); if(victimtype == uentry.userType) - return uentry.typUpLimit; + return uentry.topUpLimit; return 0; } function contains(UserType victimtype, address addr) private view returns(bool) { - UserEntry uentry = getEntry(addr); + UserEntry memory uentry = getEntry(addr); if(victimtype == uentry.userType) return true; return false;