MEDIUM severity: FundraiserFacet logic does not consider contract upgrades which can increase token decimals. **Description:** The fundraiser logic in `FundraiserFacet` assumes that the decimals of the token being raised will remain with the same number of decimals from when a fundraiser is created to when it is funded. In the case of USDC, a contract upgrade that increases the number of decimals would...

Vulnerable code:
// FundraiserFacet.sol
    function createFundraiser(
        address payee,
        address token,
        uint256 amount
    ) external payable {
        LibDiamond.enforceIsOwnerOrContract();

        // The {FundraiserFacet} was initially created to support USDC, which has the
        // same number of decimals as Bean (6). Fundraisers created with tokens measured
        // to a different number of decimals are not yet supported.
        if (ERC20(token).decimals() != 6) {
            revert("Fundraiser: Token decimals");
        }

        uint32 id = s.fundraiserIndex;
        s.fundraisers[id].token = token;
        s.fundraisers[id].remaining = amount;
        s.fundraisers[id].total = amount;
        s.fundraisers[id].payee = payee;
        s.fundraisers[id].start = block.timestamp;
+       s.fundraisers[id].savedDecimals = 6;
        s.fundraiserIndex = id + 1;

        // Mint Beans to pay for the Fundraiser. During {fund}, 1 Bean is burned
        // for each `token` provided to the Fundraiser.
        // Adjust `amount` based on `token` decimals to support tokens with different decimals.
        C.bean().mint(address(this), amount);

        emit CreateFundraiser(id, payee, token, amount);
    }

    function fund(
        uint32 id,
        uint256 amount,
        LibTransfer.From mode
    ) external payable nonReentrant returns (uint256) {
        uint256 remaining = s.fundraisers[id].remaining;

        // Check amount remaining and constrain
        require(remaining > 0, "Fundraiser: completed");
        if (amount > remaining) {
            amount = remaining;
        }
+
+       require(s.fundraisers[id].token.decimals() == s.fundraisers[id].savedDecimals, "Fundraiser token decimals not synchronized.");
+
        // Transfer tokens from msg.sender -> Beanstalk
        amount = LibTransfer.receiveToken(
            IERC20(s.fundraisers[id].token),
            amount,
            msg.sender,
            mode
        );
        s.fundraisers[id].remaining = remaining - amount; // Note: SafeMath is redundant here.
        emit FundFundraiser(msg.sender, id, amount);

        // If completed, transfer tokens to payee and emit an event
        if (s.fundraisers[id].remaining == 0) {
            _completeFundraiser(id);
        }

        // When the Fundraiser was initialized, Beanstalk minted Beans.
        C.bean().burn(amount);

        // Calculate the number of Pods to Sow.
        // Fundraisers bypass Morning Auction behavior and Soil requirements,
        // calculating return only based on the current `s.w.t`.
        uint256 pods = LibDibbler.beansToPods(
            amount,
            uint256(s.w.t).mul(LibDibbler.TEMPERATURE_PRECISION)
        );

        // Sow for Pods and return the number of Pods received.
        return LibDibbler.sowNoSoil(msg.sender, amount, pods);
    }
+
+   function synchronizeFundraiserDecimals(uint32 id) public {
+       uint32 currentTokenDecimals = s.fundraisers[id].token.decimals();
+       uint32 savedDecimals = s.fundraisers[id].savedDecimals;
+       require(currentTokenDecimals != savedDecimals, "Fundraiser token decimals already synchronized");
+       if (currentTokenDecimals > savedDecimals) {
+           uint32 decimalDifference = currentTokenDecimals - savedDecimals;
+           s.fundraisers[id].total = s.fundraisers[id].total * decimalDifference;
+           s.fundraisers[id].remaining = s.fundraisers[id].remaining * decimalDifference;
+       } else {
+           uint32 decimalDifference = savedDecimals - currentTokenDecimals;
+           s.fundraisers[id].total = s.fundraisers[id].total / decimalDifference;
+           s.fundraisers[id].remaining = s.fundraisers[id].remaining / decimalDifference;
+       }
+   }

    // AppStorage.sol
    struct Fundraiser {
        address payee;
        address token;
        uint256 total;
        uint256 remaining;
        uint256 start;
+       uint256 savedDecimals;
    }