contract LPTokenWrapper {
    using SafeMath for uint256;
    using SafeERC20 for IERC20;
    using Address for address;

    mapping(address => uint256) private _totalSupply; // token_address -> total_supply
    mapping(address => mapping(address => uint256)) private _balances; // token_address -> map(account -> balance)

    function totalSupply(address tokenAddress) public view returns (uint256) {
        return _totalSupply[tokenAddress];
    }

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

    function tokenStake(address tokenAddress, uint256 amount) internal {
        address sender = msg.sender;
        require(!address(sender).isContract(), "Andre, we are farming in peace, go harvest somewhere else sir.");
        require(tx.origin == sender, "Andre, stahp.");
        _totalSupply[tokenAddress] = _totalSupply[tokenAddress].add(amount);
        _balances[tokenAddress][sender] = _balances[tokenAddress][sender].add(amount);
        IERC20(tokenAddress).safeTransferFrom(sender, address(this), amount);
    }

    function tokenWithdraw(address tokenAddress, uint256 amount) internal {
        _totalSupply[tokenAddress] = _totalSupply[tokenAddress].sub(amount);
        _balances[tokenAddress][msg.sender] = _balances[tokenAddress][msg.sender].sub(amount);
        IERC20(tokenAddress).safeTransfer(msg.sender, amount);
    }
}
function totalSupply(address tokenAddress) public view returns (uint256) {
    return _totalSupply[tokenAddress];
}

// token_address -> map(account -> balance)