ThirtyFive

Difficulty

We are hackers, We have our own ways!
Author: Razzor
Network: Goerli
Address: 0x302e61d03f91773a6618e50a1ef973993e28cc61

Contract Code

pragma solidity ^0.7.0;
    contract ThirtyFive{
        using ECDSA for bytes32;
        bytes32 public constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); 
        bytes32 public constant SIGNING_TYPEHASH = keccak256("SIGNING(uint16 nonce,uint256 expiry)");
        bytes32 public immutable DOMAIN_SEPARATOR;
        bytes32 public immutable name;
        bytes32 public immutable version;
            
        mapping(address=>uint24) public nonces;
        mapping(address=>bytes32) internal verificationTokens;
        mapping(address=>bool) internal isTokenGenerated;
        mapping(bytes32=>bool) internal identifiers;
        mapping(address=>uint256) public pwnCounter;
        event TokenGen(address indexed signer, bytes32 indexed token);
            
    constructor(string memory _name, string memory _version){
        bytes32 name_ = keccak256(bytes(_name));
        bytes32 version_ = keccak256(bytes(_version));
        name = name_;
        version = version_;
        uint chainId;
        assembly {
            chainId := chainid()
        }
        DOMAIN_SEPARATOR = keccak256(abi.encode(DOMAIN_TYPEHASH, name_, version_, chainId, address(this)));
    }
            
    fallback() payable external{
    }
            
    function signItLikeYouMeanIt(uint16 nonce, uint deadline, bytes memory signature) external{
        require(block.timestamp <= deadline, "Expired");
        require(nonce == nonces[msg.sender]+1, "Invalid Nonce");
        bytes32 structHash = keccak256(abi.encode(SIGNING_TYPEHASH, nonce, deadline));
        bytes32 digest = keccak256(abi.encodePacked("\x19\x01", DOMAIN_SEPARATOR, structHash));
        address signer = digest.recover(signature);
        require(signer == msg.sender, "Only Self Signed Signatures are allowed");
        bytes32 slot = keccak256(abi.encode(msg.sender, 0));
        assembly{
            sstore(slot, calldataload(4))     
        }
    }
    function giveMeMyToken() external{
        if (nonces[msg.sender] > 0x5014C3 && !isTokenGenerated[msg.sender]) {
            bytes32 token = keccak256(abi.encode(msg.sender,block.timestamp));
            verificationTokens[msg.sender] = token;
            isTokenGenerated[msg.sender]=true;
            emit TokenGen(msg.sender, token);
        }
    }
            
    function pwn(bytes32 token) external{
        require(token!=bytes32(0), "No Token Yet");
        require(token == verificationTokens[msg.sender], "Invalid Token");
        bytes32 id = keccak256(msg.data);
        require(!identifiers[id], "Already executed");
        identifiers[id] = true;
        ++pwnCounter[msg.sender]; 
    }
            
    function HackerWho() external view returns(string memory){
        uint counter = pwnCounter[msg.sender];
        if (counter > 0 && counter <= 2){
            return "Yayyy! You solved the challenge";
        }
        else if (counter > 2) {
            return "Hello Hacker";
        }
        else { return "Not yet" ;}
    
    }
            
    }
          
      
    

Writeups