sherlock-audit / 2024-06-boost-aa-wallet-judging

3 stars 1 forks source link

scyron6 - `clawback` is not callable on provided incentive contracts because owner is set to BoostCore address #462

Open sherlock-admin2 opened 2 months ago

sherlock-admin2 commented 2 months ago

scyron6

Medium

clawback is not callable on provided incentive contracts because owner is set to BoostCore address

Summary

The clawback function on the in scope incentive contracts has the onlyOwner modifier. Here is an example,

CGDAIncentive.sol#L103-L112

    function clawback(bytes calldata data_) external virtual override onlyOwner returns (bool) {
        ClawbackPayload memory claim_ = abi.decode(data_, (ClawbackPayload));
        (uint256 amount) = abi.decode(claim_.data, (uint256));

        // Transfer the tokens back to the intended recipient
        asset.safeTransfer(claim_.target, amount);
        emit Claimed(claim_.target, abi.encodePacked(asset, claim_.target, amount));

        return true;
    }

The problem is that all of the incentive contracts are initialized by BoostCore and set the owner to the BoostCore address. BoostCore does not contain any logic to call clawback on the incentives. This is a design issue that makes clawback uncallable for any of the provided incentive contracts.

Impact

If users use the provided incentive contracts when they make a boost, they will not be able to call clawback and funds will not be retrievable from boost incentives.

Consider if a boost is created with an action that is restricted by timestamps. For example, a user creates a boost to incentive minting an NFT during a certain period of time. If the NFT is unpopular and nobody decides to mint during that period, any funds sent to that boost incentive will be locked.

Code Snippet

    function testIncentiveClawbacksNotCallable() public {
        boostCore.createBoost(validCreateCalldata);
        assertEq(1, boostCore.getBoostCount());

        address myIncentive = address(boostCore.getBoost(0).incentives[0]);
        assertEq(boostCore.getBoost(0).owner, address(1));
        assertNotEq(address(1), Ownable(myIncentive).owner());
        assertEq(address(boostCore), Ownable(myIncentive).owner());
    }

Tool used

Manual Review

Recommendation

The incentive owner should be set to be equal to the boost owner.