hats-finance / Tapioca-0xe0b920d38a0900af3bab7ff0ca0af554129f54ad

1 stars 2 forks source link

Inability to lock `TAP` for any user in the `twTAP` contract #20

Open hats-bug-reporter[bot] opened 1 month ago

hats-bug-reporter[bot] commented 1 month ago

Github username: @bauchibred Twitter username: Bauchibred Submission hash (on-chain): 0xee35e968cc281e9b052def1e5ea5cfa6ea6c3ee8cf81e440b8c562367846a985 Severity: high

Description: Description

Take a look at https://github.com/hats-finance/Tapioca-0xe0b920d38a0900af3bab7ff0ca0af554129f54ad/blob/baddafc15616a5674e73c2f5a920b92bf9b21888/contracts/tokens/TapTokenReceiver.sol#L120C1-L135C6

    function _lockTwTapPositionReceiver(address _srcChainSender, bytes memory _data) internal virtual twTapExists {
        LockTwTapPositionMsg memory lockTwTapPositionMsg_ = TapTokenCodec.decodeLockTwpTapDstMsg(_data);

        /// @dev xChain owner needs to have approved dst srcChain `sendPacket()` msg.sender in a previous composedMsg. Or be the same address.
        _internalTransferWithAllowance(lockTwTapPositionMsg_.user, _srcChainSender, lockTwTapPositionMsg_.amount);

        // _approve(address(this), address(twTap), lockTwTapPositionMsg_.amount);
        _approve(address(this), address(pearlmit), lockTwTapPositionMsg_.amount);
        //@audit
        pearlmit.approve(
            20, address(this), 0, address(twTap), uint200(lockTwTapPositionMsg_.amount), uint48(block.timestamp + 1)
        );
        twTap.participate(lockTwTapPositionMsg_.user, lockTwTapPositionMsg_.amount, lockTwTapPositionMsg_.duration);
        _approve(address(this), address(pearlmit), 0);

        emit LockTwTapReceived(lockTwTapPositionMsg_.user, lockTwTapPositionMsg_.duration, lockTwTapPositionMsg_.amount);
    }

This function's core use as documented is to lock TAP for users in the twTAP contract. In it's execution thefunction makes a query to approve via pearlmit, however this is the specification on IPearlmit's approve: function approve(address token, uint256 id, address operator, uint200 amount, uint48 expiration) external;

Which showcases that it needs five parameters, the instance above from _lockTwTapPositionReceiver() as hinted by the @audit tag however passes in 6 parameters, with the uint256 20 not being accounted for on Pearlmit, this then leads to all attempts to lock the TwTapPositionReceiver to revert as the function signature would not match anything on IPearlmit, making the call to pearlmit.approve() be unsuccessful.

This essentially makes it impossible to lock tokens TAP for any user in the twTAP contract which is a core functionality and also any logic that queries TapTokenReceiver#_lockTwTapPositionReceiver() would also revert.

Attack Scenario N/A Recommendation Correctly query pearlmit.approve() by passing in the right parameters Attachments

  1. Proof of Concept (PoC) File

N/A

  1. Revised Code File (Optional)

N/A

maarcweiss commented 1 month ago

Hey @bauchired https://github.com/limitbreakinc/PermitC/blob/65e3a4a493aa14d1a03c23512233d7546e8f1e96/src/PermitC.sol#L182

Permit.approve in fact has 6 params has you can see on the link.

Make sure to check all the commits properly as might be that you are checking an old one.