Untitled
unknown
plain_text
a year ago
3.5 kB
9
Indexable
Never
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract TeamWallet { address public deployer; // The deployer of the contract address[] public members; // Array to store team members uint public totalCredits; // Total available credits in the wallet struct Transaction { uint amount; bool executed; uint approvals; } Transaction[] public transactions; mapping(address => mapping(uint => bool)) public hasApproved; mapping(address => mapping(uint => bool)) public hasRejected; modifier onlyDeployer() { require(msg.sender == deployer, "Only the deployer can call this function"); _; } modifier onlyTeamMember() { require(isTeamMember(msg.sender), "Only team members can call this function"); _; } constructor() { deployer = msg.sender; } function isTeamMember(address _address) internal view returns (bool) { for (uint i = 0; i < members.length; i++) { if (members[i] == _address) { return true; } } return false; } function setWallet(address[] memory _members, uint _totalCredits) public onlyDeployer { require(members.length == 0, "Wallet has already been initialized"); require(_members.length > 0, "There must be at least one team member"); require(_totalCredits > 0, "Credits must be greater than 0"); require(deployer != _members[0], "The deployer cannot be a team member"); for (uint i = 0; i < _members.length; i++) { members.push(_members[i]); } totalCredits = _totalCredits; } function spend(uint _amount) public onlyTeamMember { require(_amount > 0, "Amount must be greater than 0"); transactions.push(Transaction(_amount, false, 1)); hasApproved[msg.sender][transactions.length - 1] = true; } function approve(uint _n) public onlyTeamMember { require(_n < transactions.length, "Invalid transaction index"); require(!hasApproved[msg.sender][_n], "Approval already recorded"); require(!hasRejected[msg.sender][_n], "Transaction already rejected"); transactions[_n].approvals++; hasApproved[msg.sender][_n] = true; } function reject(uint _n) public onlyTeamMember { require(_n < transactions.length, "Invalid transaction index"); require(!hasApproved[msg.sender][_n], "Transaction already approved"); require(!hasRejected[msg.sender][_n], "Rejection already recorded"); transactions[_n].approvals++; hasRejected[msg.sender][_n] = true; if (transactions[_n].approvals > members.length * 70 / 100) { transactions[_n].executed = true; totalCredits -= transactions[_n].amount; } } function getAvailableCredits() public view onlyTeamMember returns (uint) { return totalCredits; } function viewTransaction(uint _n) public view onlyTeamMember returns (uint amount, string memory status) { require(_n < transactions.length, "Invalid transaction index"); amount = transactions[_n].amount; if (transactions[_n].executed) { status = "debited"; } else if (transactions[_n].approvals > members.length * 70 / 100) { status = "pending"; } else { status = "failed"; } } }