// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0 <0.9.0; // The goal here is to create a multi-sig wallet safe // Eventually the deployer will have to decide how many sigs are needed for the tranx to be approved // The deployer will also be able to add/remove the allowed addresses // BEFORE we get to that, let's create a SIMPLE wallet safe // We'll expand upon its functionalities to make it a multi-sig safe bit by bit // Create a cotract called Safe that: (This is how to make a wallet) // 1 - Keeps track of users balance (balances mapping) // 2 - Shows how many users have funds in the Safe // 3 - Each user is represented by a Struct with at least: address, balance, unique ID // 4 - A user can deposit, withdraw and tranfer funds to other users // 5 - Create a modifier called "hasFunds" instead of require statements // 6 - Create events for each functions // 7 - Make an OnlyOwner Modifier. Use it in a function that will check the balance of the entire contract // 8 - Use Assert(State the fact, list error message) in all 3 functions // 9 - Have 2 require statements: Msg.sender is not a 0 address | Msg.value is not 0 in the deposit function // NB - no need to create a new token: we'll use ETH // Use OpenZeppelin's SafeMath for uint operations contract Safe { mapping(address => uint256) public balances; //balances[msg.sender] (how to call mapping) struct User{ address userAddress; uint256 userBalance; uint256 userID; } User[] public users; modifier hasFunds() { require(balances[msg.sender] >= msg.value, "Error! Insufficient Funds"); _; } modifier onlyOwner() { require(balances[msg.sender], "Error! Not Owner"); _; event transactionLogs(address sender, string message); // function withdrawFunds() public payable { //checks, effects, interactions // require(balances[msg.sender] >= msg.value, "Error! Insufficient Funds"); // balances[msg.sender] -= msg.value; // payable(msg.sender).transfer(msg.value); function withdrawFunds() public payable hasFunds { //my updated code balances[msg.sender] -= msg.value; payable(msg.sender).transfer(msg.value); assert(balances[msg.sender] -= msg.value;) emit transactionLogs(msg.sender, "Withdraw Successful"); } function transferFunds(address _to) public payable hasFunds returns (bool) { //my udpated code balances[msg.sender] -= msg.value; balances[_to] += msg.value; payable(_to).transfer(msg.value); assert(balances[_to] += msg.value;) emit transactionLogs(msg.sender, "Transfer Successful"); return true; } function depositFunds() public payable returns (bool) { //Have 2 require statements: Msg.sender is not a 0 address | Msg.value is not 0 uint oldBalance = balances[msg.sender]; // old balance 1000$ uint updatedBalance = balances[msg.value]; require([msg.sender] != address(0)); require([msg.value] != address(0)); balances[msg.sender] += msg.value; // I'm depositing 200$ so after this line my balance is 1200$ // assert that the balance of the msg.sender did in fact increase by msg.value assert(balances[msg.sender] ++ msg.value == updatedBalance); assert(balances[msg.sender] - msg.value == oldBalance); emit transactionLogs(msg.sender, "Deposit Successful"); return true; } function getContractBalance() public view onlyOwner returns (uint) { balances[msg.sender] == msg.value; assert(balances[msg.sender] == msg.value;) emit transactionLogs(msg.sender, "Current Balance Checked"); return address(this).balance; } }
0.4.18