Malicious actor can transfer user reward or exit user's position (transfer TAP token) to approved address that does not design to receive token and make user lose fund.
Audit: 2024-02-tapioca-findings
Severity: HIGH

# Lines of code

https://github.com/Tapioca-DAO/tap-token/blob/20a83b1d2d5577653610a6c3879dff9df4968345/contracts/governance/twTAP.sol#L548


# Vulnerability details

## Impact

Incorrect access control when user claim token reward and exitPosition

## Proof of Concept

In TwTAP.sol,

when user claim rewards, the authorization is implemented below

```
  function claimRewards(uint256 _tokenId, address _to)
        external
        nonReentrant
        whenNotPaused
        returns (uint256[] memory amounts_)
    {
        _requireClaimPermission(_to, _tokenId);
        amounts_ = _claimRewards(_tokenId, _to);
    }

```

this calls [the code](https://github.com/Tapioca-DAO/tap-token/blob/20a83b1d2d5577653610a6c3879dff9df4968345/contracts/governance/twTAP.sol#L548)

```
  function _requireClaimPermission(address _to, uint256 _tokenId) internal view {
        if (!_isApprovedOrOwner(_to, _tokenId) && !isERC721Approved(_ownerOf(_tokenId), _to, address(this), _tokenId)) {
            revert NotApproved(_tokenId, msg.sender);
        }
    }
```

we are checking if address(to) is an approved operator of the nft owner token id

then if the address(to) is an approved operator, anyone can put address(to) in and claim reward onbehalf of nft owner.

same vulnerable pattern of access control is implemented when user wants to exit the position

```
  function exitPosition(uint256 _tokenId, address _to)
        external
        nonReentrant
        whenNotPaused
        returns (uint256 tapAmount_)
    {
        {
            address owner_ = ownerOf(_tokenId);
            if (_to != owner_) {
                _requireClaimPermission(_to, _tokenId);
            }
        }
        tapAmount_ = _releaseTap(_tokenId, _to);
    }
```

The code bascially means that if the address(to) is an approved operator of the token id, anyone can exit Position and transfer the TAP token to the address(to) approved operator address

suppose when user hold the twTAP NFT after locking their TAP token,

1. they can trade and sell their nft and it is commont for user to approve a third party smart contract as operator

(for example, user wants to trade on opensea, they need to approve opensea contract, user wants to trade on blur they needs to approve blur contract)

2. then malicious actor can just claim the user's nft token rewards to the blur contract, or the malicious contract can call exitPosition

3. then malicious actor can just transfer the TAP token to the blur contract if the blur contract is address(to) when exitPosition.

these approved operator may designed to trade nft but not designed to receive reward

and user approve an operator to transfer onbehalf user does not mean user wants to let the approved operator receive rewards.

so in this case, does not use msg.sender and only check address(to) is approved make user lose fund.

## Tools Used

Manual Review

## Recommended Mitigation Steps

check if msg.sender is an approved operator instead of checking if the addres