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;