Contract Address Details

0xddfba183782dAbe1518431EecAaF38fF7248a5Ba

Contract Name
MasterChef
Creator
0xa2c8e1–4701e4 at 0x355e76–3fa06b
Balance
0 CRO ( )
Tokens
Fetching tokens...
Transactions
24,397 Transactions
Transfers
20,236 Transfers
Gas Used
4,288,072,204
Last Balance Update
5832373
Contract name:
MasterChef




Optimization enabled
true
Compiler version
v0.8.4+commit.c7e474f2




Optimization runs
200
EVM Version
default




Verified at
2021-12-25T01:24:23.421246Z

Constructor Arguments

000000000000000000000000285c3329930a3fd3c7c14bc041d3e50e165b15170000000000000000000000007b0cbc99535e9b7685bef3452dcb4b1edf714918000000000000000000000000a2c8e14b7cc468131c2c1d409b58be9e344701e400000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000

Arg [0] (address) : 0x285c3329930a3fd3c7c14bc041d3e50e165b1517
Arg [1] (address) : 0x7b0cbc99535e9b7685bef3452dcb4b1edf714918
Arg [2] (address) : 0xa2c8e14b7cc468131c2c1d409b58be9e344701e4
Arg [3] (uint256) : 1
Arg [4] (uint256) : 0

              

Contract source code

pragma solidity >=0.6.0 <=0.8.4;


interface IERC20 {
    
    function totalSupply() external view returns (uint256);

    
    function balanceOf(address account) external view returns (uint256);

    
    function transfer(address recipient, uint256 amount) external returns (bool);

    
    function allowance(address owner, address spender) external view returns (uint256);

    
    function approve(address spender, uint256 amount) external returns (bool);

    
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bool);

    
    event Transfer(address indexed from, address indexed to, uint256 value);

    
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

library Address {
    
    function isContract(address account) internal view returns (bool) {
        
        
        

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

    
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            
            if (returndata.length > 0) {
                

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

library SafeERC20 {
    using Address for address;

    function safeTransfer(
        IERC20 token,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(
        IERC20 token,
        address from,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    
    function safeApprove(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        
        
        
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        uint256 newAllowance = token.allowance(address(this), spender) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    }

    
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        
        
        

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) {
            
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

library SafeMath {
    
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            
            
            
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }

    
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return a - b;
    }

    
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }

    
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

    
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return a % b;
    }

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

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

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

abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    
    constructor() {
        _transferOwnership(_msgSender());
    }

    
    function owner() public view virtual returns (address) {
        return _owner;
    }

    
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

interface IERC20Metadata is IERC20 {
    
    function name() external view returns (string memory);

    
    function symbol() external view returns (string memory);

    
    function decimals() external view returns (uint8);
}

contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;

    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    
    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

    
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    
    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);

        uint256 currentAllowance = _allowances[sender][_msgSender()];
        require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
        unchecked {
            _approve(sender, _msgSender(), currentAllowance - amount);
        }

        return true;
    }

    
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
        return true;
    }

    
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        uint256 currentAllowance = _allowances[_msgSender()][spender];
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(_msgSender(), spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    
    function _transfer(
        address sender,
        address recipient,
        uint256 amount
    ) internal virtual {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(sender, recipient, amount);

        uint256 senderBalance = _balances[sender];
        require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[sender] = senderBalance - amount;
        }
        _balances[recipient] += amount;

        emit Transfer(sender, recipient, amount);

        _afterTokenTransfer(sender, recipient, amount);
    }

    
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);

        _afterTokenTransfer(address(0), account, amount);
    }

    
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
        }
        _totalSupply -= amount;

        emit Transfer(account, address(0), amount);

        _afterTokenTransfer(account, address(0), amount);
    }

    
    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}

    
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}
}

contract CrowToken is ERC20('Crow Token', 'CROW'), Ownable {
    using SafeMath for uint256;
    
    function mint(address _to, uint256 _amount) public onlyOwner {
        _mint(_to, _amount);
        _moveDelegates(address(0), _delegates[_to], _amount);
    }

    
    
    
    
    

    
    mapping (address => address) internal _delegates;

    
    struct Checkpoint {
        uint32 fromBlock;
        uint256 votes;
    }

    
    mapping (address => mapping (uint32 => Checkpoint)) public checkpoints;

    
    mapping (address => uint32) public numCheckpoints;

    
    bytes32 public constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)");

    
    bytes32 public constant DELEGATION_TYPEHASH = keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)");

    
    mapping (address => uint) public nonces;

      
    event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);

    
    event DelegateVotesChanged(address indexed delegate, uint previousBalance, uint newBalance);

    
    function delegates(address delegator)
        external
        view
        returns (address)
    {
        return _delegates[delegator];
    }

   
    function delegate(address delegatee) external {
        return _delegate(msg.sender, delegatee);
    }

    
    function delegateBySig(
        address delegatee,
        uint nonce,
        uint expiry,
        uint8 v,
        bytes32 r,
        bytes32 s
    )
        external
    {
        bytes32 domainSeparator = keccak256(
            abi.encode(
                DOMAIN_TYPEHASH,
                keccak256(bytes(name())),
                block.chainid,
                address(this)
            )
        );

        bytes32 structHash = keccak256(
            abi.encode(
                DELEGATION_TYPEHASH,
                delegatee,
                nonce,
                expiry
            )
        );

        bytes32 digest = keccak256(
            abi.encodePacked(
                "\x19\x01",
                domainSeparator,
                structHash
            )
        );

        address signatory = ecrecover(digest, v, r, s);
        require(signatory != address(0), "CROW::delegateBySig: invalid signature");
        require(nonce == nonces[signatory]++, "CROW::delegateBySig: invalid nonce");
        require(block.timestamp <= expiry, "CROW::delegateBySig: signature expired");
        return _delegate(signatory, delegatee);
    }

    
    function getCurrentVotes(address account)
        external
        view
        returns (uint256)
    {
        uint32 nCheckpoints = numCheckpoints[account];
        return nCheckpoints > 0 ? checkpoints[account][nCheckpoints - 1].votes : 0;
    }

    
    function getPriorVotes(address account, uint blockNumber)
        external
        view
        returns (uint256)
    {
        require(blockNumber < block.number, "CROW::getPriorVotes: not yet determined");

        uint32 nCheckpoints = numCheckpoints[account];
        if (nCheckpoints == 0) {
            return 0;
        }

        
        if (checkpoints[account][nCheckpoints - 1].fromBlock <= blockNumber) {
            return checkpoints[account][nCheckpoints - 1].votes;
        }

        
        if (checkpoints[account][0].fromBlock > blockNumber) {
            return 0;
        }

        uint32 lower = 0;
        uint32 upper = nCheckpoints - 1;
        while (upper > lower) {
            uint32 center = upper - (upper - lower) / 2; 
            Checkpoint memory cp = checkpoints[account][center];
            if (cp.fromBlock == blockNumber) {
                return cp.votes;
            } else if (cp.fromBlock < blockNumber) {
                lower = center;
            } else {
                upper = center - 1;
            }
        }
        return checkpoints[account][lower].votes;
    }

    function _delegate(address delegator, address delegatee)
        internal
    {
        address currentDelegate = _delegates[delegator];
        uint256 delegatorBalance = balanceOf(delegator); 
        _delegates[delegator] = delegatee;

        emit DelegateChanged(delegator, currentDelegate, delegatee);

        _moveDelegates(currentDelegate, delegatee, delegatorBalance);
    }

    function _moveDelegates(address srcRep, address dstRep, uint256 amount) internal {
        if (srcRep != dstRep && amount > 0) {
            if (srcRep != address(0)) {
                
                uint32 srcRepNum = numCheckpoints[srcRep];
                uint256 srcRepOld = srcRepNum > 0 ? checkpoints[srcRep][srcRepNum - 1].votes : 0;
                uint256 srcRepNew = srcRepOld.sub(amount);
                _writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew);
            }

            if (dstRep != address(0)) {
                
                uint32 dstRepNum = numCheckpoints[dstRep];
                uint256 dstRepOld = dstRepNum > 0 ? checkpoints[dstRep][dstRepNum - 1].votes : 0;
                uint256 dstRepNew = dstRepOld.add(amount);
                _writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew);
            }
        }
    }

    function _writeCheckpoint(
        address delegatee,
        uint32 nCheckpoints,
        uint256 oldVotes,
        uint256 newVotes
    )
        internal
    {
        uint32 blockNumber = safe32(block.number, "CROW::_writeCheckpoint: block number exceeds 32 bits");

        if (nCheckpoints > 0 && checkpoints[delegatee][nCheckpoints - 1].fromBlock == blockNumber) {
            checkpoints[delegatee][nCheckpoints - 1].votes = newVotes;
        } else {
            checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumber, newVotes);
            numCheckpoints[delegatee] = nCheckpoints + 1;
        }

        emit DelegateVotesChanged(delegatee, oldVotes, newVotes);
    }

    function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {
        require(n < 2**32, errorMessage);
        return uint32(n);
    }
}

contract CrowBar is ERC20('CrowBar Token', 'xCROW'), Ownable {
    using SafeMath for uint256;

    
    function mint(address _to, uint256 _amount) public onlyOwner {
        _mint(_to, _amount);
        _moveDelegates(address(0), _delegates[_to], _amount);
    }

    function burn(address _from ,uint256 _amount) public onlyOwner {
        _burn(_from, _amount);
        _moveDelegates(_delegates[_from], address(0), _amount);
    }

    
    CrowToken public crow;


    constructor(
        CrowToken _crow
    ) {
        crow = _crow;
    }

    
    function safeCrowTransfer(address _to, uint256 _amount) public onlyOwner {
        uint256 crowBal = crow.balanceOf(address(this));
        if (_amount > crowBal) {
            crow.transfer(_to, crowBal);
        } else {
            crow.transfer(_to, _amount);
        }
    }

    
    
    
    
    

    
    mapping (address => address) internal _delegates;

    
    struct Checkpoint {
        uint32 fromBlock;
        uint256 votes;
    }

    
    mapping (address => mapping (uint32 => Checkpoint)) public checkpoints;

    
    mapping (address => uint32) public numCheckpoints;

    
    bytes32 public constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)");

    
    bytes32 public constant DELEGATION_TYPEHASH = keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)");

    
    mapping (address => uint) public nonces;

      
    event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);

    
    event DelegateVotesChanged(address indexed delegate, uint previousBalance, uint newBalance);

    
    function delegates(address delegator)
        external
        view
        returns (address)
    {
        return _delegates[delegator];
    }

   
    function delegate(address delegatee) external {
        return _delegate(msg.sender, delegatee);
    }

    
    function delegateBySig(
        address delegatee,
        uint nonce,
        uint expiry,
        uint8 v,
        bytes32 r,
        bytes32 s
    )
        external
    {
        bytes32 domainSeparator = keccak256(
            abi.encode(
                DOMAIN_TYPEHASH,
                keccak256(bytes(name())),
                block.chainid,
                address(this)
            )
        );

        bytes32 structHash = keccak256(
            abi.encode(
                DELEGATION_TYPEHASH,
                delegatee,
                nonce,
                expiry
            )
        );

        bytes32 digest = keccak256(
            abi.encodePacked(
                "\x19\x01",
                domainSeparator,
                structHash
            )
        );

        address signatory = ecrecover(digest, v, r, s);
        require(signatory != address(0), "CROW::delegateBySig: invalid signature");
        require(nonce == nonces[signatory]++, "CROW::delegateBySig: invalid nonce");
        require(block.timestamp <= expiry, "CROW::delegateBySig: signature expired");
        return _delegate(signatory, delegatee);
    }

    
    function getCurrentVotes(address account)
        external
        view
        returns (uint256)
    {
        uint32 nCheckpoints = numCheckpoints[account];
        return nCheckpoints > 0 ? checkpoints[account][nCheckpoints - 1].votes : 0;
    }

    
    function getPriorVotes(address account, uint blockNumber)
        external
        view
        returns (uint256)
    {
        require(blockNumber < block.number, "CROW::getPriorVotes: not yet determined");

        uint32 nCheckpoints = numCheckpoints[account];
        if (nCheckpoints == 0) {
            return 0;
        }

        
        if (checkpoints[account][nCheckpoints - 1].fromBlock <= blockNumber) {
            return checkpoints[account][nCheckpoints - 1].votes;
        }

        
        if (checkpoints[account][0].fromBlock > blockNumber) {
            return 0;
        }

        uint32 lower = 0;
        uint32 upper = nCheckpoints - 1;
        while (upper > lower) {
            uint32 center = upper - (upper - lower) / 2; 
            Checkpoint memory cp = checkpoints[account][center];
            if (cp.fromBlock == blockNumber) {
                return cp.votes;
            } else if (cp.fromBlock < blockNumber) {
                lower = center;
            } else {
                upper = center - 1;
            }
        }
        return checkpoints[account][lower].votes;
    }

    function _delegate(address delegator, address delegatee)
        internal
    {
        address currentDelegate = _delegates[delegator];
        uint256 delegatorBalance = balanceOf(delegator); 
        _delegates[delegator] = delegatee;

        emit DelegateChanged(delegator, currentDelegate, delegatee);

        _moveDelegates(currentDelegate, delegatee, delegatorBalance);
    }

    function _moveDelegates(address srcRep, address dstRep, uint256 amount) internal {
        if (srcRep != dstRep && amount > 0) {
            if (srcRep != address(0)) {
                
                uint32 srcRepNum = numCheckpoints[srcRep];
                uint256 srcRepOld = srcRepNum > 0 ? checkpoints[srcRep][srcRepNum - 1].votes : 0;
                uint256 srcRepNew = srcRepOld.sub(amount);
                _writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew);
            }

            if (dstRep != address(0)) {
                
                uint32 dstRepNum = numCheckpoints[dstRep];
                uint256 dstRepOld = dstRepNum > 0 ? checkpoints[dstRep][dstRepNum - 1].votes : 0;
                uint256 dstRepNew = dstRepOld.add(amount);
                _writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew);
            }
        }
    }

    function _writeCheckpoint(
        address delegatee,
        uint32 nCheckpoints,
        uint256 oldVotes,
        uint256 newVotes
    )
        internal
    {
        uint32 blockNumber = safe32(block.number, "CROW::_writeCheckpoint: block number exceeds 32 bits");

        if (nCheckpoints > 0 && checkpoints[delegatee][nCheckpoints - 1].fromBlock == blockNumber) {
            checkpoints[delegatee][nCheckpoints - 1].votes = newVotes;
        } else {
            checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumber, newVotes);
            numCheckpoints[delegatee] = nCheckpoints + 1;
        }

        emit DelegateVotesChanged(delegatee, oldVotes, newVotes);
    }

    function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {
        require(n < 2**32, errorMessage);
        return uint32(n);
    }
}

interface ICrowReferral {
    
    function recordReferral(address user, address referrer) external;

    
    function recordReferralCommission(address referrer, uint256 commission) external;

    
    function getReferrer(address user) external view returns (address);
}

contract MasterChef is Ownable {
    using SafeMath for uint256;
    using SafeERC20 for IERC20;

    
    struct UserInfo {
        uint256 amount;     
        uint256 rewardDebt; 
        
        
        
        
        
        
        
        
        
        
        
    }

    
    struct PoolInfo {
        IERC20 lpToken;           
        uint256 allocPoint;       
        uint256 lastRewardBlock;  
        uint256 accCrowPerShare; 
    }

    
    CrowToken public crow;
    
    CrowBar public xCrow;
    
    address public devaddr;
    
    uint256 public crowPerBlock;
    
    uint256 public BONUS_MULTIPLIER = 1;

    
    PoolInfo[] public poolInfo;
    
    mapping (uint256 => mapping (address => UserInfo)) public userInfo;
    
    uint256 public totalAllocPoint = 0;
    
    uint256 public startBlock;

    
    ICrowReferral public crowReferral;
    
    uint16 public referralCommissionRate = 100;
    
    uint16 public constant MAXIMUM_REFERRAL_COMMISSION_RATE = 1000;

    event Deposit(address indexed user, uint256 indexed pid, uint256 amount);
    event Withdraw(address indexed user, uint256 indexed pid, uint256 amount);
    event EmergencyWithdraw(address indexed user, uint256 indexed pid, uint256 amount);
    event ReferralCommissionPaid(address indexed user, address indexed referrer, uint256 commissionAmount);

    constructor(
        CrowToken _crow,
        CrowBar _xCrow,
        address _devaddr,
        uint256 _crowPerBlock,
        uint256 _startBlock
    ) {
        crow = _crow;
        xCrow = _xCrow;
        devaddr = _devaddr;
        crowPerBlock = _crowPerBlock;
        startBlock = _startBlock;

        
        poolInfo.push(PoolInfo({
            lpToken: _crow,
            allocPoint: 1000,
            lastRewardBlock: startBlock,
            accCrowPerShare: 0
        }));

        totalAllocPoint = 1000;

    }

    function updateMultiplier(uint256 multiplierNumber) public onlyOwner {
        BONUS_MULTIPLIER = multiplierNumber;
    }

    function poolLength() external view returns (uint256) {
        return poolInfo.length;
    }

    
    
    function add(uint256 _allocPoint, IERC20 _lpToken, bool _withUpdate) public onlyOwner {
        if (_withUpdate) {
            massUpdatePools();
        }
        uint256 lastRewardBlock = block.number > startBlock ? block.number : startBlock;
        totalAllocPoint = totalAllocPoint.add(_allocPoint);
        poolInfo.push(PoolInfo({
            lpToken: _lpToken,
            allocPoint: _allocPoint,
            lastRewardBlock: lastRewardBlock,
            accCrowPerShare: 0
        }));
        updateStakingPool();
    }

    
    function set(uint256 _pid, uint256 _allocPoint, bool _withUpdate) public onlyOwner {
        if (_withUpdate) {
            massUpdatePools();
        }
        uint256 prevAllocPoint = poolInfo[_pid].allocPoint;
        poolInfo[_pid].allocPoint = _allocPoint;
        if (prevAllocPoint != _allocPoint) {
            totalAllocPoint = totalAllocPoint.sub(prevAllocPoint).add(_allocPoint);
            updateStakingPool();
        }
    }

    function updateStakingPool() internal {
        uint256 length = poolInfo.length;
        uint256 points = 0;
        for (uint256 pid = 1; pid < length; ++pid) {
            points = points.add(poolInfo[pid].allocPoint);
        }
        if (points != 0) {
            points = points.div(3);
            totalAllocPoint = totalAllocPoint.sub(poolInfo[0].allocPoint).add(points);
            poolInfo[0].allocPoint = points;
        }
    }

    
    function getMultiplier(uint256 _from, uint256 _to) public view returns (uint256) {
        return _to.sub(_from).mul(BONUS_MULTIPLIER);
    }

    
    function pendingCrow(uint256 _pid, address _user) external view returns (uint256) {
        PoolInfo storage pool = poolInfo[_pid];
        UserInfo storage user = userInfo[_pid][_user];
        uint256 accCrowPerShare = pool.accCrowPerShare;
        uint256 lpSupply = pool.lpToken.balanceOf(address(this));
        if (block.number > pool.lastRewardBlock && lpSupply != 0) {
            uint256 multiplier = getMultiplier(pool.lastRewardBlock, block.number);
            uint256 crowReward = multiplier.mul(crowPerBlock).mul(pool.allocPoint).div(totalAllocPoint);
            accCrowPerShare = accCrowPerShare.add(crowReward.mul(1e12).div(lpSupply));
        }
        return user.amount.mul(accCrowPerShare).div(1e12).sub(user.rewardDebt);
    }

    
    function massUpdatePools() public {
        uint256 length = poolInfo.length;
        for (uint256 pid = 0; pid < length; ++pid) {
            updatePool(pid);
        }
    }


    
    function updatePool(uint256 _pid) public {
        PoolInfo storage pool = poolInfo[_pid];
        if (block.number <= pool.lastRewardBlock) {
            return;
        }
        uint256 lpSupply = pool.lpToken.balanceOf(address(this));
        if (lpSupply == 0) {
            pool.lastRewardBlock = block.number;
            return;
        }
        uint256 multiplier = getMultiplier(pool.lastRewardBlock, block.number);
        uint256 crowReward = multiplier.mul(crowPerBlock).mul(pool.allocPoint).div(totalAllocPoint);
        crow.mint(devaddr, crowReward.div(10));
        crow.mint(address(xCrow), crowReward);
        pool.accCrowPerShare = pool.accCrowPerShare.add(crowReward.mul(1e12).div(lpSupply));
        pool.lastRewardBlock = block.number;
    }

    
    function deposit(uint256 _pid, uint256 _amount, address _referrer) public {

        require (_pid != 0, 'deposit CROW by staking');

        PoolInfo storage pool = poolInfo[_pid];
        UserInfo storage user = userInfo[_pid][msg.sender];
        updatePool(_pid);
        if (_amount > 0 && address(crowReferral) != address(0) && _referrer != address(0) && _referrer != msg.sender) {
            crowReferral.recordReferral(msg.sender, _referrer);
        }
        if (user.amount > 0) {
            uint256 pending = user.amount.mul(pool.accCrowPerShare).div(1e12).sub(user.rewardDebt);
            if(pending > 0) {
                safeCrowTransfer(msg.sender, pending);
                payReferralCommission(msg.sender, pending);
            }
        }
        if (_amount > 0) {
            pool.lpToken.safeTransferFrom(address(msg.sender), address(this), _amount);
            user.amount = user.amount.add(_amount);
        }
        user.rewardDebt = user.amount.mul(pool.accCrowPerShare).div(1e12);
        emit Deposit(msg.sender, _pid, _amount);
    }

    
    function withdraw(uint256 _pid, uint256 _amount) public {

        require (_pid != 0, 'withdraw CROW by unstaking');
        PoolInfo storage pool = poolInfo[_pid];
        UserInfo storage user = userInfo[_pid][msg.sender];
        require(user.amount >= _amount, "withdraw: not good");

        updatePool(_pid);
        uint256 pending = user.amount.mul(pool.accCrowPerShare).div(1e12).sub(user.rewardDebt);
        if(pending > 0) {
            safeCrowTransfer(msg.sender, pending);
            payReferralCommission(msg.sender, pending);
        }
        if(_amount > 0) {
            user.amount = user.amount.sub(_amount);
            pool.lpToken.safeTransfer(address(msg.sender), _amount);
        }
        user.rewardDebt = user.amount.mul(pool.accCrowPerShare).div(1e12);
        emit Withdraw(msg.sender, _pid, _amount);
    }

    
    function enterStaking(uint256 _amount) public {
        PoolInfo storage pool = poolInfo[0];
        UserInfo storage user = userInfo[0][msg.sender];
        updatePool(0);
        if (user.amount > 0) {
            uint256 pending = user.amount.mul(pool.accCrowPerShare).div(1e12).sub(user.rewardDebt);
            if(pending > 0) {
                safeCrowTransfer(msg.sender, pending);
            }
        }
        if(_amount > 0) {
            pool.lpToken.safeTransferFrom(address(msg.sender), address(this), _amount);
            user.amount = user.amount.add(_amount);
        }
        user.rewardDebt = user.amount.mul(pool.accCrowPerShare).div(1e12);

        xCrow.mint(msg.sender, _amount);
        emit Deposit(msg.sender, 0, _amount);
    }

    
    function leaveStaking(uint256 _amount) public {
        PoolInfo storage pool = poolInfo[0];
        UserInfo storage user = userInfo[0][msg.sender];
        require(user.amount >= _amount, "withdraw: not good");
        updatePool(0);
        uint256 pending = user.amount.mul(pool.accCrowPerShare).div(1e12).sub(user.rewardDebt);
        if(pending > 0) {
            safeCrowTransfer(msg.sender, pending);
        }
        if(_amount > 0) {
            user.amount = user.amount.sub(_amount);
            pool.lpToken.safeTransfer(address(msg.sender), _amount);
        }
        user.rewardDebt = user.amount.mul(pool.accCrowPerShare).div(1e12);

        xCrow.burn(msg.sender, _amount);
        emit Withdraw(msg.sender, 0, _amount);
    }

    
    function emergencyWithdraw(uint256 _pid) public {
        PoolInfo storage pool = poolInfo[_pid];
        UserInfo storage user = userInfo[_pid][msg.sender];
        pool.lpToken.safeTransfer(address(msg.sender), user.amount);
        emit EmergencyWithdraw(msg.sender, _pid, user.amount);
        user.amount = 0;
        user.rewardDebt = 0;
    }

    
    function safeCrowTransfer(address _to, uint256 _amount) internal {
        xCrow.safeCrowTransfer(_to, _amount);
    }

    
    function dev(address _devaddr) public {
        require(msg.sender == devaddr, "dev: wut?");
        devaddr = _devaddr;
    }

    
    function mint(address _to, uint256 amount) public onlyOwner {
        crow.mint(_to, amount);
    }

    
    function setCrowReferral(ICrowReferral _crowReferral) public onlyOwner {
        crowReferral = _crowReferral;
    }

    
    function setReferralCommissionRate(uint16 _referralCommissionRate) public onlyOwner {
        require(_referralCommissionRate <= MAXIMUM_REFERRAL_COMMISSION_RATE, "setReferralCommissionRate: invalid referral commission rate basis points");
        referralCommissionRate = _referralCommissionRate;
    }

    
    function payReferralCommission(address _user, uint256 _pending) internal {
        if (address(crowReferral) != address(0) && referralCommissionRate > 0) {
            address referrer = crowReferral.getReferrer(_user);
            uint256 commissionAmount = _pending.mul(referralCommissionRate).div(10000);

            if (referrer != address(0) && commissionAmount > 0) {
                crow.mint(referrer, commissionAmount);
                crowReferral.recordReferralCommission(referrer, commissionAmount);
                emit ReferralCommissionPaid(_user, referrer, commissionAmount);
            }
        }
    }
}
        

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_crow","internalType":"contract CrowToken"},{"type":"address","name":"_xCrow","internalType":"contract CrowBar"},{"type":"address","name":"_devaddr","internalType":"address"},{"type":"uint256","name":"_crowPerBlock","internalType":"uint256"},{"type":"uint256","name":"_startBlock","internalType":"uint256"}]},{"type":"event","name":"Deposit","inputs":[{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"uint256","name":"pid","internalType":"uint256","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"EmergencyWithdraw","inputs":[{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"uint256","name":"pid","internalType":"uint256","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"ReferralCommissionPaid","inputs":[{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"address","name":"referrer","internalType":"address","indexed":true},{"type":"uint256","name":"commissionAmount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Withdraw","inputs":[{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"uint256","name":"pid","internalType":"uint256","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"BONUS_MULTIPLIER","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint16","name":"","internalType":"uint16"}],"name":"MAXIMUM_REFERRAL_COMMISSION_RATE","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"add","inputs":[{"type":"uint256","name":"_allocPoint","internalType":"uint256"},{"type":"address","name":"_lpToken","internalType":"contract IERC20"},{"type":"bool","name":"_withUpdate","internalType":"bool"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract CrowToken"}],"name":"crow","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"crowPerBlock","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract ICrowReferral"}],"name":"crowReferral","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"deposit","inputs":[{"type":"uint256","name":"_pid","internalType":"uint256"},{"type":"uint256","name":"_amount","internalType":"uint256"},{"type":"address","name":"_referrer","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"dev","inputs":[{"type":"address","name":"_devaddr","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"devaddr","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"emergencyWithdraw","inputs":[{"type":"uint256","name":"_pid","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"enterStaking","inputs":[{"type":"uint256","name":"_amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getMultiplier","inputs":[{"type":"uint256","name":"_from","internalType":"uint256"},{"type":"uint256","name":"_to","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"leaveStaking","inputs":[{"type":"uint256","name":"_amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"massUpdatePools","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"mint","inputs":[{"type":"address","name":"_to","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"pendingCrow","inputs":[{"type":"uint256","name":"_pid","internalType":"uint256"},{"type":"address","name":"_user","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"lpToken","internalType":"contract IERC20"},{"type":"uint256","name":"allocPoint","internalType":"uint256"},{"type":"uint256","name":"lastRewardBlock","internalType":"uint256"},{"type":"uint256","name":"accCrowPerShare","internalType":"uint256"}],"name":"poolInfo","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"poolLength","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint16","name":"","internalType":"uint16"}],"name":"referralCommissionRate","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"set","inputs":[{"type":"uint256","name":"_pid","internalType":"uint256"},{"type":"uint256","name":"_allocPoint","internalType":"uint256"},{"type":"bool","name":"_withUpdate","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setCrowReferral","inputs":[{"type":"address","name":"_crowReferral","internalType":"contract ICrowReferral"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setReferralCommissionRate","inputs":[{"type":"uint16","name":"_referralCommissionRate","internalType":"uint16"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"startBlock","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalAllocPoint","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateMultiplier","inputs":[{"type":"uint256","name":"multiplierNumber","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updatePool","inputs":[{"type":"uint256","name":"_pid","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"uint256","name":"rewardDebt","internalType":"uint256"}],"name":"userInfo","inputs":[{"type":"uint256","name":"","internalType":"uint256"},{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdraw","inputs":[{"type":"uint256","name":"_pid","internalType":"uint256"},{"type":"uint256","name":"_amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract CrowBar"}],"name":"xCrow","inputs":[]}]
            

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106101f05760003560e01c80635ffe61461161010f5780638dbdbe6d116100a2578063d30ef61b11610071578063d30ef61b14610458578063d49e77cd1461046d578063f2fde38b14610480578063f93000841461049357600080fd5b80638dbdbe6d146103d857806393f1a40b146103eb5780639fadeabf14610432578063c9c0b81e1461044557600080fd5b80638aa28550116100de5780638aa28550146103985780638d88a90e146103a15780638da5cb5b146103b45780638dbb1e3a146103c557600080fd5b80635ffe614614610362578063630b5ba11461037557806364482f791461037d578063715018a61461039057600080fd5b806343972942116101875780634980d1d8116101565780634980d1d81461031657806351eb05a6146103295780635312ea8e1461033c57806355dbc8261461034f57600080fd5b806343972942146102cb578063441a3e70146102de57806348b22bfb146102f157806348cd4cb11461030d57600080fd5b80631eaaa045116101c35780631eaaa0451461026757806333a927991461027a57806340c10f19146102a557806341441d3b146102b857600080fd5b8063081e3eda146101f55780631058d2811461020c5780631526fe271461022157806317caf6f11461025e575b600080fd5b6006545b6040519081526020015b60405180910390f35b61021f61021a366004611d85565b61049c565b005b61023461022f366004611d85565b61068e565b604080516001600160a01b0390951685526020850193909352918301526060820152608001610203565b6101f960085481565b61021f610275366004611de4565b6106d2565b600a5461028d906001600160a01b031681565b6040516001600160a01b039091168152602001610203565b61021f6102b3366004611d1c565b61082a565b61021f6102c6366004611d85565b6108bf565b61021f6102d9366004611ce4565b610a60565b61021f6102ec366004611e25565b610aac565b6102fa6103e881565b60405161ffff9091168152602001610203565b6101f960095481565b6101f9610324366004611db5565b610c66565b61021f610337366004611d85565b610de6565b61021f61034a366004611d85565b611018565b61021f61035d366004611d63565b6110c8565b61021f610370366004611d85565b6111a1565b61021f6111d0565b61021f61038b366004611e73565b6111fb565b61021f6112d2565b6101f960055481565b61021f6103af366004611ce4565b611308565b6000546001600160a01b031661028d565b6101f96103d3366004611e25565b611370565b61021f6103e6366004611e46565b61138b565b61041d6103f9366004611db5565b60076020908152600092835260408084209091529082529020805460019091015482565b60408051928352602083019190915201610203565b60015461028d906001600160a01b031681565b60025461028d906001600160a01b031681565b600a546102fa90600160a01b900461ffff1681565b60035461028d906001600160a01b031681565b61021f61048e366004611ce4565b6115ad565b6101f960045481565b600060066000815481106104c057634e487b7160e01b600052603260045260246000fd5b600091825260208083203384527f6d5257204ebe7d88fd91ae87941cb2dd9d8062b64ae5a2bd2d28ec40b9fbf6df909152604090922080546004909202909201925083111561054b5760405162461bcd60e51b81526020600482015260126024820152711dda5d1a191c985dce881b9bdd0819dbdbd960721b60448201526064015b60405180910390fd5b6105556000610de6565b600061058f826001015461058964e8d4a510006105838760030154876000015461164890919063ffffffff16565b90611654565b90611660565b905080156105a1576105a1338261166c565b83156105cb5781546105b39085611660565b825582546105cb906001600160a01b031633866116a5565b600383015482546105e69164e8d4a510009161058391611648565b6001830155600254604051632770a7eb60e21b8152336004820152602481018690526001600160a01b0390911690639dc29fac90604401600060405180830381600087803b15801561063757600080fd5b505af115801561064b573d6000803e3d6000fd5b5050604051868152600092503391507ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568906020015b60405180910390a350505050565b6006818154811061069e57600080fd5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169350919084565b6000546001600160a01b031633146106fc5760405162461bcd60e51b815260040161054290611eef565b801561070a5761070a6111d0565b6000600954431161071d5760095461071f565b435b60085490915061072f908561170d565b600855604080516080810182526001600160a01b0385811682526020820187815292820184815260006060840181815260068054600181018255925293517ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f600490920291820180546001600160a01b031916919094161790925592517ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d4082015591517ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d41830155517ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d4290910155610824611719565b50505050565b6000546001600160a01b031633146108545760405162461bcd60e51b815260040161054290611eef565b6001546040516340c10f1960e01b81526001600160a01b03848116600483015260248201849052909116906340c10f19906044015b600060405180830381600087803b1580156108a357600080fd5b505af11580156108b7573d6000803e3d6000fd5b505050505050565b600060066000815481106108e357634e487b7160e01b600052603260045260246000fd5b600091825260208083203384527f6d5257204ebe7d88fd91ae87941cb2dd9d8062b64ae5a2bd2d28ec40b9fbf6df9091526040832060049092020192509061092a90610de6565b80541561097357600061095f826001015461058964e8d4a510006105838760030154876000015461164890919063ffffffff16565b9050801561097157610971338261166c565b505b821561099f578154610990906001600160a01b0316333086611822565b805461099c908461170d565b81555b600382015481546109ba9164e8d4a510009161058391611648565b60018201556002546040516340c10f1960e01b8152336004820152602481018590526001600160a01b03909116906340c10f1990604401600060405180830381600087803b158015610a0b57600080fd5b505af1158015610a1f573d6000803e3d6000fd5b5050604051858152600092503391507f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a159060200160405180910390a3505050565b6000546001600160a01b03163314610a8a5760405162461bcd60e51b815260040161054290611eef565b600a80546001600160a01b0319166001600160a01b0392909216919091179055565b81610af95760405162461bcd60e51b815260206004820152601a60248201527f77697468647261772043524f5720627920756e7374616b696e670000000000006044820152606401610542565b600060068381548110610b1c57634e487b7160e01b600052603260045260246000fd5b600091825260208083208684526007825260408085203386529092529220805460049092029092019250831115610b8a5760405162461bcd60e51b81526020600482015260126024820152711dda5d1a191c985dce881b9bdd0819dbdbd960721b6044820152606401610542565b610b9384610de6565b6000610bc1826001015461058964e8d4a510006105838760030154876000015461164890919063ffffffff16565b90508015610bdd57610bd3338261166c565b610bdd338261185a565b8315610c07578154610bef9085611660565b82558254610c07906001600160a01b031633866116a5565b60038301548254610c229164e8d4a510009161058391611648565b6001830155604051848152859033907ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568906020015b60405180910390a35050505050565b60008060068481548110610c8a57634e487b7160e01b600052603260045260246000fd5b600091825260208083208784526007825260408085206001600160a01b038981168752935280852060049485029092016003810154815492516370a0823160e01b8152309681019690965290965091949193919216906370a082319060240160206040518083038186803b158015610d0157600080fd5b505afa158015610d15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d399190611d9d565b9050836002015443118015610d4d57508015155b15610db3576000610d62856002015443611370565b90506000610d8f6008546105838860010154610d896004548761164890919063ffffffff16565b90611648565b9050610dae610da7846105838464e8d4a51000611648565b859061170d565b935050505b610ddb836001015461058964e8d4a5100061058386886000015461164890919063ffffffff16565b979650505050505050565b600060068281548110610e0957634e487b7160e01b600052603260045260246000fd5b9060005260206000209060040201905080600201544311610e28575050565b80546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b158015610e6b57600080fd5b505afa158015610e7f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea39190611d9d565b905080610eb557504360029091015550565b6000610ec5836002015443611370565b90506000610eec6008546105838660010154610d896004548761164890919063ffffffff16565b6001546003549192506001600160a01b03908116916340c10f199116610f1384600a611654565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015610f5957600080fd5b505af1158015610f6d573d6000803e3d6000fd5b50506001546002546040516340c10f1960e01b81526001600160a01b03918216600482015260248101869052911692506340c10f199150604401600060405180830381600087803b158015610fc157600080fd5b505af1158015610fd5573d6000803e3d6000fd5b50505050611003610ff88461058364e8d4a510008561164890919063ffffffff16565b60038601549061170d565b60038501555050436002909201919091555050565b60006006828154811061103b57634e487b7160e01b600052603260045260246000fd5b60009182526020808320858452600782526040808520338087529352909320805460049093029093018054909450611080926001600160a01b039190911691906116a5565b8054604051908152839033907fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae05959060200160405180910390a360008082556001909101555050565b6000546001600160a01b031633146110f25760405162461bcd60e51b815260040161054290611eef565b6103e861ffff8216111561117f5760405162461bcd60e51b815260206004820152604860248201527f736574526566657272616c436f6d6d697373696f6e526174653a20696e76616c60448201527f696420726566657272616c20636f6d6d697373696f6e207261746520626173696064820152677320706f696e747360c01b608482015260a401610542565b600a805461ffff909216600160a01b0261ffff60a01b19909216919091179055565b6000546001600160a01b031633146111cb5760405162461bcd60e51b815260040161054290611eef565b600555565b60065460005b818110156111f7576111e781610de6565b6111f081611fbe565b90506111d6565b5050565b6000546001600160a01b031633146112255760405162461bcd60e51b815260040161054290611eef565b8015611233576112336111d0565b60006006848154811061125657634e487b7160e01b600052603260045260246000fd5b9060005260206000209060040201600101549050826006858154811061128c57634e487b7160e01b600052603260045260246000fd5b906000526020600020906004020160010181905550828114610824576112c7836112c18360085461166090919063ffffffff16565b9061170d565b600855610824611719565b6000546001600160a01b031633146112fc5760405162461bcd60e51b815260040161054290611eef565b6113066000611a5a565b565b6003546001600160a01b0316331461134e5760405162461bcd60e51b81526020600482015260096024820152686465763a207775743f60b81b6044820152606401610542565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b60055460009061138490610d898486611660565b9392505050565b826113d85760405162461bcd60e51b815260206004820152601760248201527f6465706f7369742043524f57206279207374616b696e670000000000000000006044820152606401610542565b6000600684815481106113fb57634e487b7160e01b600052603260045260246000fd5b6000918252602080832087845260078252604080852033865290925292206004909102909101915061142c85610de6565b6000841180156114465750600a546001600160a01b031615155b801561145a57506001600160a01b03831615155b801561146f57506001600160a01b0383163314155b156114da57600a54604051630c7f7b6b60e01b81523360048201526001600160a01b03858116602483015290911690630c7f7b6b90604401600060405180830381600087803b1580156114c157600080fd5b505af11580156114d5573d6000803e3d6000fd5b505050505b80541561152d57600061150f826001015461058964e8d4a510006105838760030154876000015461164890919063ffffffff16565b9050801561152b57611521338261166c565b61152b338261185a565b505b831561155957815461154a906001600160a01b0316333087611822565b8054611556908561170d565b81555b600382015481546115749164e8d4a510009161058391611648565b6001820155604051848152859033907f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a1590602001610c57565b6000546001600160a01b031633146115d75760405162461bcd60e51b815260040161054290611eef565b6001600160a01b03811661163c5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610542565b61164581611a5a565b50565b60006113848284611f5c565b60006113848284611f3c565b60006113848284611f7b565b6002546040516308e0c4cb60e31b81526001600160a01b0384811660048301526024820184905290911690634706265890604401610889565b6040516001600160a01b03831660248201526044810182905261170890849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611aaa565b505050565b60006113848284611f24565b600654600060015b828110156117805761176e6006828154811061174d57634e487b7160e01b600052603260045260246000fd5b9060005260206000209060040201600101548361170d90919063ffffffff16565b915061177981611fbe565b9050611721565b5080156111f757611792816003611654565b90506117e0816112c160066000815481106117bd57634e487b7160e01b600052603260045260246000fd5b90600052602060002090600402016001015460085461166090919063ffffffff16565b60088190555080600660008154811061180957634e487b7160e01b600052603260045260246000fd5b9060005260206000209060040201600101819055505050565b6040516001600160a01b03808516602483015283166044820152606481018290526108249085906323b872dd60e01b906084016116d1565b600a546001600160a01b0316158015906118805750600a54600160a01b900461ffff1615155b156111f757600a54604051634a9fefc760e01b81526001600160a01b0384811660048301526000921690634a9fefc79060240160206040518083038186803b1580156118cb57600080fd5b505afa1580156118df573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119039190611d00565b600a5490915060009061192a9061271090610583908690600160a01b900461ffff16611648565b90506001600160a01b038216158015906119445750600081115b15610824576001546040516340c10f1960e01b81526001600160a01b03848116600483015260248201849052909116906340c10f1990604401600060405180830381600087803b15801561199757600080fd5b505af11580156119ab573d6000803e3d6000fd5b5050600a54604051631b82d29760e31b81526001600160a01b03868116600483015260248201869052909116925063dc1694b89150604401600060405180830381600087803b1580156119fd57600080fd5b505af1158015611a11573d6000803e3d6000fd5b50505050816001600160a01b0316846001600160a01b03167f86ddab457291316e0f5496737e5ca67c4037234c32c3be04c48ae96186893a7b8360405161068091815260200190565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000611aff826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611b7c9092919063ffffffff16565b8051909150156117085780806020019051810190611b1d9190611d47565b6117085760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610542565b6060611b8b8484600085611b93565b949350505050565b606082471015611bf45760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610542565b843b611c425760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610542565b600080866001600160a01b03168587604051611c5e9190611ea0565b60006040518083038185875af1925050503d8060008114611c9b576040519150601f19603f3d011682016040523d82523d6000602084013e611ca0565b606091505b5091509150610ddb82828660608315611cba575081611384565b825115611cca5782518084602001fd5b8160405162461bcd60e51b81526004016105429190611ebc565b600060208284031215611cf5578081fd5b813561138481611fef565b600060208284031215611d11578081fd5b815161138481611fef565b60008060408385031215611d2e578081fd5b8235611d3981611fef565b946020939093013593505050565b600060208284031215611d58578081fd5b815161138481612004565b600060208284031215611d74578081fd5b813561ffff81168114611384578182fd5b600060208284031215611d96578081fd5b5035919050565b600060208284031215611dae578081fd5b5051919050565b60008060408385031215611dc7578182fd5b823591506020830135611dd981611fef565b809150509250929050565b600080600060608486031215611df8578081fd5b833592506020840135611e0a81611fef565b91506040840135611e1a81612004565b809150509250925092565b60008060408385031215611e37578182fd5b50508035926020909101359150565b600080600060608486031215611e5a578283fd5b83359250602084013591506040840135611e1a81611fef565b600080600060608486031215611e87578283fd5b83359250602084013591506040840135611e1a81612004565b60008251611eb2818460208701611f92565b9190910192915050565b6020815260008251806020840152611edb816040850160208701611f92565b601f01601f19169190910160400192915050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60008219821115611f3757611f37611fd9565b500190565b600082611f5757634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615611f7657611f76611fd9565b500290565b600082821015611f8d57611f8d611fd9565b500390565b60005b83811015611fad578181015183820152602001611f95565b838111156108245750506000910152565b6000600019821415611fd257611fd2611fd9565b5060010190565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b038116811461164557600080fd5b801515811461164557600080fdfea2646970667358221220a49c3d47e84a6b81b485a9c44760e2f4af8a718c637c394df6930f4d51d339fa64736f6c63430008040033