# The governance will fail to add an ecosystem token if someone creates a hToken that uses that ecosystem token

Anyone can register an ecosystem token as an hToken underlying, populating getLocalTokenFromUnderlying and causing addEcosystemToken() to revert, blocking governance.

- Payout: Contest reward
- Severity: medium
- Program: Maia DAO
- Credited: Arz
- Disclosed: 2023-11-29
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-09-maia-findings/issues/881
- Library page: https://bugbountylibrary.com/r/c4%3A2023-09-maia%3AM-01
- Tags: domain:web3 impact:dos kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:access-control vuln:business-logic vuln:dos

**Target:** RootPort.addEcosystemToken / setAddresses mapping
**Root cause:** setAddresses() writes getLocalTokenFromUnderlying[_underlyingAddress][_srcChainId] for any user-created hToken, and addEcosystemToken() reverts if that mapping is non-zero for the ecosystem token, conflating an unrelated hToken's underlying with the ecosystem token registration.
**Steps:**
1. Attacker calls `arbitrumCoreRouter.addLocalToken{value: 0.0005 ether}(address(arbitrumMockToken), GasParams(0.5 ether, 0.5 ether))` where arbitrumMockToken is the future ecosystem token.
2. setAddresses() sets `getLocalTokenFromUnderlying[arbitrumMockToken][rootChainId] = newArbitrumAssetGlobalAddress`.
3. Admin later calls `rootPort.addEcosystemToken(address(arbitrumMockToken))`.
4. Check `getLocalTokenFromUnderlying[_ecoTokenGlobalAddress][localChainId] != address(0)` is true, reverting with AlreadyAddedEcosystemToken().
**How found:** Code reading of setAddresses() mapping write and the redundant check in addEcosystemToken(); noticed the same mapping key is shared between user-created hTokens and ecosystem token registration.
**Exploitation:** Attacker front-runs governance by registering the not-yet-added ecosystem token as the underlying of a new hToken via addLocalToken, permanently blocking addEcosystemToken() unless governance redeploys or overrides.
**Insight:** When a single mapping is written by both permissionless user actions and privileged admin registration, check whether an attacker can pre-populate the admin's key to make privileged setup revert; look for shared keys between user-controlled and governance-controlled state.
