ColorFactory

Difficulty

The Factory can make all colors of your choice. Well, Almost.
The Factory needs to make a special color, but seems like it is not possible with the colors available. Can you help?
Author: Razzor
Network: Goerli
Deployer: 0x26edC5982ea919d2358ECCbfC640eaD45Dc0c2b0

Contract Code

pragma solidity 0.8.18;
contract ColorFactory{
    mapping(string => uint256) public functions;
    bytes3 public colorRequired;
    bool public initialized;
    bool public pwned;
    address public deployer;

    function initialize(bytes3 _colorRequired) external{
        require(!initialized, "Already Initialized");
        uint ptrRed; uint ptrGreen; uint ptrBlue; uint ptrBlack;
        function() internal pure returns(bytes3) funcRed = addRed;
        function() internal pure returns(bytes3) funcGreen =  addGreen;
        function() internal pure returns(bytes3) funcBlue = addBlue;
        function() internal pure returns(bytes3) funcBlack = addBlack;
        assembly{
            ptrRed:= funcRed
            ptrGreen:= funcGreen
            ptrBlue:= funcBlue
            ptrBlack:= funcBlack
        }
        functions["Red"] = ptrRed;
        functions["Green"] = ptrGreen;
        functions["Blue"] = ptrBlue;
        functions["Black"] = ptrBlack;
        colorRequired = _colorRequired;
        initialized = true;
        deployer = msg.sender;
    }

// -----------------Let's Mix Some Colors----------------------------

    function addRed() internal pure returns(bytes3){
        return 0xff0000;
    }
    function addGreen() internal pure returns(bytes3){
        return 0x00b500;
    }
    function addBlue() internal pure returns(bytes3){
        return 0x0047ab;
    }
    function addBlack() internal pure returns(bytes3){
        return 0x000000;
    }


    function mixer(uint[] calldata pointers, uint[] calldata parts) external payable{
        require(!pwned, "Already Pwned!");
        require(pointers.length == parts.length, "Arrays not equal");
        bytes3[] memory colors = new bytes3[](numberOfColors(parts)); 
        uint count;
        for (uint i;i<pointers.length;++i){
            bytes3 color = toFunc(pointers[i])();
            for (uint j; j<parts[i];++j){
                colors[count] = color;
                ++count;
            }
        }
        bytes3 mixedColor = mix(colors);
        if (mixedColor == colorRequired) {
            pwned = true;
        }
        
    }

    function toFunc(uint pointer) internal pure returns(function() internal pure returns(bytes3) func){
        assembly{
            func:= pointer
        }
    }

    function numberOfColors(uint[] calldata pointers, uint[] calldata parts) internal pure returns(uint count){
      uint RedCount; uint GreenCount; uint BlueCount; uint BlackCount; 
      for(uint i;i<pointers.length;++i){
          bytes3 color = toFunc(pointers[i])();
          if(color == 0xff0000) RedCount+= parts[i];
          else if(color == 0x00b500) GreenCount+= parts[i];
          else if(color == 0x0047ab) BlueCount+= parts[i];
          else BlackCount+= parts[i];
      }
      require(RedCount <= 30 && GreenCount <=30 && BlueCount <=30 && BlackCount <=30, "Too many colors to mix");

      count = RedCount + GreenCount + BlueCount + BlackCount;

    }
    

    function mix(bytes3[] memory colors) internal pure returns(bytes3){
        uint colorsCount = colors.length;
        
        require(colorsCount >= 2, "Not enough colors to mix");
        bytes memory res;
        for (uint j;j<3;++j){
            uint temp;
            for(uint i;i<colorsCount;++i){
                temp += uint8(colors[i][j]);
             }
             uint8 value;
             if(temp>0){
                if(temp%colorsCount < ((colorsCount-1)/2)+1){
                    value = uint8(temp/colorsCount);
                } else{
                    value = uint8(((temp-1)/colorsCount)+1);
                }
                
             }
             
             res = abi.encodePacked(res,bytes1(value));
        }

        return bytes3(res);
    }
    
    fallback() external payable{
        
    }
}