Transfer Assignment

Fail fast with a require() check at the top, and decrement the user’s balance at the bottom.

function withdraw(uint amount) public returns (uint) {
    require(amount <= balance[msg.sender]);
    msg.sender.transfer(amount);
    balance[msg.sender] -= amount;
}

Solve by a require.

pragma solidity 0.7.5;

contract EtherBank {

mapping(address => uint) balances;

function deposit() public payable returns(uint) {
balances[msg.sender] += msg.value;
return balances[msg.sender];
}

function withdraw(uint amount) public payable returns(uint) {

require(balances[msg.sender] >= amount, "Not enough balance!");

balances[msg.sender] -= amount;

msg.sender.transfer(amount);
return balances[msg.sender];
}

function getbalance() view public returns(uint) {
    return balances[msg.sender];
}
}
1 Like
pragma solidity 0.7.5;

contract Bank{
    
  mapping(address=>uint)balance;
  
  address owner;
  
  modifier onlyOwner{
     require( msg.sender == owner);
     _;
  }
  
  constructor(){
      owner=msg.sender;
  }
  
  event transferTo(uint amount , address whoGets , address whoSent);
  event depositDone(uint amount , address sender);
  
  function deposit()public payable returns(uint){
     balance[msg.sender]+= msg.value;
     emit depositDone(msg.value , msg.sender);
      return balance[msg.sender];
  }
  
  function withdraw(uint _withd)public{
      require(balance[msg.sender]>= _withd , "insufficient funds");
    msg.sender.transfer(_withd);
    balance[msg.sender]-= _withd;
      
  }
  
  
  
   function getBalance()public view returns(uint){
       return balance[msg.sender];
   }
   
   
  function transfer(address recipient,uint amount)public{
      require(balance[msg.sender]>= amount);
      require(msg.sender != recipient);
      emit transferTo (amount , recipient , msg.sender);
  _transfer(msg.sender , recipient , amount);
  }
  
  function _transfer(address from, address to, uint amount)private {
      balance[from]-=amount;
      balance[to]+=amount;
  }
  
}

Hi @zero0_cero

Solidity works with wei amounts therefore you will send the amount in wei from your front end. Same thing if you call the function directly using truffle, you will pass the amount in wei.

1 Like

Hi @Emmerich

does it matter that “msg.sender.transfer(amount);” comes before “balance[msg.sender] -= amount;”? Is there a specific rule that stipulates the order or is it down to personal preference?

This is explained in the smart contract security course that I highly suggest to take once done solidity 101 and 201 because it’s really a good course.

You should always follow the pattern check/effect/interaction therefore you should decrease the user balance in the mapping before sending ether :slight_smile:

require(balance[msg.sender] >= amount, “Balance not sufficient”);
balance[msg.sender] -= amount;
msg.sender.transfer(amount);

Happy learning,
Dani

I originally messed up on the transfer feature where i wrote it as
transfer.msg.sender(amount);…nevertheless i understood what was required.

function withdraw(uint amount) public returns (uint) {
require(balance[msg.sender]>= amount);
balance[msg.sender] -= amount;
msg.sender.transfer(amount);
return balance[msg.sender];
}

1 Like

function withdraw(uint amount) public returns(uint){
require(balance[msg.sender] >= amount);
msg.sender.transfer(amount);
balance[msg.sender] = balance[msg.sender] - amount;
return balance[msg.sender];
}

1 Like
function withDraw(uint ammount) public returns (uint) {
    require(balance[msg.sender] >= ammount, "Invalid ammount to withdraw");
    uint previousBalance = balance[msg.sender];
    msg.sender.transfer(ammount);
    balance[msg.sender] = previousBalance - ammount;
    assert(balance[msg.sender] == previousBalance - ammount);
    return balance[msg.sender];
}
1 Like
function widthraw(uint _amount) public returns (uint){
    uint targetBalance;
    targetBalance = balance[msg.sender] - _amount;
    require(_amount>0);
    require(balance[msg.sender] >=_amount, "you don't have that much ETH");
    msg.sender.transfer(_amount);
    balance[msg.sender] -= _amount;
    assert(targetBalance == balance[msg.sender]);
    emit widthrawDone(_amount, msg.sender);
    return balance[msg.sender];
}
1 Like

So I need help, my code keeps getting an error. I even went to your github and embedded that code too and still it got an error.

pragma solidity 0.8.2;
contract Bank {
    
    mapping(address => uint) balance;
    
    event depositDone(uint amount, address indexed depositedTo);
    
    function deposit() public payable returns (uint)  {
        balance[msg.sender] += msg.value;
        emit depositDone(msg.value, msg.sender);
        return balance[msg.sender];
    }
    
    function withdraw(uint amount) public returns (uint){
        require(balance[msg.sender] >= amount);
        balance[msg.sender] -= amount;
        msg.sender.transfer(amount);
        return balance[msg.sender];
    }
    
    function getBalance() public view returns (uint){
        return balance[msg.sender];
    }
    
    function transfer(address recipient, uint amount) public {
        require(balance[msg.sender] >= amount, "Balance not sufficient");
        require(msg.sender != recipient, "Don't transfer money to yourself");
        
        uint previousSenderBalance = balance[msg.sender];
        
        _transfer(msg.sender, recipient, amount);
                
        assert(balance[msg.sender] == previousSenderBalance - amount);
    }
    
    function _transfer(address from, address to, uint amount) private {
        balance[from] -= amount;
        balance[to] += amount;
    }
    
}

It keeps telling me that my line msg.sender.transfer(amount); is wrong.
PLEASE HELP

Your assignment is to:
1) Make sure that the user can not withdraw more than their balance

2) Correctly adjust the balance of the user after a withdrawal

    function withdraw(uint amount) public returns (uint) {
        require(balance[msg.sender] >= amount, "Withdraw amount exceeds available funds.");
        msg.sender.transfer(amount);
        
        balance[msg.sender] -= amount;
    
        return balance[msg.sender];
    }
       
1 Like
    function withdraw(uint amount) public returns (uint) {
        require(balance[msg.sender] >= amount, "Balance not sufficient");
        msg.sender.transfer(amount);
        balance[msg.sender] = balance[msg.sender] - amount;
        return balance[msg.sender];
    }
1 Like

Created a checkBalance modifier that ensures the amount being withdrawn is not greater than the balance. Also added an assert to ensure that the previous balance == current balance + amount withdrawn.

pragma solidity 0.7.5;

contract Bank {
    
    mapping(address => uint) balance;
    
    address owner;
    
    event depositDone(uint amount, address indexed depositedTo);
    
    modifier onlyOwner {
        require(msg.sender == owner);
        _;
    }
    
    modifier costs(uint price){
        require(msg.value >= price);
        _;
    }
    
    modifier balanceCheck(uint amount){
        require(balance[msg.sender] >= amount, "Insuficient funds.");
        _;
    }
    
    constructor(){
        owner = msg.sender;
        balance[owner] = 0;
    }
    
    function deposit() public payable returns (uint){
        balance[msg.sender] += msg.value;
        emit depositDone(msg.value, msg.sender);
        return balance[msg.sender];
    }
    
    function withdraw(uint amount) public balanceCheck(amount) returns (uint) {
        uint previousBalance = balance[msg.sender];
        msg.sender.transfer(amount);
        balance[msg.sender] -= amount;
        assert(previousBalance == balance[msg.sender] + amount);
        return balance[msg.sender];
    }
    
    function getBalance() public view returns (uint){
        return balance[msg.sender];
    }
    
  
    function transfer(address recipient, uint amount) public {
        require(balance[msg.sender] >= amount);
        require(msg.sender != recipient);
        
        uint previousSenderBalance = balance[msg.sender];
        
        _transfer(msg.sender, recipient, amount);
        
        assert(balance[msg.sender] == previousSenderBalance - amount);
    }
    
    function _transfer(address from, address to, uint amount) private {
        balance[from] -= amount;
        balance[to] += amount;
    }
}
1 Like

Hey @solich

Good job, just few tips.
“Checks” have to be on the top of your function, you should always check the requirements first so that you do not waste any gas:

    require(_amount>0);
    require(balance[msg.sender] >=_amount, "you don't have that much ETH");

Happy coding,
Dani

1 Like

Hi @Samuel1

No need to use caps I always read all your messages :slight_smile:
Also please always report the error message returned by the compiler so that we can help you quickly.

In this case I am pretty sure that the error is here:
msg.sender.transfer(amount);

For Solidity 0.8, msg.sender is not considered payable by default anymore, therefore you have to cast it to payable in order to be able to call the method .transfer().

payable(msg.sender).transfer(amount);

Give it a try,
Dani

I used 0.8.2 which is why I have payable(msg.sender).transfer(amount);. I checked the solidity docs and found this solution. If there is a better way please let me know. I’m still not sure where these error messages such as “Balance not sufficient” are displayed.

pragma solidity 0.8.2;

contract Bank {
    mapping(address => uint) balance;
    
    address owner;
    
    event depositDone(uint amount, address indexed depositedTo);
    
    modifier onlyOwner {
        require(msg.sender == owner);
        _; //run the function
    }
    
    constructor() {
        owner = msg.sender;
    }
    
    function deposit() public payable returns(uint) {
        balance[msg.sender] += msg.value;
        emit depositDone(msg.value, msg.sender);
        return balance[msg.sender];
    } 
    
    function withdraw(uint amount) public returns(uint) {
        require(balance[msg.sender] >= amount, "Balance not sufficient");
        payable(msg.sender).transfer(amount);
        balance[msg.sender] -= amount;
    }
    
    function getBalance() public view returns(uint) {
        return balance[msg.sender];
    }
    
    function transfer(address recipient, uint amount) public {
        require(balance[msg.sender] >= amount, "Balance not sufficient");
        require(msg.sender != recipient, "Don't transfer money to yourself");
        
        uint prevSenderBalance = balance[msg.sender];
        
        _transfer(msg.sender, recipient, amount);
        
        assert(balance[msg.sender] == prevSenderBalance - amount);
    }
    
    function _transfer(address from, address to, uint amount) private {
        balance[from] -= amount;
        balance[to] += amount;
    }
}

Thanks for the advice !

pragma solidity 0.7.5;
contract myfirstbank {

mapping (address =>uint) balance;
balance[msg.sender] amount

function withdraw (uint amount) public returns uint {
require (balance [msg.sender] => amount “not enough funds”;

}

function deposit (uint amount) public returns uint{
require msg.sender.transfer(amount);
return balance[msg.sender];

}

*is wrong but i am new to all these and i need practice.Just post it to see what is my faults

function withdraw(uint amount) public returns (uint){
    require(balance[msg.sender] >= amount, "Too much withdrawn");
    balance[msg.sender] -= amount;
    msg.sender.transfer(amount);
    return balance[msg.sender];
}
1 Like