This certainly could use some improvements after having looked at some others’. However this should work as far as I understand
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.7.5;
import “./MultiOwner.sol”;
import “./Destroyable.sol”;
contract MultiSigWallet {
uint256 private balance = 0;
TransferToBeSigned [] transferRequests;
mapping(address => mapping(uint => bool)) signed;
mapping (address => bool) owners;
address [] ownerList;
uint signees;
struct TransferToBeSigned{
uint amount;
address payable recipient;
bool executed;
}
modifier onlyOwners {
require(owners[msg.sender] == true);
_; //run the function
}
constructor(address [] memory o, uint _s){
signees = _s;
ownerList = o;
for(uint i = 0; i < o.length; i++){
owners[o[i]] = true;
}
}
function deposit() public payable returns (uint) {
balance += msg.value;
return balance;
}
function getBalance() public view returns (uint){
return balance;
}
function transferRequest(address recipient, uint amount) public onlyOwners {
TransferToBeSigned memory tr = TransferToBeSigned(amount, recipient, false);
transferRequests.push(tr);
}
function sign(uint transaction_id) public onlyOwners{
require(signed[msg.sender][transaction_id] != true)
signed[msg.sender][transaction_id] = true;
}
function startTransfer(uint transaction_id) public onlyOwners{
uint approvals = 0;
for(uint o = 0; o < ownerList.length; o++){
//address a = ownerList[o];
if(signed[ownerList[o]][transaction_id]){
approvals++;
}
}
if(approvals >= signees && !(transferRequests[transaction_id].executed)){
transfer(transferRequests[transaction_id].recipient, transferRequests[transaction_id].amount);
}
}
function transfer(address recipient, uint amount) private {
require(balance >= amount, "Balance not sufficient");
require(msg.sender != recipient, "Don't transfer money to yourself");
uint previousSenderBalance = balance;
balance -= amount;
assert(balance == previousSenderBalance - amount);
}
}