xanoutas/solidity-security-findings huggingface dataset:
Founder count can be incorrect if there are more than 255 founders
Audit: 2022-09-nouns-builder-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2022-09-nouns-builder/blob/main/src/token/types/TokenTypesV1.sol#L16-L22
https://github.com/code-423n4/2022-09-nouns-builder/blob/main/src/token/Token.sol#L71-L126
https://github.com/code-423n4/2022-09-nouns-builder/blob/main/src/token/Token.sol#L235-L237


# Vulnerability details

## Impact
In the following `TokenTypesV1.Settings` struct, `numFounders` is an `uint8`. Its maximum value is 255.

https://github.com/code-423n4/2022-09-nouns-builder/blob/main/src/token/types/TokenTypesV1.sol#L16-L22
```solidity
    struct Settings {
        address auction;
        uint96 totalSupply;
        IBaseMetadata metadataRenderer;
        uint8 numFounders;
        uint8 totalOwnership;
    }
```

When an organization is crowdfunded or is a collaboration of multiple groups, it is possible that the the organization has hundreds of founders. If the deployed DAO has more than 255 founders for which at most 100 of them have the percentages of token ownership specified, then calling the following `_addFounders` function would assign an unexpected value to `settings.numFounders`. Because of the executions of `uint256 numFounders = _founders.length` and `settings.numFounders = uint8(numFounders)` within the `unchecked` block, the conversion from `uint256` to `uint8` occurs, and `settings.numFounders` could be overflowed to 0 when `numFounders` is 256. Therefore, calling the `totalFounders` function below would return an incorrect number of founders when there are more than 255 of them.

https://github.com/code-423n4/2022-09-nouns-builder/blob/main/src/token/Token.sol#L71-L126
```solidity
    function _addFounders(IManager.FounderParams[] calldata _founders) internal {
        // Cache the number of founders
        uint256 numFounders = _founders.length;

        // Used to store the total percent ownership among the founders
        uint256 totalOwnership;

        unchecked {
            // For each founder:
            for (uint256 i; i < numFounders; ++i) {
                // Cache the percent ownership
                uint256 founderPct = _founders[i].ownershipPct;

                // Continue if no ownership is specified
                if (founderPct == 0) continue;

                // Update the total ownership and ensure it's valid
                if ((totalOwnership += uint8(founderPct)) > 100) revert INVALID_FOUNDER_OWNERSHIP();

                // Compute the founder's id
                uint256 founderId = settings.numFounders++;

                // Get the pointer to store the founder
                Founder storage newFounder = founder[founderId];

                // Store the founder's vesting details
                newFounder.wallet = _founders[i].wallet;
                newFounder.vestExpiry = uint32(_founders[i].vestExpiry);
                newFounder.ownershipPct = uint8(founderPct);

                // Compute the vesting schedule
                uint256 schedule = 100 / founderPct;
User can lose his governance power
Audit: 2022-09-nouns-builder-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2022-09-nouns-builder/blob/debe9b792cc70510eadf9b3728cde5b0f2ec9a1f/src/lib/token/ERC721Votes.sol#L144


# Vulnerability details

### Proof of concept

If a user calls the `delegateBySig()` function with the zero address (for example unintentionally) as the value of the `_to` argument then the new delegate of the `_from` address will become the zero address, effectively burning his vote. Ideally if the `_to` argument has a value of the zero address it is best to be set as the `_from` address, so the user keeps his vote instead of burning it.

### Impact

This vulnerability can result in undesired loss of governance power for a user.

### Recommendation

On the first line of `delegateBySig` add the following code:
```jsx
if (_to == address(0)) {
		_to = _from;
}
```
State function does not require majority of votes for supporting and passing a proposal
Audit: 2022-09-nouns-builder-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2022-09-nouns-builder/blob/main/src/governance/governor/Governor.sol#L413-L456


# Vulnerability details

## Impact
When determining the proposal's state, the following `state` function is called, which can execute `else if (proposal.forVotes < proposal.againstVotes || proposal.forVotes < proposal.quorumVotes) { return ProposalState.Defeated; }`. If `proposal.forVotes` and `proposal.againstVotes` are the same, the proposal is not considered defeated when the quorum votes are reached by the for votes. However, many electoral systems require that the for votes to be more than the against votes in order to conclude that the proposal is passed because the majority of votes supports it. If the deployed DAO wants to require the majority of votes to support a proposal in order to pass it, the `state` function would incorrectly conclude that the proposal is not defeated when the for votes and against votes are the same at the end of voting. As a result, critical proposals, such as for updating implementations or withdrawing funds from the treasury, that should not be passed can be passed, or vice versa, so the impact can be huge.

https://github.com/code-423n4/2022-09-nouns-builder/blob/main/src/governance/governor/Governor.sol#L413-L456
```solidity
    function state(bytes32 _proposalId) public view returns (ProposalState) {
        // Get a copy of the proposal
        Proposal memory proposal = proposals[_proposalId];

        // Ensure the proposal exists
        if (proposal.voteStart == 0) revert PROPOSAL_DOES_NOT_EXIST();

        // If the proposal was executed:
        if (proposal.executed) {
            return ProposalState.Executed;

            // Else if the proposal was canceled:
        } else if (proposal.canceled) {
            return ProposalState.Canceled;

            // Else if the proposal was vetoed:
        } else if (proposal.vetoed) {
            return ProposalState.Vetoed;

            // Else if voting has not started:
        } else if (block.timestamp < proposal.voteStart) {
            return ProposalState.Pending;

            // Else if voting has not ended:
        } else if (block.timestamp < proposal.voteEnd) {
            return ProposalState.Active;

            // Else if the proposal failed (outvoted OR didn't reach quorum):
        } else if (proposal.forVotes < proposal.againstVotes || proposal.forVotes < proposal.quorumVotes) {
            return ProposalState.Defeated;

            // Else if the proposal has not been queued:
        } else if (settings.treasury.timestamp(_proposalId) == 0) {
            return ProposalState.Succeeded;

            // Else if the proposal can no longer be executed:
        } else if (settings.treasury.isExpired(_proposalId)) {
            return ProposalState.Expired;

            // Else the proposal is queued
        } else {
            return ProposalState.Queued;
        }
    }
```

## Proof of Concept
Please append the fol
Vulnerability in callContract Function Due to Misuse of tx.origin as refundAddress in payNativeGasForContractCall
Audit: 2024-08-axelar-network-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2024-08-axelar-network/blob/4572617124bed39add9025317d2c326acfef29f1/interchain-token-service/contracts/utils/GatewayCaller.sol#L51
https://github.com/code-423n4/2024-08-axelar-network/blob/4572617124bed39add9025317d2c326acfef29f1/interchain-token-service/contracts/utils/GatewayCaller.sol#L61
https://github.com/code-423n4/2024-08-axelar-network/blob/4572617124bed39add9025317d2c326acfef29f1/interchain-token-service/contracts/utils/GatewayCaller.sol#L101
https://github.com/code-423n4/2024-08-axelar-network/blob/4572617124bed39add9025317d2c326acfef29f1/interchain-token-service/contracts/utils/GatewayCaller.sol#L113


# Vulnerability details

cription
A significant security flaw within the `callContract` function where the tx.origin is erroneously utilized as the refundAddress when invoking the `payNativeGasForContractCall` function. This improper use of `tx.origin` introduces a substantial risk of exploitation through phishing, reentrancy, and other malicious activities. The issue arises because tx.origin, representing the original external account that initiated the transaction, is inappropriately assigned to the refundAddress parameter, which governs the destination for gas refunds. 

This spans across so many Gas service providers [1](https://github.com/code-423n4/2024-08-axelar-network/blob/4572617124bed39add9025317d2c326acfef29f1/interchain-token-service/contracts/utils/GatewayCaller.sol#L51), [2](https://github.com/code-423n4/2024-08-axelar-network/blob/4572617124bed39add9025317d2c326acfef29f1/interchain-token-service/contracts/utils/GatewayCaller.sol#L61), [3](https://github.com/code-423n4/2024-08-axelar-network/blob/4572617124bed39add9025317d2c326acfef29f1/interchain-token-service/contracts/utils/GatewayCaller.sol#L101) and [4](https://github.com/code-423n4/2024-08-axelar-network/blob/4572617124bed39add9025317d2c326acfef29f1/interchain-token-service/contracts/utils/GatewayCaller.sol#L113) 


## Proof of Concept
```solidity
function callContract(
    string calldata destinationChain,
    string calldata destinationAddress,
    bytes calldata payload,
    MetadataVersion metadataVersion,
    uint256 gasValue
) external payable override {
    if (gasValue > 0) {
        if (metadataVersion == MetadataVersion.CONTRACT_CALL) {
            // slither-disable-next-line arbitrary-send-eth
            gasService.payNativeGasForContractCall{ value: gasValue }(
                address(this),
                destinationChain,
                destinationAddress,
                payload,
                // solhint-disable-next-line avoid-tx-origin
                tx.origin  <-----------------
            );
        } else if (metadataVersion == MetadataVersion.EXPRESS_CALL) {
            // slither-disable-next-line arbitrary-send-eth
            gasService.payNativeGasForExpressCall{ value: gasValue }(
                address(this),
                destinationChain,
                destinationAddress,
Not all ERC20 tokens have symbol defined as a string data type
Audit: 2024-08-axelar-network-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2024-08-axelar-network/blob/main/interchain-token-service/contracts/InterchainTokenFactory.sol#L199
https://github.com/code-423n4/2024-08-axelar-network/blob/main/interchain-token-service/contracts/InterchainTokenFactory.sol#L290
https://github.com/code-423n4/2024-08-axelar-network/blob/main/interchain-token-service/contracts/InterchainTokenFactory.sol#L317
https://github.com/code-423n4/2024-08-axelar-network/blob/main/interchain-token-service/contracts/TokenHandler.sol#L113


# Vulnerability details

## Impact
The Axelar description states: "ERC20 used by the protocol: Any (all possible ERC20s)". The InterchainTokenFactory.sol and TokenHandler.sol contracts use the symbol parameter reading via the symbol() command. The symbol parameter is of type string:

https://github.com/code-423n4/2024-08-axelar-network/blob/main/interchain-token-service/contracts/InterchainTokenFactory.sol#L199
https://github.com/code-423n4/2024-08-axelar-network/blob/main/interchain-token-service/contracts/InterchainTokenFactory.sol #L290
https://github.com/code-423n4/2024-08-axelar-network/blob/main/interchain-token-service/contracts/InterchainTokenFactory.sol#L317
https://github.com/code-423n4/2024-08-axelar-network/blob/main/interchain-token-service/contracts/TokenHandler.sol#L113

However, not all tokens are of type metadata string.

## Proof of Concept
https://github.com/d-xo/weird-erc20?tab=readme-ov-file#non-string-metadata

## Tools Used
Manual review

## Recommended Mitigation Steps
Please note that not all tokens have a metadata string.


## Assessed type

ERC20
TokenHandler:transferTokenFrom doesn't ensure msg.value is equal to the desired amount in case of tokenIds of native tokens
Audit: 2024-08-axelar-network-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2024-08-axelar-network/blob/4572617124bed39add9025317d2c326acfef29f1/interchain-token-service/contracts/InterchainTokenService.sol#L405


# Vulnerability details

## Description
In case a user wants to transfer native tokens across chains, the expressExecute function at the InterchainTokenService contract is payable and attempts to call TokenHandler's transferTokenFrom function. 
The logic, however, has some oversights:
The first one is the msg.value of the payable call. If a user wants to send some native tokens at the express execution, there should be sanity checks ensuring the payload-encoded amount corresponds to the msg.value. This doesn't happen at the `expressExecute` or at the `_expressExecute` implementations.

The second oversight is at the delegate call to  TokenHandler's transferTokenFrom function:
the `_expressExecute` function decodes the amount but never checks if the tokenId's corresponding token address is zero and doesn't check if the amount is equal to the msg.value:
```solidity
function _expressExecute(bytes32 commandId, string calldata sourceChain, bytes calldata payload) internal {
        (, bytes32 tokenId, bytes memory sourceAddress, bytes memory destinationAddressBytes, uint256 amount, bytes memory data) = abi
            .decode(payload, (uint256, bytes32, bytes, bytes, uint256, bytes));
       ...
            (bool success, bytes memory returnData) = tokenHandler.delegatecall(
                abi.encodeWithSelector(ITokenHandler.transferTokenFrom.selector, tokenId, msg.sender, destinationAddress, amount)
            );
    ...
}
```
## Impact
Malicious users may attempt to do native transfers with amounts set on the payload without sending any msg.value in order to spend the available InterchainTokenService native funds.
Legitimate users that want to help the protocol work by doing express executions may set amounts lower than the msg.value and not receive any sort of refund.

## Tools Used
Manual review
## Recommended Mitigation Steps
Make sure the amount variable decoded at the payload is sanity checked in case the tokenId's corresponding token address is zero.
Make sure not to allow users to send a msg.value different than this amount.


## Assessed type

Context
Calling core state functionalities would fail since they've been restricted to the testing scope
Audit: 2024-08-axelar-network-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2024-08-axelar-network/blob/69c4f2c3fcefb1b8eb2129af9c3685a44ae5b6fe/axelar-amplifier/interchain-token-service/src/contract/query.rs#L12-L17


# Vulnerability details


### Impact

DOS to an entry point to the ITS Hub, considering the attempt reverts when querying a test code in live production.

Now would be key to note that this report only focuses on _querying_ the trusted addresses, however this same bug case is applicable to all other functions under the first test scope that's been implemented in across the ITS, as they all would revert and are being used in core areas across scope raising the impact/severity of the finding.

Below are search commands to pinpoint areas where these functionalities are implemented across scope:

- https://github.com/search?q=repo%3Acode-423n4%2F2024-08-axelar-network+start_token_balance+language%3ARust&type=code
- https://github.com/search?q=repo%3Acode-423n4%2F2024-08-axelar-network+update_token_balance+language%3ARust&type=code
- https://github.com/search?q=repo%3Acode-423n4%2F2024-08-axelar-network+may_load_token_balance+language%3ARust&type=code

Evidently these three are heavily used in [execute.rs](https://github.com/code-423n4/2024-08-axelar-network/blob/4572617124bed39add9025317d2c326acfef29f1/axelar-amplifier/interchain-token-service/src/contract/execute.rs#L428) with the first even causing a revert during [deployments of new interchain tokens](https://github.com/code-423n4/2024-08-axelar-network/blob/4572617124bed39add9025317d2c326acfef29f1/axelar-amplifier/interchain-token-service/src/contract/execute.rs#L135).

### Proof of Concept

Take a look at https://github.com/code-423n4/2024-08-axelar-network/blob/69c4f2c3fcefb1b8eb2129af9c3685a44ae5b6fe/axelar-amplifier/interchain-token-service/src/contract/query.rs#L12-L17

```rust
pub fn all_trusted_addresses(deps: Deps) -> Result<Binary, state::Error> {
    let addresses = state::load_all_trusted_addresses(deps.storage)?
        .into_iter()
        .collect();
    to_json_binary(&AllTrustedAddressesResponse { addresses }).map_err(state::Error::from)
}
```

This function is used to query the trusted addresses in the ITS, it's been externally called via https://github.com/code-423n4/2024-08-axelar-network/blob/69c4f2c3fcefb1b8eb2129af9c3685a44ae5b6fe/axelar-amplifier/interchain-token-service/src/contract.rs#L112-L124

```rust
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(
    deps: Deps,
    _: Env,
    msg: QueryMsg,
) -> Result<Binary, axelar_wasm_std::error::ContractError> {
    match msg {
        QueryMsg::TrustedAddress { chain } => query::trusted_address(deps, chain)?,
        QueryMsg::AllTrustedAddresses {} => query::all_trusted_addresses(deps)?,
        QueryMsg::TokenBalance { chain, token_id } => query::token_balance(deps, chain, token_id)?,
    }
    .then(Ok)
}
```

Issue however is that in the [ITS `state.rs`](https://github.com/code-423n4/2024-08-axelar-network/blob/69c4f2c3
Lack of ETH Validation in InterchainTokenFactory
Audit: 2024-08-axelar-network-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2024-08-axelar-network/blob/4572617124bed39add9025317d2c326acfef29f1/interchain-token-service/contracts/InterchainTokenFactory.sol#L127-L134


# Vulnerability details

## Impact
The ``deployInterchainToken`` function in the ``InterchainTokenFactory`` contract is marked as ``payable`` but lacks any validation or handling of the ``msg.value``. This can lead to ETH being permanently trapped in the contract, resulting in financial losses for users and potential contract bloat.
The deployInterchainToken function is defined as payable but does not use or check the msg.value. This allows users to send ETH along with their token deployment transaction, but the ETH is not used or accounted for in any way. 
```solidity
function deployInterchainToken(
    bytes32 salt,
    string calldata name,
    string calldata symbol,
    uint8 decimals,
    uint256 initialSupply,
    address minter
) external payable returns (bytes32 tokenId) {
   
    // No check or use of msg.value
}
```
## Proof of Concept
https://github.com/code-423n4/2024-08-axelar-network/blob/4572617124bed39add9025317d2c326acfef29f1/interchain-token-service/contracts/InterchainTokenFactory.sol#L127-L134
```solidity
contract TestToken {
    InterchainTokenFactory public factory;

    constructor(address _factory) {
        factory = InterchainTokenFactory(_factory);
    }

    function TestDeploy() external payable {
        // Deploy a token while sending 1 ETH
        factory.deployInterchainToken{value: 1 ether}(
            bytes32(0),
            "Test Token",
            "TEST",
            18,
            1000000,
            address(this)
        );
        // The 1 ETH is now trapped in the factory contract
    }
}
```

## Tools Used
manual review
## Recommended Mitigation Steps
If ETH is not intended to be used in this function, add a check to reject any ETH sent.
```solidity
    require(msg.value == 0, "ETH not accepted for token deployment");
```
Otherwise implement a withdrawal function for any trapped ETH



## Assessed type

ETH-Transfer
Inconsistent balance tracking allows unlimited token minting
Audit: 2024-08-axelar-network-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2024-08-axelar-network/blob/4572617124bed39add9025317d2c326acfef29f1/axelar-amplifier/interchain-token-service/src/state.rs#L192
https://github.com/code-423n4/2024-08-axelar-network/blob/4572617124bed39add9025317d2c326acfef29f1/axelar-amplifier/interchain-token-service/src/contract/execute.rs#L62


# Vulnerability details

## Impact
The current design allows for inconsistent balance tracking between chains, potentially leading to unlimited token minting on the destination chain. This occurs when a token is untracked on the source chain but tracked on the destination chain.

The issue arises from the following behavior:

- The `state::update_token_balance` function silently ignores balance updates for untracked tokens. 
- The `execute::execute_message` function does not verify if the token is tracked on both the source and destination chains before processing a transfer.

This vulnerability could be exploited to inflate the token supply on the destination chain, potentially leading to economic attacks and undermining the integrity of the cross-chain token system.


## Proof of Concept
Add the following POC to execute.rs. I have shown that you do the same transfer twice to double the balance on the destination chain.

```rust
fn test_untracked_balance_inconsistency() {
        let mut deps = setup();
    
        let source_chain: ChainName = "source-chain".parse().unwrap();
        let destination_chain: ChainName = "destination-chain".parse().unwrap();
        let source_address: Address = "trusted-source".parse().unwrap();
        let destination_address: Address = "trusted-destination".parse().unwrap();
    
        register_trusted_address(&mut deps.as_mut(), source_chain.as_ref(), &source_address);
        register_trusted_address(
            &mut deps.as_mut(),
            destination_chain.as_ref(),
            &destination_address,
        );
    
        let token_id = TokenId::new([1u8; 32]);
        let amount = Uint256::from(1000u128);
    
        // Initialize token as untracked on source chain 
        state::start_token_balance(
            deps.as_mut().storage,
            token_id.clone(),
            source_chain.clone(),
            false, // untracked
        )
        .unwrap();

        // Initialize token as tracked on destination chain
        state::start_token_balance(
            deps.as_mut().storage,
            token_id.clone(),
            destination_chain.clone(),
            true, // tracked
        )
        .unwrap();
    
        // Perform an interchain transfer
        let transfer_message = ItsMessage::InterchainTransfer {
            token_id: token_id.clone(),
            source_address: HexBinary::from_hex("1234").unwrap(),
            destination_address: HexBinary::from_hex("5678").unwrap(),
            amount,
            data: HexBinary::from_hex("abcd").unwrap(),
        };
        
        let its_hub_message = ItsHubMessage::SendToHub {