// 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 { address private owner; mapping(address => uint256) public balances; 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(msg.sender == owner, "Error! Not Owner"); _; } event transactionLogs(address sender, string message); constructor () { owner = msg.sender; } function withdrawFunds() public payable hasFunds { uint256 oldBalance = balances[msg.sender]; balances[msg.sender] -= msg.value; payable(msg.sender).transfer(msg.value); assert(balances[msg.sender] == oldBalance + msg.value); emit transactionLogs(msg.sender, "Withdraw Successful"); } // require that _to is not a zero address // require that msg.value is not zero function transferFunds(address _to) public payable hasFunds returns (bool) { uint balanceSender = balances[msg.sender]; balances[msg.sender] -= msg.value; uint balanceReceiver = balances[_to]; balances[_to] += msg.value; payable(_to).transfer(msg.value); assert(balances[msg.sender] + msg.value == balanceSender); assert(balances[_to] - msg.value == balanceReceiver ); emit transactionLogs(msg.sender, "Transfer Successful"); return true; } function depositFunds() public payable returns (bool) { require(msg.sender != address(0)); require(msg.value != 0); uint oldBalance = balances[msg.sender]; balances[msg.sender] += msg.value; assert(balances[msg.sender] - msg.value == oldBalance); emit transactionLogs(msg.sender, "Deposit Successful"); return true; } function getContractBalance() public view onlyOwner returns (uint) { return address(this).balance; } }
0.4.18