WthdrawForTeams Contract. To prevent rug to the development team

In this blockchain world not only buyers can be scammed.
I've also seen the development and networking make them a rug

For example, owners are promised a payment after a seed comes out to the team.
The team working for months for free, just like developers.
When making the pre-sale many times they do not comply with what was agreed.
Above all I have seen it in NFTs projects

To avoid those rugs to the team I have created this contract that prevents the withidraw if the team members are not paid first.

Payments can be agreed to team members both by percentage of collection or fixed amount.

What better place than this to share it and to give me your opinion as proposals for improvements.

Perhaps there is already a contract with these characteristics and I have done a useless job but I personally have not found it.

Thanks in advance for your suggestions on security or design.

// SPDX-License-Identifier: Unlicensed
pragma solidity ^0.8.0;

import 'https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol';
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeMath.sol";

/**
 * @dev https://cainuriel.github.io/ 
 * This contract is intended to prevent a rug for the team. 
 * Does not allow funds to be withdrawn until the entire team has purchased their share.
 * Allows payments in percentage or direct amount
 */
contract WithdrawForTeams is Ownable {

    using SafeMath for uint256;

    uint public teamNumber;
    uint public stillToBePaid;  
    mapping(address => uint256) public percentage;
    mapping(address => uint256) public memberAmount;
    mapping(address => bool) public paidOut;

        /**
    * withdraw from the remainder sold after the team has cashed
    * @param amount total balance remainder
    * @param date collection date
    */
    event Withdraw(
        uint256 amount,
        uint256 date
    );

        /**
    * Event for team collect logging
    * @param member address of team
    * @param percentage of the member
    * @param amount balance of the team
    * @param date collection date
    */
    event WithdrawTeamPercentage(
        address member,
        uint256 percentage,
        uint256 amount,
        uint256 date
    );

          /**
    * Event for team collect logging
    * @param member address of team
    * @param amount balance of the team
    * @param date collection date
    */
    event WithdrawTeamAmount(
        address member,
        uint256 amount,
        uint256 date
    );
    
    /**CAUTION
     * @dev Cannot reduce or expand the number of team members after deploying the contract
     */
    constructor(uint _teamNumber)  
    {
        teamNumber = _teamNumber;
        stillToBePaid = _teamNumber;
    }

        /**
        * @dev sets the percentage that a team member will receive.
        */
        function setPercentageTeam(address _member, uint256 _percentage)  public onlyOwner 
    {
        require(teamNumber != 0, "The registration of team members is now complete");
        percentage[_member] = _percentage;
        teamNumber = teamNumber.sub(1);
    }

        /**
        * @dev sets the amount that a team member will receive.
        */
        function setAmountTeam(address _member, uint256 _amount)  public onlyOwner 
    {
        require(teamNumber != 0, "The registration of team members is now complete");
        memberAmount[_member] = _amount;
        teamNumber = teamNumber.sub(1);
    }

        /**
        * @dev Before collecting the team has to take the agreed part
        */
        function withdraw() public onlyOwner 
    {   require(stillToBePaid == 0, "Has not yet received all the team");
        uint256 amount = address(this).balance;
        payable(msg.sender).transfer(amount);
        emit Withdraw(amount, block.timestamp);
        
    }
        /**
        * @dev Members who have a percentage must call this function
        */
        function withdrawTeamPercentage() public 
    {   require(percentage[msg.sender] != 0, "This account is not in the team or have amount");
        require(!paidOut[msg.sender], "You have already collected your share");
        uint256 balance = getBalance();
        uint256 amount = balance.mul(percentage[msg.sender]).div(10**2);
        payable(msg.sender).transfer(amount);
        stillToBePaid = stillToBePaid.sub(1);
        paidOut[msg.sender] = true;
        emit WithdrawTeamPercentage(msg.sender,percentage[msg.sender], amount, block.timestamp);
        
    }

        /**
        * @dev Members who have a amount must call this function
        */
        function withdrawTeamAmount() public 
    {   require(memberAmount[msg.sender] != 0, "This account is not in the team or have percentage");
        require(!paidOut[msg.sender], "You have already collected your share");
        uint256 amount = memberAmount[msg.sender];
        payable(msg.sender).transfer(amount);
        stillToBePaid = stillToBePaid.sub(1);
        paidOut[msg.sender] = true;
        emit WithdrawTeamAmount(msg.sender, amount, block.timestamp);
        
    }

        function getBalance() public view returns(uint256) 
    {
        return address(this).balance;
    }

} 

1 Like

In the case of a team member not performing after the shares were decided.
A scheduled, group consensus to re adjust shares may be useful.

What you say is interesting.
Although I have thought that it is better to limit all change. In other words, when the contract is deployed, it must be clear who the team is and how much has been promised for the work.

The contract does not need to be deployed soon. Just a couple of weeks before the presale event

at least i think so

1 Like

Great example, I just did wonder about the member that said they would do their share then did not.

For this reason, the contract is only deployed shortly before the presale. What one has to do is easily to check if there is a follow-up. It is clear that if someone has not done what he said he would do, he would not have to participate, for the simple reason that if he has not done what he had to do for the project to finish, someone else would have had to do it, and therefore, he would enter in the collection

In any case, I am not convinced by the contract. I would like to improve it. Hence, I share it for your opinion and advice.