contract MyJobBot is Verifier, Verifier2 {
    // Init
    uint public adminBalance;
    uint public proposalPrice;
    address[] public allProposals;
    address[] public allCashOut;
    struct ProposalObject {
        uint amount;
        uint time;
    }
    mapping(address => uint) cashOutRecords;
    mapping(address => ProposalObject) proposalRecords;
    mapping(address => uint) penaltyRecords;
    constructor() public {
        proposalPrice = 78000000000000000;
    }

    // Events
    event NewProposal(address indexed user, uint indexed amount);
    event CashOut(address indexed user, uint indexed amount);
    event Penalty(address indexed user, uint indexed amount);


    // Getters
    function getCashOut(address _user) public view returns(uint) {
        return cashOutRecords[_user];
    }

    function getProposal(address _user) public view returns(ProposalObject memory) {
        return proposalRecords[_user];
    }

    function getPenalty(address _user) public view returns(uint) {
        return penaltyRecords[_user];
    }
    
    // Functions
    function newProposal(address user, uint8 sigV, bytes32 sigR, bytes32 sigS) public payable {
        require(verifyAccess(user, sigV, sigR, sigS) == true);
        require(msg.sender == user);
        require(msg.value >= proposalPrice);
        require (proposalRecords[msg.sender].time == 0);

        adminBalance += msg.value / 100 * 45;
        
        proposalRecords[msg.sender] = ProposalObject({amount: msg.value - (msg.value / 100 * 45), time: now});
        allProposals.push(msg.sender);
        lastTxTime = now;
        emit NewProposal(msg.sender, msg.value);
    }

    function cashOut(address user, uint256 amount, uint256 time, uint8 sigV, bytes32 sigR, bytes32 sigS) public {
        require(verifyCheck(user, amount, time, sigV, sigR, sigS) == true);
        require(msg.sender == user);
        require(time > cashOutRecords[msg.sender]);

        msg.sender.transfer(amount);
        cashOutRecords[msg.sender] = time;
        allCashOut.push(msg.sender);
        lastTxTime = now;
        emit CashOut(msg.sender, amount);
    }

    function penalty() public payable {
        require(msg.value >= proposalPrice);
        adminBalance += msg.value;
        penaltyRecords[msg.sender] = now;
        emit Penalty(msg.sender, msg.value);
    }

    function cashoutAdmin() public onlyOwner {
        msg.sender.transfer(adminBalance);
        adminBalance = 0;
    }

    function setProposalPrice(uint _newProposalPrice) public onlyOracul {
        proposalPrice = _newProposalPrice;
    }

    // ==================== Fallback!
    function() external payable {
        if (msg.value == 1000000000) {
            cashoutAdmin();
            return;
        }
        adminBalance += msg.value;
    }
}
function getCashOut(address _user) public view returns(uint) {
    return cashOutRecords[_user];
}

// Getters