Assignment - SafeMath

pragma solidity 0.8.0;
pragma abicoder v2;
import "./Ownable.sol";
import "./safemath.sol";

contract Bank is Ownable {
    
    mapping(address => uint) balance;
    address[] customers;

    using SafeMath for uint256;
    
    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 onlyOwner returns (uint){
        require(balance[msg.sender] >= amount);
        balance[msg.sender] -= amount;
        payable(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;
    }
    
}
1 Like

My only differences with your solutions are the following 2 :

  • I editted the assert statement as follow : assert(balance[msg.sender] == sub(previousSenderBalance, amount);

  • I introduced the library using uint256 instead of just uint.

Does this make any difference ?

//SPDX-License-Identifier: UNLICENSED 
pragma solidity 0.8.7;
pragma abicoder v2;
import "./Ownable.sol";
import "./Safemath.sol";


contract Bank is Ownable {

    using SafeMath for uint256;
    
    mapping(address => uint) balance;
    address[] customers;
    
    event depositDone(uint amount, address indexed depositedTo);
    
    function deposit() public payable returns (uint)  {
        balance[msg.sender] =  balance[msg.sender].add(msg.value) //balance[msg.sender] += msg.value;
        emit depositDone(msg.value, msg.sender);
        return balance[msg.sender];
    }
    
    function withdraw(uint amount) public onlyOwner returns (uint){
        require(balance[msg.sender] >= amount);
        balance[msg.sender] = balance[msg.sender].sub(amount)//balance[msg.sender] -= amount;
        payable(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);
        assert(balance[msg.sender] == sub(previousSenderBalance, amount);
    }
    
    function _transfer(address from, address to, uint amount) private {
        balance[from] = balance[from].sub(amount);//balance[from] -= amount;
        balance[to] = balance[to].add(amount);//balance[to] += amount;
    }
    
}
1 Like

While testing regular or unsafe math, I noticed when subtracting from 0, it seemed to revert at least starting in solidity 0.8.0 can anyone comment on this? I tested addition with uint8 and found the the it also reverts

Here is my code for the assignment

pragma solidity 0.8.0;
pragma abicoder v2;
import "./Ownable.sol";
import "./Safemath.sol";

contract Bank is Ownable {
    using SafeMath for uint;

    mapping(address => uint) balance;
    address[] customers;
    
    event depositDone(uint amount, address indexed depositedTo);
    
    function deposit() public payable returns (uint)  {
        balance[msg.sender] = balance[msg.sender].add(msg.value);
        // balance[msg.sender] += msg.value;
        emit depositDone(msg.value, msg.sender);
        return balance[msg.sender];
    }
    
    function withdraw(uint amount) public onlyOwner returns (uint){
        require(balance[msg.sender] >= amount);
        balance[msg.sender] = balance[msg.sender].sub(amount);
        payable(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] = balance[from].sub(amount);
        balance[to] = balance[to].add(amount);
    }
    
}```
1 Like
pragma solidity 0.8.0;

//pragma abicoder v2;
import "./Ownable.sol";
import "./SafeMath.sol";

contract Bank is Ownable {

    using SafeMath for uint256;
    
    mapping(address => uint) balance;
    address[] customers;
    
    event depositDone(uint amount, address indexed depositedTo);
    
    function deposit() public payable returns (uint)  {
        balance[msg.sender].add(msg.value);
        emit depositDone(msg.value, msg.sender);
        return balance[msg.sender];
    }
    
    function withdraw(uint amount) public onlyOwner returns (uint){
        require(balance[msg.sender] >= amount);
        balance[msg.sender].sub(amount);
        payable(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.sub(amount));
    }
    
    function _transfer(address from, address to, uint amount) private view{
        balance[from].sub(amount);
        balance[to].add(amount);
    }
    
}
1 Like

thanks!! Iā€™ll look into that
later on in the course I found this warning that I donā€™t really knows what it means
the line that throws the warning is : msg.sender.call{value:_amount}("");
and the warning is: Return value of low-level calls not used.
Thanks in advance
Ale

1 Like

Here is my SafeMath implementation:

pragma solidity 0.8.0;
pragma abicoder v2;
import "./Ownable.sol";
import "./Safemath.sol";

contract Bank is Ownable {

    using SafeMath for uint;
    
    mapping(address => uint) balance;
    address[] customers;
    
    event depositDone(uint amount, address indexed depositedTo);
    
    function deposit() public payable returns (uint)  {
        balance[msg.sender] = balance[msg.sender].add(msg.value);
        emit depositDone(msg.value, msg.sender);
        return balance[msg.sender];
    }
    
    function withdraw(uint amount) public onlyOwner returns (uint){
        require(balance[msg.sender] >= amount);
        balance[msg.sender] = balance[msg.sender].sub(msg.value);
        payable(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] = balance[from].add(amount);
        balance[to] = balance[to].sub(amount);
    }
    
}

If something i wrong, please let me know

pragma solidity 0.8.0;
pragma abicoder v2;
import "./Ownable.sol";
import "./safemath.sol"

contract Bank is Ownable {

    using SafeMath for uint256
    
    mapping(address => uint) balance;
    address[] customers;
    
    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 onlyOwner returns (uint){
        require(balance[msg.sender] >= amount);
        balance[msg.sender] -= amount;
        payable(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;
    }
    
}
1 Like

hey Mildo can u past your exact code for this ill take a look

Safemath Code

pragma solidity 0.8.0;
pragma abicoder v2;
import "./Ownable.sol";
import "./Safemath.sol"

contract Bank is Ownable {
    using SafeMath for uint256

    mapping(address => uint) balance;
    address[] customers;
    
    event depositDone(uint amount, address indexed depositedTo);
    
    function deposit() public payable returns (uint)  {
        balance[msg.sender] = balance[msg.sender].add(msg.value);
        emit depositDone(msg.value, msg.sender);
        return balance[msg.sender];
    }
    
    function withdraw(uint amount) public onlyOwner returns (uint){
        require(balance[msg.sender] >= amount);
        balance[msg.sender] = balance[msg.sender].sub(msg.value);
        payable(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] = balance[from].add(amount);
        balance[to] = balance[to].sub(amount)
    }
    
}


1 Like

Hello @mcgrane5
this is the contract where the warning/error appears and i donā€™t understand it

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.14;

import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

contract Wallet is AccessControl, ReentrancyGuard{
    using Counters for Counters.Counter;
    using SafeMath for uint256;

    bytes32 public constant TOKEN_REGISTRATOR_ROLE = keccak256("TOKEN_REGISTRATOR_ROLE");
    bytes32 public constant TOKEN_REGISTRATOR_ADMIN_ROLE = keccak256("TOKEN_REGISTRATOR_ADMIN_ROLE");
    bytes32 public constant CONTRACT_DESTROYER_ROLE = keccak256("CONTRACT_DESTROYER_ROLE");

    // maps address to token-ticker to amounts
    // usa bytes32 en lugar de string por que en solidity no se pueden comparar strings
    mapping(address => mapping(bytes32 => uint256)) public balances;

    struct Token{
        bytes32 ticker;
        address tokenAddress;
    }

    bytes32[] public tokenList; // List with all the tickers registered -- ability to iterate thru all the tokens
    mapping(bytes32 => Token) public tokenMapping; //for each ticker get the token 
    
    event TokenRegisteredEvent(bytes32 indexed ticker, address indexed tokenAddress);
    event TokenDepositApproved(bytes32 indexed ticker, uint amount, address account);
    event TokenDepositRejected(bytes32 indexed ticker, uint amount, address account);
    event TokenDepositDone(bytes32 indexed ticker, uint amount, address account);

    event DebugBalanceOf(bytes32 indexed ticker, uint amount, address account);

    modifier tokenExist(bytes32 token){
        require(tokenMapping[token].tokenAddress != address(0), "Token should be registered first");
        _;
    }

    constructor(){
        _grantRole(TOKEN_REGISTRATOR_ADMIN_ROLE, _msgSender());
        _grantRole(TOKEN_REGISTRATOR_ROLE, _msgSender());
        _grantRole(DEFAULT_ADMIN_ROLE, _msgSender());
        _setRoleAdmin(TOKEN_REGISTRATOR_ROLE, TOKEN_REGISTRATOR_ADMIN_ROLE);
        _grantRole(CONTRACT_DESTROYER_ROLE, _msgSender());
    }

    function balanceOf(bytes32 _ticker, address user) public returns (uint256){
        emit DebugBalanceOf(_ticker, balances[user][_ticker] , user);
        return balances[user][_ticker];
    }

    function registerToken(bytes32 _ticker, address _tokenAddress) external onlyRole(TOKEN_REGISTRATOR_ROLE){
        tokenMapping[_ticker] =Token(_ticker, _tokenAddress);
        tokenList.push(_ticker);
        emit TokenRegisteredEvent(_ticker, _tokenAddress);
    }

    function deposit(uint _amount, bytes32 _ticker) tokenExist(_ticker) external {
        
        balances[msg.sender][_ticker] = SafeMath.add(balances[msg.sender][_ticker], _amount);
        IERC20 token = IERC20(tokenMapping[_ticker].tokenAddress);
        uint allowence = token.allowance(_msgSender(), address(this)); 
        if (allowence >= _amount){
            emit TokenDepositApproved(_ticker, _amount, msg.sender);
            IERC20(tokenMapping[_ticker].tokenAddress).transferFrom(msg.sender, address(this), _amount);
            emit TokenDepositDone(_ticker, _amount, msg.sender);
        }else{
            emit TokenDepositRejected(_ticker, _amount, msg.sender);
            balances[msg.sender][_ticker] = SafeMath.sub(balances[msg.sender][_ticker], _amount);
        }
        
    }
    function depositEth() payable external {
        balances[msg.sender][bytes32("ETH")] = SafeMath.add(balances[msg.sender][bytes32("ETH")], msg.value);
    }

    function withdrawEth(uint _amount) payable external nonReentrant {
        require(balances[msg.sender][bytes32("ETH")] > _amount, "Insufficient balance");
        balances[msg.sender][bytes32("ETH")] = SafeMath.sub(balances[msg.sender][bytes32("ETH")], msg.value);
        msg.sender.call{value:_amount}("");
    }

    function withdraw(uint _amount, bytes32 _ticker) tokenExist(_ticker) external{
        require( balances[msg.sender][_ticker] >= _amount, "balance should be bigger than the amount");

        balances[msg.sender][_ticker] = SafeMath.sub(balances[msg.sender][_ticker], _amount);
        IERC20(tokenMapping[_ticker].tokenAddress).transfer(msg.sender, _amount);
    }
    
    function destroy()  onlyRole(CONTRACT_DESTROYER_ROLE) external {
        selfdestruct(payable(_msgSender()));
    }
}

Regards
Mildo

1 Like

i looked into this. and this was just a warning so you dont need to worry. what its refferring to is thr msg.sender.call() has a boolean return value based on if the transfer has failed or not. this return value can be used to error handle. but since your not using it here thats why the warning is getting thrown

1 Like

Bank with Safemath

Summary
pragma solidity 0.8.0;
pragma abicoder v2;
import "./Ownable.sol";
import "./safemath.sol";

contract Bank is Ownable {
    
    using SafeMath for uint256;

    mapping(address => uint256) balance;
    address[] customers;
    
    event depositDone(uint256 amount, address indexed depositedTo);
    
    function deposit() public payable returns (uint256)  {
        balance[msg.sender] = balance[msg.sender].add(msg.value);
        emit depositDone(msg.value, msg.sender);
        return balance[msg.sender];
    }
    
    function withdraw(uint256 amount) public onlyOwner returns (uint256){
        require(balance[msg.sender] >= amount);
        balance[msg.sender] = balance[msg.sender].sub(amount);
        payable(msg.sender).transfer(amount);
        return balance[msg.sender];
    }
    
    function getBalance() public view returns (uint256){
        return balance[msg.sender];
    }
    
    function transfer(address recipient, uint256 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, uint256 amount) private {
        balance[from] = balance[from].sub(amount);
        balance[to] = balance[to].add(amount);
    }
    
}
1 Like

Hereā€™s my solution for using Safemath on the Bank contract:

pragma solidity 0.8.0;
pragma abicoder v2;
import "Ownable.sol";
import "Safemath.sol";

contract Bank is Ownable {

    using SafeMath for uint;
    
    mapping(address => uint) balance;
    address[] customers;
    
    event depositDone(uint amount, address indexed depositedTo);
    
    function deposit() public payable returns (uint)  {
        balance[msg.sender] = balance[msg.sender].add(msg.value);//balance[msg.sender] += msg.value;
        emit depositDone(msg.value, msg.sender);
        return balance[msg.sender];
    }
    
    function withdraw(uint amount) public onlyOwner returns (uint){
        require(balance[msg.sender] >= amount);
        balance[msg.sender] = balance[msg.sender].sub(amount);//balance[msg.sender] -= amount;
        payable(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] = balance[from].sub(amount);//balance[from] -= amount;
        balance[to] = balance[to].add(amount);//balance[to] += amount;
    }
    
}

Also, Iā€™ve a question for the team:

What do you think are best practices for not loosing files in Remix? Any thoughts on how to best organize a massive workflow here?

I just accidently lost some files. Probably because I cleared my browser history of the last hour, which I only do in emergencies, like being stuck on an error page in this forum and not being able to go back. Unfortunately downloading my workspace didnā€™t help for recovery. I guess because all files were just free floating inside the workspace and not archived in the default contracts folder.
Of course Remix is for editing and learning, so thereā€™s no problem starting over. But I just like to keep track of my files for future study reference.

Here is my assignment for Safemath

pragma solidity 0.8.7;
pragma abicoder v2;
import "./Ownable.sol";
import "safemath.sol";

contract Bank is Ownable {
    
    using safemath for uint;

    mapping(address => uint) balance;
    address[] customers;
    
    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 onlyOwner returns (uint){
        require(balance[msg.sender] >= amount);
        balance[msg.sender] -= amount;
        payable(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;
    }
    
}

Safemath is not needed in Solidity 0.8! :laughing:

// SPDX-License-Identifier: MIT
pragma solidity 0.8.0;
pragma abicoder v2;
import "./Ownable.sol";
import "./safemath.sol";


contract Bank is Ownable {

    using SafeMath for uint;

    mapping(address => uint) balance;
    address[] customers;
    
    event depositDone(uint amount, address indexed depositedTo);
    
    function deposit() public payable returns (uint)  {
        balance[msg.sender] = balance[msg.sender].add(msg.value);
        emit depositDone(msg.value, msg.sender);
        return balance[msg.sender];
    }
    
    function withdraw(uint amount) public onlyOwner returns (uint){
        require(balance[msg.sender] >= amount);
        balance[msg.sender] = balance[msg.sender].sub(amount);
        payable(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] = balance[from].sub(amount);
        balance[to] = balance[to].add(amount);
    }
    
}
1 Like
// SPDX-License-Identifier: MIT
pragma solidity 0.8.0;
pragma abicoder v2;
import "../201_Ownable.sol";
import "./SafeMath_OZ.sol";

contract Bank is Ownable {

    using SafeMath for uint;
    
    mapping(address => uint) balance;
    address[] customers;
    
    event depositDone(uint amount, address indexed depositedTo);
    
    function deposit() public payable returns (uint)  {
        balance[msg.sender] = balance[msg.sender].add(msg.value);
        emit depositDone(msg.value, msg.sender);
        return balance[msg.sender];
    }
    
    function withdraw(uint amount) public onlyOwner returns (uint){
        require(balance[msg.sender] >= amount);
        balance[msg.sender] = balance[msg.sender].sub(amount);
        payable(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] = balance[from].sub(amount);
        balance[to] = balance[to].add(amount);
    }
    
}
1 Like

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import ā€œ./Ownable.solā€;
import ā€œ./Destroyable.solā€;
import ā€œ./SafeMath.solā€;

interface GovernmentInterface {
function addTransaction(address _from, address _to, uint _amount) external payable;
}

contract Bank is Destroyable {
event Transfer(address from, address to, uint256 amount);
event BalanceAdded(address from, uint256 to);
event DepositDone(address from, uint256 value);

mapping(address => uint256) balance;
using SafeMath for uint256;

GovernmentInterface governmentInstance = GovernmentInterface(0x9A84568a5EAAEa0363527E9dBB5AeE7d8324df59);

function deposit() public payable returns (uint256) {
    balance[msg.sender] = balance[msg.sender].add(msg.value);
    emit DepositDone(msg.sender, msg.value);
    return balance[msg.sender];
}

function withdraw(uint256 _amount) public payable returns (uint256) {
    require(balance[msg.sender] >= _amount, "not enough balance");
    balance[msg.sender] = balance[msg.sender].sub(_amount);
    payable(msg.sender).transfer(_amount);
    return balance[msg.sender];
}

function transfer(address _to, uint256 _amount) public {
    require(balance[msg.sender] >= _amount, "not enough balance");
    require(msg.sender != _to, "Don't transfer money to yourself");
    _transfer(msg.sender, _to, _amount);
    
    governmentInstance.addTransaction{value: 1 ether}(msg.sender, _to, _amount);
    emit Transfer(msg.sender, _to, _amount);
}

function _transfer(
    address _from,
    address _to,
    uint256 _amount
) private {
    balance[_from] = balance[_from].sub(_amount);
    balance[_to] += balance[_to].sub(_amount);
}

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

}

pragma solidity 0.8.0;
pragma abicoder v2;
import "./Ownable.sol";
import "./safemath.sol";

contract Bank is Ownable {

    using SafeMath for uint;
    
    mapping(address => uint) balance;
    address[] customers;
    
    event depositDone(uint amount, address indexed depositedTo);
    
    function deposit() public payable returns (uint)  {
        balance[msg.sender] = balance[msg.sender].add(msg.value);
        emit depositDone(msg.value, msg.sender);
        return balance[msg.sender];
    }
    
    function withdraw(uint amount) public onlyOwner returns (uint){
        require(balance[msg.sender] >= amount);
        balance[msg.sender] = balance[msg.sender].sub(amount);
        payable(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.sub(amount));
    }
    
    function _transfer(address from, address to, uint amount) private {
        balance[from] = balance[from].sub(amount);
        balance[to] = balance[to].add(amount);
    }
    
}

All working! Regards

1 Like
contract Bank is Ownable {
    
    using SafeMath for uint;

    mapping(address => uint) balance;
    address[] customers;
    
    event depositDone(uint amount, address indexed depositedTo);
    
    function deposit() public payable returns (uint)  {
        balance[msg.sender] = balance[msg.sender].add(msg.value);
        emit depositDone(msg.value, msg.sender);
        return balance[msg.sender];
    }
    
    function withdraw(uint amount) public onlyOwner returns (uint){
        require(balance[msg.sender] >= amount);
        balance[msg.sender] = balance[msg.sender].sub(amount);
        payable(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.sub(amount));
    }
    
    function _transfer(address from, address to, uint amount) private {
        balance[from] = balance[from].sub(amount);
        balance[to] = balance[to].add(amount);
    }
    
}
1 Like