Assignment - SafeMath

pragma solidity >=0.7.5 <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);
    }
    
}
1 Like

yeah @Heyns this is indeed correct, howeevr as your smart contract skills grow you will be finding that in many cases (when doing defi) you will be inheriting contracts from other protocols. this is for many reasons, the first is that the defi contracts offered by large players like uniswap are well audited at this stage so many times you will use certain uniswap functions to do grunt work in your smart contracts instead of doing the implementation yourself as its both quicker and safer. so many times some production contracs will be using older version sof solidity below 0.8.0 so if your relying on older versions then u shoudl always use safemath just to be safe

2 Likes

nice one @stanmation. onto the next one now keep it up the final project in this course is amaaziinggg youll learn tons and really be at and advanced level if you can complete it

1 Like

My Bank contract code using SafeMath

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;
        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] -= 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] -= amount;
        balance[from] = balance[from].sub(amount);
        // balance[to] += amount;
        balance[to] = balance[to].add(amount);
    }
    
}
2 Likes
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(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);
    }
    
}
2 Likes

Hey guys! Here’s my solution to the SafeMath 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);
        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
bank.sol
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);
    }
    
}

1 Like
Bank.sol
pragma solidity 0.8.0;
pragma abicoder v2;
import "./Ownable.sol";

import "./SafeMath1.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] += amount;
        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[to] = balance[to].add(amount);
        //balance[from] -= amount;
        //balance[to] += amount;
    }
    
}
1 Like

My code below, simply swapped all math operations to use the SafeMath functions.

Thanks,
Luke

AssignmentSafeMath.sol
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 newBalance){
        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);
    }
    
}
Ownable.sol
pragma solidity >=0.4.4;


/*
 * Ownable
 *
 * Base contract with an owner.
 * Provides onlyOwner modifier, which prevents function from running if it is called by anyone other than the owner.
 */
contract Ownable {
  address public owner;

  constructor() {
    owner = msg.sender;
  }

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

  function transferOwnership(address newOwner) public onlyOwner {
    if (newOwner != address(0)) owner = newOwner;
  }

}
SafeMath.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, "SafeMath: division by zero");
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return mod(a, b, "SafeMath: modulo by zero");
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

hello Team, these are my files for the solution

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.13;
pragma abicoder v2;
import "./Destroyable.sol";
import "./SafeMath.sol";
import "./Ownable.sol";

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

contract Bank is Destroyable{
    using SafeMath for uint;
    GovermentInterface govermentInstance =  GovermentInterface(0xd8b934580fcE35a11B58C6D73aDeE468a2833fa8);

    mapping(address => uint) balance;
    address[] customers;
    uint public contractBalance = 0;

    event depositDone(uint amount, address indexed depositedTo);
    
    function deposit() public payable returns (uint){
        balance[msg.sender] = SafeMath.add(balance[msg.sender], msg.value);  
        emit depositDone(msg.value, msg.sender);
        return balance[msg.sender];
    }

    function getBalance(address _address) public view returns (uint){
        return balance[_address];  
    }
    
    function withdraw(uint amount) public onlyOwner returns (uint){
        require(balance[msg.sender] >= amount);
        balance[msg.sender] = SafeMath.sub(balance[msg.sender], amount);
        payable(msg.sender).transfer(amount);
        return balance[msg.sender];
    }

    function transfer (address _from, address _to) public payable{
        require(balance[_from] >= msg.value,"Balance not sufficient" );
        require(_from != _to," Can't be the same");
        uint previousSenderBalance = balance[msg.sender];
        
        uint value = SafeMath.mul(SafeMath.div(msg.value,100),99);
        uint commission = SafeMath.div(msg.value,100);
        contractBalance = SafeMath.add(contractBalance,commission);

        _transfer(_from, _to, value);
        
        govermentInstance.addTransaction{value: commission}(_from, _to, value);
        emit depositDone(value, _to);

        assert(balance[msg.sender] == SafeMath.sub(SafeMath.sub(previousSenderBalance, value), commission));
    }

    function _transfer(address from, address to, uint amount) private {
        balance[from] = SafeMath.sub(balance[from], amount);
        balance[to] = SafeMath.add(balance[to], amount);
    }
}

Regards

Alex

1 Like
pragma solidity 0.8.0;
pragma abicoder v2;
import "@openzeppelin/contracts/access/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);
    }
    
}
2 Likes

Here’s my solution, but as I read answers in the forum, it is no need to use safemath when using solidity 0.8.0 and above… hmmm

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] += 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] -= 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");

       

        uint256 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] -= amount;

     balance[to] += amount;

    }

   

}
1 Like

Pretty simple to implement but did see people saying its not necessary to use SafeMath with 0.8.0 and after. I suppose it depends on the use case etc but still probably best practice to use it?

My solution:

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);
    }
    
}
2 Likes
pragma solidity 0.8.15;

import "safemath.sol";
contract Bank{

    using SafeMath for uint;
    mapping(address => uint) balance;
    event Depositdone(uint amount, address indexed depositedTo);
    event Withdrawdone(uint amount, address indexed withdrawnTo);
    event Transferdone(uint amount, address indexed From, address indexed To);

    function deposit() public payable returns(address, uint){
        balance[msg.sender] = balance[msg.sender].sum(msg.value);
        emit Depositdone(msg.value, msg.sender);
        return(msg.sender,balance[msg.sender]);
    }

    function withdraw(uint amount) public returns(address, uint){
        require(balance[msg.sender] >= amount, "Insufficient Balance");
        balance[msg.sender] = balance[msg.sender].sub(amount);
        payable(msg.sender).transfer(amount);
        emit Withdrawdone(amount, msg.sender);
        return(msg.sender, balance[msg.sender]);
    }

    function getBalance(address _address) public view returns(uint){
        return balance[_address];
    }

    function transfer(address from, address to, uint amount) public{
        require(balance[from] >= amount, "Balance not sufficient");
        require(from != to, "sender and receiver addresses same");
        uint previousBalance = balance[from];
        _transfer(from, to, amount);
        emit Transferdone(amount, from, to);
        assert(balance[from].sum(amount) == previousBalance);
    }

    function _transfer(address from, address to, uint amount) private{
        balance[from] =  balance[from].sub(amount);
        balance[to] = balance[to].add(amount);
    }
}
1 Like

Bank Contract w SafeMath integrated:

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;
    }
    
}

2 Likes
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); //change the syntax for add/ subtract lines
        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);  // change
        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);  //change
        balance[to] = balance[from].add(amount);  //change
    }
   
}
1 Like

niceee mann. i really like this solution because you are experimenting with interfaces. well done. its a good sign that u understand their purpose this early on and how you can use interfaces to access functions in a smart contract without having to import the whole thing so great job. one thing you could do just to clean up your declaration of government is to make the address either a public or private global var (visibility is up to you)

address public GOVERNMENT_ADDRESS = 0xd8b934580fcE35a11B58C6D73aDeE468a2833fa8;
GovermentInterface govermentInstance =  GovermentInterface(GOVERNMENT_ADDRESS );

but this is just a nit pick. one other thing you can do is to make a require in your deposit function to make sure the user cannot input a negative or 0 amount

function deposit() public payable returns (uint){`
        require(msg.value > 0 , "amount too low");
        balance[msg.sender] = SafeMath.add(balance[msg.sender], msg.value);  
        emit depositDone(msg.value, msg.sender);
        return balance[msg.sender];
    }

you also dont need to return uints or addresses on state changing functions as you cannnot access return vars from such a function. sometimes a common approach is to return a bool like returns (bool _success) and if you function passes return this bool. but other than this great solution man keep it up

1 Like

Here is my solution for the assignment

1 Like

Hello, this is my solution for the assignment

// SPDX-License-Identifier: UNLICENSED

pragma solidity 0.7.5;

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(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] -= 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[from] -= amount;

          balance[to] = balance[to].add(amount);   //balance[to] += amount;

    }

   

}
1 Like

nice. you know you can copy and paste your code and directly paste it into the text editor here properly formatted