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{
}
}