Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Invalid Fee Handling in Boost Core #133

Open
1 task done
Quazia opened this issue Sep 30, 2024 · 0 comments
Open
1 task done

fix: Invalid Fee Handling in Boost Core #133

Quazia opened this issue Sep 30, 2024 · 0 comments
Labels
bug Something isn't working

Comments

@Quazia
Copy link
Member

Quazia commented Sep 30, 2024

Is there an existing issue for this?

  • I have searched the existing issues

Package Version

0.0.0-alpha.12

Current Behavior

Summary
The boost creator can set the value of referralFee to 9_000 when creating the boost. The BoostCore::referralFee (the base fee) is set to 1000 in line 70,

https://github.com/sherlock-audit/2024-06-boost-aa-wallet/blob/main/boost-protocol/packages/evm/contracts/BoostCore.sol#L70

and added to the boost creator input in line 122,

https://github.com/sherlock-audit/2024-06-boost-aa-wallet/blob/main/boost-protocol/packages/evm/contracts/BoostCore.sol#L122

This will make the BoostCore::referralFee to be 10_000 (equal to the BoostCore::FEE_DENOMINATOR) ensuring that 100% of the fees collected when claimants claim their incentives are sent to the referrer address. To get the fees, the boost creator just need to ensure claimants use his address as referrer_ address. The protocol will never receive any fee for this particular boost.

Expected Behavior

No response

Steps To Reproduce

Root Cause
Maximum value for BoostCore::referralFee was not set, allowing boost creators to allocate unlimited fraction of the fees to the referrer.

Internal pre-conditions
No response

External pre-conditions
No response

Attack Path
No response

Impact
The protocol will receive no fees as all the fees will continuously be sent to the referrer_ address.

PoC
Please copy the code below into BoostCore.t.sol and run the test.

    uint64 public constant boostAdditionalReferralFee = 9_000; // additional 90%
    uint256 public constant PRECISION = 10_000;
    uint256 public constant BASE_FEE = 1_000; // 10%
    bytes invalidCreateCalldata =
        LibZip.cdCompress(
            abi.encode(
                BoostCore.InitPayload({
                    budget: budget,
                    action: action,
                    validator: BoostLib.Target({
                        isBase: true,
                        instance: address(0),
                        parameters: ""
                    }),
                    allowList: allowList,
                    incentives: _makeIncentives(1),
                    protocolFee: 500, // 5%
                    referralFee: boostAdditionalReferralFee, // 90%
                    maxParticipants: 10_000,
                    owner: address(1)
                })
            )
        );

    function testClaimIncentive_ReferralTakesAllFees_audit() public {
        uint256 claimFee = 0.000075 ether;
        // Create a Boost first
        boostCore.createBoost(invalidCreateCalldata);

        // Mint an ERC721 token to the claimant (this contract)
        uint256 tokenId = 1;
        mockERC721.mint{value: 0.1 ether}(address(this));
        mockERC721.mint{value: 0.1 ether}(address(this));
        mockERC721.mint{value: 0.1 ether}(address(this));

        // Prepare the data payload for validation
        bytes memory data = abi.encode(address(this), abi.encode(tokenId));
        address referralAddress = makeAddr("referral");
        address protocolFeeReceiver = boostCore.protocolFeeReceiver();
        uint256 initialProtocolFeeReceiverBalance = protocolFeeReceiver.balance;
        // Claim the incentive
        boostCore.claimIncentive{value: claimFee}(0, 0, referralAddress, data);

        uint256 actualReferrerBalance = referralAddress.balance;
        uint256 finalProtocolFeeReceiverBalance = protocolFeeReceiver.balance;
        // check referral balance
        assertEq(actualReferrerBalance, claimFee);
        // check protocol fee receiver balance
        assertEq(
            (finalProtocolFeeReceiverBalance -
                initialProtocolFeeReceiverBalance),
            0
        );
        // Check the claims
        BoostLib.Boost memory boost = boostCore.getBoost(0);
        ERC20Incentive _incentive = ERC20Incentive(
            address(boost.incentives[0])
        );
        assertEq(_incentive.claims(), 1);
    }

Mitigation
Set a maximum value for BoostCore::referralFee and refactor BoostCore::createBoost as shown below.

Link to Minimal Reproducible Example (StackBlitz, CodeSandbox, GitHub repo etc.)

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

Anything else?

No response

@Quazia Quazia added the bug Something isn't working label Sep 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant