`CoreRootRouter._setLocalToken` FUNCTION COULD OVERWRITE THE EXISTING VALUES OF THE `getLocalTokenFromGlobal` MAPPING VALUES DUE TO LACK OF CONDITIONAL CHECKS
Audit: 2023-09-maia-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2023-09-maia/blob/main/src/CoreRootRouter.sol#L481-L487
https://github.com/code-423n4/2023-09-maia/blob/main/src/RootPort.sol#L266-L267


# Vulnerability details

## Impact

The `CoreRootRouter._setLocalToken` function is used to set the local token on a specific chain for a global token. The function initially checks whether the local token is is already added as shown below:

        if (IPort(rootPortAddress).isLocalToken(_localAddress, _dstChainId)) revert TokenAlreadyAdded();

If the token is not already added then the `global token's new branch chain address` is set as shown below:

        IPort(rootPortAddress).setLocalAddress(_globalAddress, _localAddress, _dstChainId);

The `IPort.setLocalAddress` function performs two mapping state updates as shown below:

        getGlobalTokenFromLocal[_localAddress][_srcChainId] = _globalAddress;
        getLocalTokenFromGlobal[_globalAddress][_srcChainId] = _localAddress;

Now let's consider the following scenario:

1. Assume _globalAddress = 0x01, _localAddress = 0x02, _srcChainId = 1.
2. The `CoreRootRouter._setLocalToken` function is called with above input parameter values.
3. The `getGlobalTokenFromLocal[0x02][1]` is `equal to address(0)` since it is not initialized.
4. Hence the `IPort(rootPortAddress).isLocalToken(_localAddress, _dstChainId)` condition will return `false` and the `_setLocalToken` function will proceed executing.
5. But the `getLocalTokenFromGlobal[0x01][1]` has value `0x03` since it is already assigned during a previous call to the `CoreRootRouter._setLocalToken` function.
6. There is no check to verify whether `getLocalTokenFromGlobal[_globalAddress][_srcChainId]` is already set.
7. Hence the transaction execution will proceed to the `IPort.setLocalAddress` function and will update the `getGlobalTokenFromLocal` and `getLocalTokenFromGlobal` for the corresponding values provided.
8. This will overwrite the existing value of ``getLocalTokenFromGlobal[0x01][1]` which is `0x03` with the new passed in `_localAddress` value `0x02` as shown below:

        getLocalTokenFromGlobal[0x01][1] = 0x02;

But this is not the expected behaviour of the `IPort.setLocalAddress` function since above vulnerability could overwrite the `getLocalTokenFromGlobal` mapping values for already set `_globalAddress` and `_srcChainId` pairs. This can break the internal logic execution and accounting of the `hTokens` defined in the system.


## Proof of Concept

```solidity
    function _setLocalToken(address _globalAddress, address _localAddress, uint16 _dstChainId) internal {
        // Verify if the token already added
        if (IPort(rootPortAddress).isLocalToken(_localAddress, _dstChainId)) revert TokenAlreadyAdded();

        // Set the global token's new branch chain address
        IPort(rootPortAddress).setLocalAddress(_globalAddress, _localAddress, _dstChainId);
    }
```

https://github.com/code-423n4/2023-09-maia/blob/main/src/CoreRootRouter.sol#