Skip to content
This repository has been archived by the owner on Jul 21, 2024. It is now read-only.

0xGreyWolf - CouncilMembers::_retrieve() loops over an array of balances to stream individualBalance and as the array size (council members) grow, gas cost expands until it becomes unusable. #162

Closed
sherlock-admin opened this issue Jan 15, 2024 · 1 comment
Labels
Excluded Excluded by the judge without consulting the protocol or the senior Non-Reward This issue will not receive a payout

Comments

@sherlock-admin
Copy link
Contributor

sherlock-admin commented Jan 15, 2024

0xGreyWolf

high

CouncilMembers::_retrieve() loops over an array of balances to stream individualBalance and as the array size (council members) grow, gas cost expands until it becomes unusable.

Summary

  • An internal function CouncilMembers::_retrieve() loops over an array balances then adds individualBalance on every element. Every element represents nft token holders / Council Members so it is expected to increase over time. As it happens, the gas cost increases until it becomes unusable either by impracticality or until it reaches the block gas limit.

  • The CouncilMembers::_retrieve() is also used in multiple occasions as listed in Vulnerability Detail.

  • Here's a quick look of the code.

        /**
        * @notice Retrieve and distribute TELCOIN to council members based on the stream from _target
        * @dev This function fetches the maximum possible TELCOIN and distributes it equally among all council members.
        * @dev It also updates the running balance to ensure accurate distribution during subsequent calls.
        */
        function _retrieve() internal {
        ...
    
            // Add the individual balance to each council member's balance
            for (uint i = 0; i < balances.length; i++) {
                balances[i] += individualBalance;
            }
        }

Vulnerability Detail

  • As the council members increase, the array size increases because that is where the tokenId is stored. As it happens the gas cost increases until the time it is unusable either by impracticality or until it reaches the block gas limit.

  • This internal function is "also" used in multiple functions. It is expected that the adverse effect will spread across them too.

    • CouncilMembers::retrieve()
    • CouncilMembers::claim()
    • CouncilMembers::removeFromOffice()
    • CouncilMembers::mint()
    • CouncilMembers::burn()
    • CouncilMembers::_update()

Impact

  • As council members become too large, functions listed above will never be executed.
  • The contract will reach an unusable state.

Code Snippet

Tool used

Manual Review

Recommendation

Use mapping to track balances per tokenId then implement the code around it.

--    uint256[] public balances;
++    mapping (uint256 tokenId => uint256 balance) balances;
@github-actions github-actions bot added Has Duplicates A valid issue with 1+ other issues describing the same vulnerability Excluded Excluded by the judge without consulting the protocol or the senior labels Jan 19, 2024
@sherlock-admin2 sherlock-admin2 changed the title Old Fossilized Stallion - CouncilMembers::_retrieve() loops over an array of balances to stream individualBalance and as the array size (council members) grow, gas cost expands until it becomes unusable. 0xGreyWolf - CouncilMembers::_retrieve() loops over an array of balances to stream individualBalance and as the array size (council members) grow, gas cost expands until it becomes unusable. Jan 29, 2024
@sherlock-admin2 sherlock-admin2 added Non-Reward This issue will not receive a payout and removed Has Duplicates A valid issue with 1+ other issues describing the same vulnerability labels Jan 29, 2024
@nevillehuang
Copy link
Collaborator

Invalid, it is extremely if not impossible that an OOG will occur given council members will not reach that kind of lengths, since it is admin approved

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Excluded Excluded by the judge without consulting the protocol or the senior Non-Reward This issue will not receive a payout
Projects
None yet
Development

No branches or pull requests

3 participants