Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
3.5 kB
9
Indexable
// 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";
        }
    }
}