59844 sc insight incorrect and misleading events when adding levels in stargatenft
Submitted on Nov 16th 2025 at 10:44:17 UTC by @blackgrease for Audit Comp | Vechain | Stargate Hayabusa
Report ID: #59844
Report Type: Smart Contract
Report severity: Insight
Target: https://github.com/immunefi-team/audit-comp-vechain-stargate-hayabusa/tree/main/packages/contracts/contracts/StargateNFT/libraries/Levels.sol
Description
Affected Files: StargateNFT.sol and Levels
The StargateNFT inherits the Levels library allowing levels to be added into the contract by an address with the LEVEL_OPERATOR_ROLE privilege (set by protocol). However, when adding a level the addLevel function emits incorrect/misleading events. Specifically, the function emits:
LevelUpdated: misleading and incorrect because this is an addition operation and not updating an existing level.LevelCirculatingSupplyUpdated: misleading and incorrect because this is an addition operation (not an update). Also theoldCirculatingSupplyvalue is 0 which isn't useful.LevelCapUpdated: again, not an updating operation; theoldCapparameter is meaningless.
A stack trace of the emitted events:
│ │ │ ├─ emit LevelUpdated(levelId: 4, name: "Thunder Boosted", isX: false, maturityBlocks: 7200, scaledRewardFactor: 1, vetAmountRequiredToStake: 500000000000000000000 [5e20])
│ │ │ ├─ emit LevelCirculatingSupplyUpdated(levelId: 4, oldCirculatingSupply: 0, newCirculatingSupply: 0)
│ │ │ ├─ emit LevelCapUpdated(levelId: 4, oldCap: 0, newCap: 1000000000 [1e9])These events are emitted by Levels::updateLevel. Note: in version 3 of StargateNFT the updateLevel function is no longer exposed. Documentation confirms removal of setters: StargateNFT#L92 "Removed setters to optimize contract size: setStargateDelegation, setLegacyNodes, updateLevelCap, updateLevel".
The addLevel function should emit its own unique event that accurately represents the addition operation and contains meaningful data.
The Associated Code
StargateNFT wrapper:
Levels library (relevant extract):
Impact
This is classified as an Insight under "Code Optimizations and Enhancements". Incorrect or misleading event emission can confuse indexers, analytics services, and anyone relying on on-chain events to understand protocol state changes. The semantics of "add" differ from "update" and should be represented distinctly.
Mitigation
Create and emit a new event that accurately represents level addition. Suggested event:
Change Levels::addLevel to emit the new event instead of the three misleading events. Example patch:
This preserves accurate semantics and removes confusing old* fields that are meaningless for additions.
Link to Proof of Concept
https://gist.github.com/blackgrease/e056f70903d89aea4fe1ddda4461a862
Proof of Concept
A runnable Foundry PoC is provided in the private gist at the link above. Run:
forge test --mt testAddLevelInccorectEventEmitted -C ./packages/contracts -vvvv
PoC Description
Add a level to the contract using the LEVEL_OPERATOR_ROLE.
Retrieve the emitted event logs.
Confirm the stored event logs match what is (incorrectly) expected to be emitted from the contract.
Hardhat conversion to Foundry
Start: clone the repository
git clone https://github.com/immunefi-team/audit-comp-vechain-stargate-hayabusa.git cd audit-comp-vechain-stargate-hayabusa/
Install dependencies:
forge install foundry-rs/forge-std
Install OpenZeppelin upgradeable contracts:
forge install OpenZeppelin/[email protected]
Install OpenZeppelin contracts (used in test):
forge install OpenZeppelin/[email protected]
Compile and run the PoC:
forge compile ./packages/contracts/ (warnings can be ignored)
forge test --mt testAddLevelInccorectEventEmitted -C ./packages/contracts -vvvv
If you want, I can:
produce a minimal patch (diff) that adds the NewLevelAdded event and replaces the three emits in
Levels::addLevel, oropen a suggested PR message and commit body consistent with the repo style.
Was this helpful?