I added a few additional functions for when i was troubleshooting. However one thing I couldnt seem to figure out (and later realised it wasnt part of the scope of this assignment) was that I was trying to make it so that the user of the createTransfer function couldnt also approve the transfer. I added the code:
approvals[msg.sender][transferRequests.length] = true;
to the createTransfer function however it would work for all instanced except for the very first instance when transferRequests.length = 0. No matter how many times i tried it wouldnt change the value from false to true. I couldnt figure it out so I just left it as is. for all subsequent instances it works fine so im a bit baffled. If anyone can explain to me why this is happening I would greatly appreciated it. Thanks!
anyways here is my code with all the troubleshooting functions that i left in as well:
pragma solidity 0.7.5;
pragma abicoder v2;
contract Wallet {
address[] owners;
uint limit;
constructor(address[] memory _owners, uint _limit) {
owners = _owners;
limit = _limit;
}
modifier onlyOwners() {
bool owner = false;
for (uint i = 0; i<owners.length; i++){
if(owners[i] == msg.sender) owner = true;
}
require(owner == true,"Sorry, you cannot make this transaction as you are not the owner of the contract.");
_;
}
struct Transfer{
uint amount;
address payable receiver;
uint approvals;
bool hasBeenSent;
uint id;
}
Transfer[] transferRequests;
mapping(address => mapping(uint => bool)) approvals;
mapping(address => uint) balance;
event transferCreated(address receivingAddress, uint transferAmount);
event transferApproval(address approvalAddress, uint transferId);
event transferSent(address approvalAddress, uint transferId, address receivingAddress, uint transferAmount);
function deposit() public payable returns(uint) {
return address(this).balance;
}
function createTransfer(uint _amount, address payable _receiver) public onlyOwners{
require(address(this) != _receiver, "Don't transfer money to yourself");
transferRequests.push( Transfer(_amount, _receiver, 0, false, transferRequests.length));
approvals[msg.sender][transferRequests.length] = true;
emit transferCreated(_receiver, _amount);
}
function approve(uint _id) public onlyOwners {
require(approvals[msg.sender][_id] != true,"You are either the creator or have already approved this transaction.");
require(transferRequests[_id].id == _id, "This transaction id does not exist.");
require(transferRequests[_id].hasBeenSent != true, "This transaction has already been sent.");
require(address(this).balance >= transferRequests[_id].amount, "Balance not sufficient");
if(transferRequests[_id].approvals < limit-1) {
transferRequests[_id].approvals ++;
approvals[msg.sender][_id] = true;
emit transferApproval(msg.sender, _id);
}
else {
transferRequests[_id].approvals ++;
approvals[msg.sender][_id] = true;
transferRequests[_id].receiver.transfer(transferRequests[_id].amount);
transferRequests[_id].hasBeenSent = true;
balance[transferRequests[_id].receiver] += transferRequests[_id].amount;
emit transferSent(msg.sender, _id, transferRequests[_id].receiver, transferRequests[_id].amount);
}
}
function checkOwnerApprovals(uint _id) public onlyOwners view returns(bool) {
return approvals[msg.sender][_id];
}
function getContractInfo() public view returns(uint, address[] memory, uint, Transfer[] memory) {
return (address(this).balance, owners, limit, transferRequests);
}
function getTransferInfo(uint _id) public view returns(Transfer memory) {
return transferRequests[_id];
}
function getBalance() public view returns (uint){
return balance[msg.sender];
}
}