Transfer Assignment

Hey @jelle_van_der_meer

Don’t forget to decrease the user balance in the mapping otherwise your user will be able to drain your contract :slight_smile:

Happy learning,
Dani

1 Like

Hey @DearPhumi

Please check this faq that will guide you to post readable code in the forum:
https://forum.ivanontech.com/t/faq-how-to-post-code-in-the-forum/35357/3

Regarding your code don’t forget to decrease the user balance in the mapping otherwise your user will be able to drain your contract.

Cheers,
Dani

Thanks @dani —

I appreciate the correction on removing the payable modifier from the withdrawal() header. My transferTx is definitely being emitted to the log now.

Thanks for cruising the forums & helping us all out! It’s greatly appreciated :slight_smile:
—H

2 Likes
function withdraw(uint _amount) public
    {
        require(balance[msg.sender] >= _amount, "Balance not sufficient");
        payable(msg.sender).transfer(_amount);  
        balance[msg.sender] = balance[msg.sender] - _amount;
    }
1 Like

Solution for the withdraw function `
function withdraw(uint amount) public returns (uint){
//msg.sender is and address
require(balance[msg.sender]>= amount,“You have insufficent funds in your account”);
balance[msg.sender]-= amount;

msg.sender.transfer(amount);
return balance[msg.sender];

}`

Hey @matthew_ryan

Great solution well done.
Check this FAQ out next time you will post code in the forum, it will guide you step by step to post a well formatted code :slight_smile:

Happy learning,
Dani

    function withdraw(uint amount) public returns (uint) {
        require(balance[msg.sender] >= amount, "Can't withdraw more than your balance");
        msg.sender.transfer(amount);
        balance[msg.sender] -= amount;
        return balance[msg.sender];
    }  
2 Likes
function withdraw(uint amount) public onlyOwner returns (uint){
        require(balance[msg.sender] >= amount);
        msg.sender.transfer(amount);
        return balance[msg.sender];
    }

Hi @deniselbs

You are not sending ether to the user in your withdraw function :slight_smile:
Double check it.
Also please follow this FAQ that will guide you to post well formatted code in the forum:
https://forum.ivanontech.com/t/faq-how-to-post-code-in-the-forum/35357/2

Happy learning, let me know if you have question,
Dani

1 Like
pragma solidity 0.7.5;

contract Bank {
    mapping(address => uint) balance;
    address owner;
    event depositDone(uint amount, address indexed depositedTo);
    event transferTo(uint amount, address accountSender, address accountReceiver);
    
    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, "Unable to Withdraw. Balance is not sufficient!");
        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, "Unable to Transfer. Balance is not sufficient");
        require(msg.sender != recipient, "Do not transfer money to yourself");
        
        uint previousSenderBalance = balance[msg.sender];
        
        _transfer(msg.sender, recipient, amount);
        
        assert(balance[msg.sender] == previousSenderBalance - amount);
        emit transferTo(amount, msg.sender, recipient);
        
    }
    
    function _transfer(address from, address to, uint amount) private {
        balance[from] -= amount;
        balance[to] += amount;
    }
}
1 Like

I hope this is correct :slight_smile:

pragma solidity 0.7.5;

contract SolidityBasic{

    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(amount <= balance[msg.sender], "Amount to be withdrawn is more than deposited balance"); // This ensures that user can only withdraw his deposits, and not more. Answer to 1
        msg.sender.transfer(amount);
        balance[msg.sender] -= amount; // If users withdrawal is successful, amount withdrawn is subtracted to initial balance and is updated. Answer to 2
        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, "Insufficient funds");
        require(msg.sender != recipient, "Don't send 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;
    }
}
1 Like

Thank you for your feedback!

1 Like

An interesting note. I accidentally used a higher version compiler and got an error that the msg.sender address is NOT payable. This did not happen with the 0.7.5 compiler.

Does this mean this code could not run on the current Ethereum blockchain?

//SPDX-License-Identifier: UNLICENSED;
pragma solidity >= 0.8.0;

contract Bank {

mapping(address => uint) balance;
address owner;

event depositDone(uint amount, address indexed depositedTo);

event transferTo(uint amount, address accountSender, address accountReceiver);

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 is not sufficient!");
    balance[msg.sender] -= amount;
    msg.sender.transfer(amount);    // (1) footnote
    return balance[msg.sender];
    
}

function getBalance() public view returns (uint) {
    return balance[msg.sender];
}

}

(1) compiler version 0.8.0 does this: TypeError: “send” and “transfer” are only available for objects of type “address payable”, not “address”. --> contracts/Bank:31:9: | 31 | msg.sender.transfer(amount); | ^^^^^^^^^^^^^^^^^^^

Hi @Placebo, I think you replied to my assignment by mistake, anyway I’ll do my best to find the error. I’m not yet an expert at this but I’ll take a look at your code and see if it would work.

@Placebo Hi, there, I think I fixed your code.

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

I just removed “msg.sender.transfer(amount);” I’m not really sure if that answered your question, you should try asking others like @dan-i or @thecil.

Hi @Placebo

From solidity 0.8 msg.sender is not payable anymore.
You have to cast it as payable:

payable(msg.sender).transfer(_amount)

You can check the docs too where this is explained: https://docs.soliditylang.org/en/v0.8.0/080-breaking-changes.html

The global variables tx.origin and msg.sender have the type address instead of address payable . One can convert them into address payable by using an explicit conversion, i.e., payable(tx.origin) or payable(msg.sender) .

Happy learning,
Dani

pragma solidity 0.7.5;

contract Bank{
    
    mapping(address =>uint)balance;
     event despositeinfo(uint amount,address indexed holder); 

function desposit()public payable returns(uint){
       balance[msg.sender] +=msg.value;
       emit despositeinfo(msg.value,msg.sender);
       return balance[msg.sender];
   }
     function getbal()public view returns(uint){
         return balance[msg.sender];
     }
     
     function withdraw(uint amount)public returns(uint){
     require(balance[msg.sender]>=amount,"Balance not sufficient");
         balance[msg.sender] -=amount;
           msg.sender.transfer(amount);
         return balance[msg.sender];
            
     }
}
1 Like
function withdraw(uint amount) public returns(uint) {
        require(amount <= balance[msg.sender]);
        balance[msg.sender] -=amount;
        msg.sender.transfer(amount);
        return balance[msg.sender];
1 Like
 function withdraw (uint _amount) public payable returns (uint){
        require (balance[msg.sender] >= _amount, "Insufficient funds.");
        uint previous = balance[msg.sender];
        balance[msg.sender] -= _amount;
        msg.sender.transfer(_amount);
        assert (balance[msg.sender] == previous - _amount);
        return balance[msg.sender];
    }
    function withdraw(uint amount) public returns (uint){
        require(balance[msg.sender]>= amount, "Balance not sufficient");
        msg.sender.transfer(amount);
        balance[msg.sender] -= amount;
        return balance[msg.sender];
    }

Btw where I can see the return value of the withdraw() function on remix?

image