At default there not able to..though its pretty easy to edit PunBB to make moderators do that. I did it once, but it wasn't that secure. I don't think I did it in the most safest way. Just edit this part of profile.php..
else if (isset($_POST['update_group_membership']))
{
if ($pun_user['g_id'] > PUN_ADMIN)
message($lang_common['No permission']);
confirm_referrer('profile.php');
$new_group_id = intval($_POST['group_id']);
$db->query('UPDATE '.$db->prefix.'users SET group_id='.$new_group_id.' WHERE id='.$id) or error('Unable to change user group', __FILE__, __LINE__, $db->error());
// If the user was a moderator or an administrator, we remove him/her from the moderator list in all forums as well
if ($new_group_id > PUN_MOD)
{
$result = $db->query('SELECT id, moderators FROM '.$db->prefix.'forums') or error('Unable to fetch forum list', __FILE__, __LINE__, $db->error());
while ($cur_forum = $db->fetch_assoc($result))
{
$cur_moderators = ($cur_forum['moderators'] != '') ? unserialize($cur_forum['moderators']) : array();
if (in_array($id, $cur_moderators))
{
$username = array_search($id, $cur_moderators);
unset($cur_moderators[$username]);
$cur_moderators = (!empty($cur_moderators)) ? '\''.$db->escape(serialize($cur_moderators)).'\'' : 'NULL';
$db->query('UPDATE '.$db->prefix.'forums SET moderators='.$cur_moderators.' WHERE id='.$cur_forum['id']) or error('Unable to update forum', __FILE__, __LINE__, $db->error());
}
}
}
redirect('profile.php?section=admin&id='.$id, $lang_profile['Group membership redirect']);
}