Skip to content
$1,000,000 in security audit grants are live now, Apply here →

Security review · December 2025

Airdrop Updates

for Magna

Guardian's review of Airdrop Updates for Magna, published December 2025. The report records 2 findings, including 1 low and 1 informational.

Published
Review window
December 22 to 23, 2025
Language
Solidity
Chains
Ethereum, Base, Optimism, Polygon, Arbitrum, BNB Chain
Sector
Infrastructure
  • 0 Critical
  • 0 High
  • 0 Medium
  • 1 Low
  • 1 Informational

2 acknowledged

Scope

Findings 2

  1. L-01 Low Unbounded Per-allocation Claim Fees Validation Acknowledged
    Location
    MerkleVester.sol

    Description

    The claim fee is now stored inside each allocation leaf and used directly during withdrawals without any on-chain maximum. The allocation struct includes a claimFee field and the withdrawal flow uses that value to compute the required ETH, so the contract will enforce whatever fee is encoded in the merkle tree. This removes the previous on-chain guardrail and shifts correctness to off-chain tooling and UI expectations, because the contract only compares claimFee against msg.value and does not validate bounds.

    struct Allocation {
        string id;
        address originalBeneficiary;
        uint256 totalAllocation;
        bool cancelable;
        bool revokable;
        bool transferableByAdmin;
        bool transferableByBeneficiary;
        uint256 claimFee;
        bytes extraData;
    }
    
    modifier checkFee(string memory allocationId, uint256 claimFee) {
        uint256 expectedFee = getClaimFee(allocationId, claimFee);
        if (expectedFee > 0) {
            transientFeeIncurred += expectedFee;
            require(transientFeeReceived >= transientFeeIncurred, TooSmallFeeAmountSent());
        }
        _;
    }
    
    function getClaimFee(string memory allocationId, uint256 claimFee) public view returns (uint256) {
        if (shouldPayClaimFeeOnlyOnce && feeAlreadyPayed[allocationId]) {
            return 0;
        } else {
            return claimFee;
        }
    }
    

    Impact: Users can be economically blocked from claiming if fees are set unreasonably high and the contract provides no on-chain protection against excessive fees.

    Recommendation

    Consider introducing an on-chain guardrail by enforcing a maximum fee, either as an absolute cap or as a percentage of the allocation size, and validate claimFee against it during withdrawal or merkle root acceptance. If the design intentionally relies on off-chain checks, add explicit governance approval for fee changes and ensure the UI and tooling reject out-of-policy claimFee values before roots are published.

  2. I-02 Informational getClaimFee Can't Quote Fee From allocationId Informational Acknowledged
    Location
    MerkleVester.sol

    Description

    The getClaimFee function now requires the caller to provide a claimFee value as an input parameter. As a result, the function can no longer be used to derive the claim fee for a given allocationId by itself. This removes the ability for integrators or users to query the correct claim fee directly from the contract.

    Recommendation

    Consider adding a view function that derives and returns the correct claim fee for a given allocationId, allowing callers to query the expected fee without prior knowledge.

More from Magna

All 9 reports
  1. Staking Updates

    23 findings 23 findings: 3 low, 20 informational
  2. Direct Transfer

    9 findings 9 findings: 1 medium, 1 low, 7 informational
  3. Merkle Vester

    13 findings 13 findings: 1 medium, 6 low, 6 informational
  4. Fixed and Dynamic Staking

    21 findings1 high 21 findings: 1 high, 3 medium, 17 low

Put your code through the same review.

This review started with a conversation about scope. Tell us what you are building and we will plan yours with you.

Get a quote