1
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

contract SavingsContract is ReentrancyGuard{

address owner;
uint8 interest = 10;

struct Savers{
    address saver;
    uint savedAmount;
    uint dateOfDeposit;
}
Savers[] public savers;

constructor(){
    owner = msg.sender;
}
modifier onlyOwner{
    owner == msg.sender;
    _;
}

function depositMoney() payable public {
    require(msg.value <= (msg.sender).balance,"Insufficient funds");
    require(msg.value >= 10000, "Need to send min 10 000 Wei");
    savers.push(Savers(msg.sender, msg.value, block.timestamp));
}
function interestEarned() view public returns(uint){
    uint storedTime;
    for (uint i=0; i < savers.length; ++i){
        Savers storage savingsAccount = savers[i];
        if (msg.sender == savingsAccount.saver){
            storedTime = block.timestamp - savingsAccount.dateOfDeposit;
            return (savingsAccount.savedAmount);
        }
    }
}
function withdraw() external nonReentrant {
    uint storedTime;
    for (uint i=0; i < savers.length; ++i){
        Savers storage savingsAccount = savers[i];
        if (msg.sender == savingsAccount.saver){
            storedTime = block.timestamp - savingsAccount.dateOfDeposit;
            payable(msg.sender).transfer(savingsAccount.savedAmount);
            savers[i] = savers[savers.length - 1];
            savers.pop();
        }
    }
    revert("User not found!");
}

function viewContractBalance() public view returns(uint){
    return address(this).balance;
}
}

Hey guys, I have written a simple savings smart contract, which pays you interest for storing funds with them and I have decided to secure it against reentrancy with the ReentrancyGuard.sol library. However for some reason I get an error that the code is unreachable. Can you please help me out?

enter image description here

1 Answer 1

2

You can ignore that warning, the "unreachable" code is actually the initial state of the "modified" function

1.- the state of the modified withdraw function is _NOT_ENTERED before calling the function because the function hasn't been called

2.- once you call the function withdraw, the modifier code is executed

3.- in the modifier, everything that is before the _; is executed, therefore the function state is set to _ENTERED making it impossible to call the function again until its execution is finished (thats the reentrancy guard in action)

//ReentrancyGuard contract by OpenZeppelin

modifier nonReentrant() {
    // On the first call to nonReentrant, _notEntered will be true
    require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

    // Any calls to nonReentrant after this point will fail
    _status = _ENTERED;

    _; // <--- everything before this is executed

    // By storing the original value once again, a refund is triggered (see
    // https://eips.ethereum.org/EIPS/eip-2200)
    _status = _NOT_ENTERED;
}

I inspired my answer by this question and this medium post

2
  • So are you saying the the Reentrancy guard will work despite the warning?
    – f22daniel
    Oct 31, 2022 at 15:55
  • Yes, indeed :) the magic happens within the _;
    – Casareafer
    Oct 31, 2022 at 18:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.