EthereumCommonwealth / Auditing

Ethereum Commonwealth Security Department conducted over 400 security audits since 2018. Not even a single contract that we audited was hacked. You can access our audit reports in the ISSUES of this repo. We are accepting new audit requests.
https://audits.callisto.network/
GNU General Public License v3.0
132 stars 34 forks source link

Meta 2ken #662

Closed amir30040 closed 1 year ago

amir30040 commented 2 years ago

/ Implements EIP20 token standard: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md ./

pragma solidity ^0.5.1;

import "./EIP20Interface.sol";

library SafeMath {

function add(uint256 a, uint256 b) internal pure returns (uint256) {
    uint256 c = a + b;
    require(c >= a, "SafeMath: addition overflow");
    return c;
}

function sub(uint256 a, uint256 b) internal pure returns (uint256) {
    return sub(a, b, "SafeMath: subtraction overflow");
}

function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
    require(b <= a, errorMessage);
    uint256 c = a - b;

    return c;
}

function mul(uint256 a, uint256 b) internal pure returns (uint256) {
    if (a == 0) {
        return 0;
    }
    uint256 c = a * b;
    require(c / a == b, "SafeMath: multiplication overflow");
    return c;
}

function div(uint256 a, uint256 b) internal pure returns (uint256) {
    return div(a, b, "SafeMath: division by zero");
}

function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
    require(b > 0, errorMessage);
    uint256 c = a / b;
    return c;
}

function mod(uint256 a, uint256 b) internal pure returns (uint256) {
    return mod(a, b, "SafeMath: modulo by zero");
}

function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
    require(b != 0, errorMessage);
    return a % b;
}    

}

contract MetAmirGameToken is EIP20Interface {

using SafeMath for uint256;

uint256 constant private MAX_UINT256 = 2**256 - 1;
mapping (address => uint256) public balances;
mapping (address => mapping (address => uint256)) public allowed;

string public name;       // fancy name
uint8  public decimals;   // How many decimals to show.
string public symbol;     // An identifier: eg SBX

// **** jpoor variables ****    
struct ContractStep {
    uint256 OnHand;           // OnHand Tokens.
    uint256 HoldTime;         // minimum time to hold by seconds.
}
struct HoldLimit {
    uint256 Expire;         // Expire date of holding value.
    uint256 Value;          // Value of this hold limit.
}

uint256 public Token_OnHand;               // remain amount of tokens to contract
uint256 public Token_EarnedByGas;          // variable to hold owner gases
uint256 public Token_ReceivedByUsers;      // received amount of tokens by receiveToken method.
bool public contract_Lock;                 // Lock contact to prepare
uint256 public contract_GasPercent;        // per transaction Gas fee by percent.
uint256 public contract_ParentPercent;     // Parent Commission fee by percent.
uint256 public contract_MaxBalance;        // maximum token that per address can save as balance.

mapping (address => uint256) public owners;          // contract owners. 
mapping (address => address) public parents;         // member parent to gas for per transation
mapping (address => HoldLimit[]) public holdLimits;  // Tokens with hold time limitation. will be deleted after expire date.
mapping (uint8 => ContractStep) public steps;        // contract Steps => 0: PublicSale | 1: PrivateSale | 2: Airdrop | 3: PreSale

// **** jpoor events ****    
event ev_Owner_Set(address _user, address _ownerAddress);
event ev_Owner_Del(address _user, address _ownerAddress);
event ev_Parent_Set(address indexed _child, address indexed _parent);
event ev_Token_ReceivedByUsers_Withdraw(address _user, uint256 _value);
event ev_Token_EarnedByGas_Withdraw(address _user, uint256 _value);

// **** jpoor modifiers ****    
modifier onlyOwner {
    require(owners[msg.sender] > 0);
    _;
}

constructor (
    uint256 _initialAmount,
    string memory _tokenName,
    uint8 _decimalUnits,
    string memory _tokenSymbol,
    uint256 _contract_MaxBalance_ByPercent,
    uint256 _contract_GasPercent
) public {
    name = _tokenName;                               // Set the name for display purposes.
    decimals = _decimalUnits;                        // Amount of decimals for display purposes.
    symbol = _tokenSymbol;                           // Set the symbol for display purposes.
    owners[msg.sender] = block.timestamp - 864000;   // set owner. 10 days default for deleting.
    totalSupply = _initialAmount;                    // Update total supply.
    Token_OnHand = _initialAmount;                   // Set first token value.
    contract_GasPercent = _contract_GasPercent;      // Default Gas of contract.
    contract_MaxBalance = _initialAmount * _contract_MaxBalance_ByPercent / 100;  // Maximum Tokens in per wallet.
    contract_ParentPercent = 3;

    // Settings
    steps[1].HoldTime = 7776000;
    steps[1].OnHand = _initialAmount * 3 / 100;

    steps[2].HoldTime = 7776000;
    steps[2].OnHand = _initialAmount * 1 / 100;

    steps[3].HoldTime = 15552000;
    steps[3].OnHand = _initialAmount * 3 / 100;
}

// ***********************   
// **** jpoor methods ****
// *********************** 

function availableBalanceOf(address _owner) public view returns (uint256 availableBalance) {
    uint256 valueLimit;
    for (uint i = 0; i < holdLimits[_owner].length; i++) {
        if (block.timestamp < holdLimits[_owner][i].Expire) {
            valueLimit.add(holdLimits[_owner][i].Value);
        }
    }
    if (balances[_owner] > valueLimit) {
        return balances[_owner] - valueLimit;
    }
    else {
        return 0;
    }
}

function sendToken(
    address _to, uint256 _value, uint256 _gasToParent, 
    uint8 _step, bool _manualHoldingTime, uint256 _HoldingTimeBySecond
) public onlyOwner returns (bool success) {
    require(!contract_Lock, "Contract is lock! Please try again later.");
    require(_value > 0, "Invalid Value!");
    require(balances[_to] + _value <= contract_MaxBalance, "maximum balance limitation!");
    require(_step <= 3, "Invalid Step!");        

    uint256 _parentGas;
    address _parent;

    if ((_gasToParent > 0) && (contract_ParentPercent > 0)) {
        _parent = parents[_to];
        if (_parent != address(0)) {
            _parentGas = (_value * contract_ParentPercent) / 100;
            if (balances[_parent] + _parentGas > contract_MaxBalance) {
                _parentGas = 0;
            }
        }
    }
    require(_value + _parentGas <= Token_OnHand, "Token limitation!");
    require(_step == 0 || _value + _parentGas <= steps[_step].OnHand, "Invalid OnHand!");

    // Add Hold limitation
    if (_manualHoldingTime && _step == 0) {
        holdLimits[_to].push(HoldLimit(block.timestamp + _HoldingTimeBySecond, _value));
    }
    else if (steps[_step].HoldTime > 0) {
        holdLimits[_to].push(HoldLimit(block.timestamp + steps[_step].HoldTime, _value));
    }

    // Set balances
    Token_OnHand.sub(_value + _parentGas);
    balances[_to].add(_value);
    if (_step > 0) {
        steps[_step].OnHand.sub(_value + _parentGas);
    }

    // Set parent gass 
    if (_parentGas > 0) {                
        balances[_parent].add(_parentGas);
        emit Transfer(address(this), _parent, _parentGas); //solhint-disable-line indent, no-unused-vars
    }

    emit Transfer(address(this), _to, _value); //solhint-disable-line indent, no-unused-vars

    return true;
}

function sendToken(
    address[] memory _toList, uint256[] memory _valueList, uint256 _gasToParent,
    uint8 _step, bool _manualHoldingTime, uint256 _HoldingTimeBySecond
) public onlyOwner returns (bool success) {
     for (uint i=0; i<_toList.length; i++){
        sendToken(_toList[i], _valueList[i], _gasToParent, _step, _manualHoldingTime, _HoldingTimeBySecond);
     }
     return true;
}

function PrivateSale(address _to, uint256 _value, uint256 _gasToParent) public onlyOwner returns (bool success) {
    return sendToken (_to, _value, _gasToParent, 1, false, 0);
}

function Airdrop(address _to, uint256 _value, uint256 _gasToParent) public onlyOwner returns (bool success) {
    return sendToken (_to, _value, _gasToParent, 2, false, 0);
}

function PreSale(address _to, uint256 _value, uint256 _gasToParent) public onlyOwner returns (bool success) {
    return sendToken (_to, _value, _gasToParent, 3, false, 0);
}

function PublicSale(address _to, uint256 _value, uint8 _gasToParent) public onlyOwner returns (bool success) {
    return sendToken (_to, _value, _gasToParent, 0, false, 0);
}

function PublicSale(address _to, uint256 _value, uint8 _gasToParent, uint256 _holdingTimeByHour) public onlyOwner returns (bool success) {
    return sendToken (_to, _value, _gasToParent, 0, true, _holdingTimeByHour * 3600);
}

function receiveToken(uint256 _value) public returns (bool success) {

    require(!contract_Lock, "Contract is lock! Please try again later.");
    require(_value > 0, "Invalid Value!");
    require(_value <= balances[msg.sender], "Low balance.");

    // Check balance validations
    uint256 availableBalance = availableBalanceOf(msg.sender);
    require(_value <= availableBalance, "Hold time limitation!");

    // Set balances
    balances[msg.sender] -= _value;
    Token_ReceivedByUsers += _value;

    return true;
}

function Token_ReceivedByUsers_Withdraw(uint256 _value) public onlyOwner returns (bool success) {
    require(!contract_Lock, "Contract is lock! Please try again later.");
    require(_value > 0, "Invalid Value!");
    require(_value <= Token_ReceivedByUsers, "Token_ReceivedByUsers limitation!");

    // Set balances
    Token_ReceivedByUsers.sub(_value);
    Token_OnHand.add(_value);

    emit ev_Token_ReceivedByUsers_Withdraw(msg.sender, _value); 
    return true;
}

function Token_EarnedByGas_Withdraw(uint256 _value) public onlyOwner returns (bool success) {
    require(!contract_Lock, "Contract is lock! Please try again later.");
    require(_value <= Token_EarnedByGas, "Token_ReceivedByUsers limitation!");

    // Set balances
    Token_EarnedByGas.sub(_value);
    Token_OnHand.add(_value);

    emit ev_Token_EarnedByGas_Withdraw(msg.sender, _value); 
    return true;
}

function owner_set(address _ownerAddress) public onlyOwner returns (bool success) {
    require(_ownerAddress != address(0));
    if (owners[_ownerAddress] == 0){
        owners[_ownerAddress] = block.timestamp;
        emit ev_Owner_Set(msg.sender, _ownerAddress);
    }
    return true;
}

function owner_del(address _ownerAddress) public onlyOwner returns (bool success) {
    require(_ownerAddress != address(0));
    if (owners[_ownerAddress] > 0) {
        // Delete access after 10 days.
        require(owners[_ownerAddress] - 864000 > block.timestamp, "Access denied!"); 
        owners[_ownerAddress] = 0;
        emit ev_Owner_Del(msg.sender, _ownerAddress);
    }
    return true;
}

function parent_set(address _parent) public returns (bool success) {
    require(!contract_Lock, "Contract is lock! Please try again later.");
    require(parents[msg.sender] == address(0), "You can't change your parent.");
    parents[msg.sender] = _parent;
    emit ev_Parent_Set(msg.sender, _parent); //solhint-disable-line indent, no-unused-vars
    return true;
}

function parent_set(address _parent, address _child) public onlyOwner returns (bool success) {
    require(!contract_Lock, "Contract is lock! Please try again later.");
    require(parents[_child] == address(0), "You can't change parent.");
    parents[_child] = _parent;
    emit ev_Parent_Set(_child, _parent); //solhint-disable-line indent, no-unused-vars
    return true;
}

function contract_Lock_set(bool status) public onlyOwner returns (bool success) {
    contract_Lock = status;
    return true;
}

function contract_GasPercent_set(uint256 _gas) public onlyOwner returns (bool success) {
    contract_GasPercent = _gas;
    return true;
}

function contract_ParentPercent_set(uint256 _parentPercent) public onlyOwner returns (bool success) {
    contract_ParentPercent = _parentPercent;
    return true;
}

function PublicSale_HoldTime_set(uint256 _HoldTimeByHour) public onlyOwner returns (bool success) {
    steps[0].HoldTime = (_HoldTimeByHour * 3600);
    return true;
}

// **** EIP20 methods ****

function transfer(address _to, uint256 _value) public returns (bool success) {
    require(!contract_Lock, "Contract is lock! Please try again later.");
    require(_value <= balances[msg.sender], "Low balance.");

    // Check balance validations
    uint256 availableBalance = availableBalanceOf(msg.sender);
    require(_value <= availableBalance, "Hold time limitation!");

    uint256 _contractGas;
    if (contract_GasPercent > 0) {
        _contractGas = _value * contract_GasPercent / 100;
    }
    require(balances[_to] + (_value - _contractGas) <= contract_MaxBalance, "maximum balance limitation!");

    // Add Hold limitation except owner
    if (steps[0].HoldTime > 0) {
        holdLimits[_to].push(HoldLimit(
            block.timestamp + steps[0].HoldTime,
            (_value - _contractGas)));
    }

    // Set balances
    balances[msg.sender].sub(_value);
    balances[_to].add(_value - _contractGas);

    // Set gass fee
    if (_contractGas > 0) {
        Token_EarnedByGas.add(_contractGas);
    }

    emit Transfer(msg.sender, _to, (_value - _contractGas)); //solhint-disable-line indent, no-unused-vars
    return true;
}

function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
    require(!contract_Lock, "Contract is lock! Please try again later.");
    uint256 allowance = allowed[_from][msg.sender];
    require(balances[_from] >= _value && allowance >= _value);

    // Check balance validations
    uint256 availableBalance = availableBalanceOf(_from);
    require(_value <= availableBalance, "Hold time limitation!");

    uint256 _contractGas;
    if (contract_GasPercent > 0) {
        _contractGas = _value * contract_GasPercent / 100;
    }
    require(balances[_to] + (_value - _contractGas) <= contract_MaxBalance, "maximum balance limitation!");

    // Add Hold limitation except owner
    if (steps[0].HoldTime > 0) {
        holdLimits[_to].push(HoldLimit(
            block.timestamp + steps[0].HoldTime,
            (_value - _contractGas)));
    }

    balances[_from].sub(_value);
    balances[_to].add(_value - _contractGas);

    // Set gass fee
    if (_contractGas > 0) {
        Token_EarnedByGas.add(_contractGas);
    }

    if (allowance < MAX_UINT256) {
        allowed[_from][msg.sender].sub(_value);
    }
    emit Transfer(_from, _to, (_value - _contractGas)); //solhint-disable-line indent, no-unused-vars
    return true;
}

function balanceOf(address _owner) public view returns (uint256 balance) {
    return balances[_owner];
}

function approve(address _spender, uint256 _value) public returns (bool success) {
    require(!contract_Lock, "Contract is lock! Please try again later.");
    allowed[msg.sender][_spender] = _value;
    emit Approval(msg.sender, _spender, _value); //solhint-disable-line indent, no-unused-vars
    return true;
}

function allowance(address _owner, address _spender) public view returns (uint256 remaining) {
    return allowed[_owner][_spender];
}

}

yuriy77k commented 1 year ago

@amir30040 the audit fee is 1000 USDT. You may send USDT (ERC20 or BEP20) to: 0x6317c6944bd1cD3932d062cce39d7Fd602119529

The estimated auditing time - is 7 days after payment.