I have written a very basic smart contract
It can accept ethers using a deposit function
ppl can withdraw from their balance using withdraw function
Everything works fine except withdraw function, when I test the contract over Ganance and Remix..
Screenshots are below
am I missing any thing here?
Adding the Code blocks
pragma solidity >= 0.4.25;
contract Bank {
uint256 private bankLiquidity; // Balance of whole contract
address public owner;
mapping(address => uint256) private customerBalance;
event fallbackCalled(address, uint256);
event deposit(address, uint256);
event withdrawal(address, uint256);
constructor() public {
owner = msg.sender;
}
modifier ownerOnly() {
require(msg.sender == owner, "message.sender is not the bank owner");
_;
}
/** Customer Deposit payable function */
function depositFunds(uint256 _value) external payable returns(bool){
require(_value > 0, "values not greater then zero");
customerBalance[msg.sender] += _value;
bankLiquidity += _value;
this.Balance = msg.value;
emit deposit(msg.sender, _value);
return true;
}
/** Pull and Push / Check Effects and Interactions patterns */
function withdrawFunds(uint256 _value) public payable {
// Checks
require(_value > 0, "a non Positive value");
// Checked the input values
require(_value <= customerBalance[msg.sender], "Insufficent customerBalance"); // Validate the Contract state
// Effects
customerBalance[msg.sender] -= _value;
// Update the state
// bankLiquidity -= _value;
// Interactions
/** Transfer is better way to send funds as it is equivalant to required(msg.sender.send(_value))
as well with limit quota of gas allocation 2300, it prevents for reentracny attack as well refunds any
remaining unused gas in case of any exceptions */
msg.sender.transfer(_value);
// Push funds
emit withdrawal(msg.sender, _value);
}
/** Fetch Bank Liquidity */
function getBankLiquidity() external view ownerOnly returns(uint256) {
return bankLiquidity;
}
/** Fetch Customer Balance */
function getCustomerBalance() public view returns(uint256) {
return customerBalance[msg.sender];
}
function () public payable {
emit fallbackCalled(msg.sender, msg.value);
}
}
Working Contract after fixes
pragma solidity >= 0.4.25;
/**
1 - Bank will hold total funds and only owner will able to get the details by call getter getBankLiquidity() 2 - Customers will have account balance 3 - Deposit payable function will work for everyone in Public 4 - Withdraw is a Pull and Push function and anyone with valid balance should able to withdraw funds 5 - Customers should able to check their balances using getCustomerBalance() 6 - There is a payable function */
contract Bank { address public owner; mapping(address => uint256) private customerBalance; event fallbackCalled(address, uint256); event deposit(address, uint256); event withdrawal(address, uint256);
constructor() public payable {
owner = msg.sender;
customerBalance[msg.sender] += msg.value;
}
modifier ownerOnly() {
require(msg.sender == owner, "message.sender is not the bank owner");
_;
}
/** Customer Deposit payable function */
function depositFunds() external payable returns(bool){
require(msg.value > 0, "values not greater then zero");
customerBalance[msg.sender] += msg.value;
emit deposit(msg.sender, msg.value);
return true;
}
/** Pull and Push / Check Effects and Interactions patterns */
function withdrawFunds(uint256 _value) public payable {
require(_value <= customerBalance[msg.sender], "account balance is low");
customerBalance[msg.sender] -= _value; // Update the state
msg.sender.transfer(_value); // Push funds
emit withdrawal(msg.sender, _value);
}
/** withdraw all funds and distory the contract*/
function withdrawFundsEmergency() external ownerOnly {
require(address(this).balance > 0, "account balance is low");
msg.sender.transfer(address(this).balance); // Push funds
emit withdrawal(msg.sender, address(this).balance);
selfdestruct(address(this));
}
/** Fetch Bank Liquidity */
function getBankLiquidity() external view ownerOnly returns(uint256) {
return address(this).balance;
}
/** Fetch Customer Balance */
function getCustomerBalance() public view returns(uint256) {
return customerBalance[msg.sender];
}
function () external payable {
emit fallbackCalled(msg.sender, msg.value);
}
}