xanoutas/solidity-security-findings huggingface dataset:
Smart wallet accounts will have issues when interacting with the ITS contract because of the use of tx.origin
Audit: 2024-08-axelar-network-findings
Severity: MEDIUM

# Lines of code

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


# Vulnerability details

## Impact

RefundAddress will be set incorrectly.

## Proof of Concept

A user will call `interchainTransfer()` in the InterchainTokenService contract  when initiating an interchain transfer to a destination chain. This function will eventually call `callContract()` in the gatewayCaller contract. 

> interchainTransfer() -> _takeToken -> _transmitInterchainTransfer() -> _callContract() -> gatewayCaller.delegatecall(IGatewayCaller.callContract.selector)


In InterchainTokenService.sol, when `_callContract()` is called, it uses a delegatecall to the gateway caller contract.

```
InterchainTokenService.sol
    function _callContract(
        string memory destinationChain,
        bytes memory payload,
        IGatewayCaller.MetadataVersion metadataVersion,
        uint256 gasValue
    ) internal {
        string memory destinationAddress;

        (destinationChain, destinationAddress, payload) = _getCallParams(destinationChain, payload);

>       (bool success, bytes memory returnData) = gatewayCaller.delegatecall(
            abi.encodeWithSelector(
                IGatewayCaller.callContract.selector,
                destinationChain,
                destinationAddress,
                payload,
                metadataVersion,
                gasValue
            )
        );

        if (!success) revert GatewayCallFailed(returnData);
    }
```
Since delegateCall is used, the `msg.sender` that calls the gateway contract is actually the caller of the `interchainTransfer()` function , and not the InterchainTokenService contract.

If the caller is a smart wallet, then the `msg.sender` is the `smart wallet`. In GatewayCaller.callContract, `tx.origin` is used for the refundAddress.

```
 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 the chains have 20 bytes addresses
Audit: 2024-08-axelar-network-findings
Severity: MEDIUM

# Lines of code

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


# Vulnerability details

## Impact

ITS contracts in the current implementation are used to transfer tokens between chains and also deploy remote interchain tokens and token managers for them. The problem is that the contract converts the address of the destination contract to Ethereum type address with 20 bytes and not all the chains have the same address size. This will lead to tx revert on some other chains and will make it impossible to implement remote transactions.


## Proof of Concept

Take a look at `_processInterchainTransferPayload()` functionality:

https://github.com/code-423n4/2024-08-axelar-network/blob/main/interchain-token-service/contracts/InterchainTokenService.sol#L733-739
```
{
            bytes memory destinationAddressBytes;
            (, tokenId, sourceAddress, destinationAddressBytes, amount, data) = abi.decode(
                payload,
                (uint256, bytes32, bytes, bytes, uint256, bytes)
            );
            destinationAddress = destinationAddressBytes.toAddress();
        }

```

It takes the payload and decodes `destinationAddressBytes` from it. Then it calls `toAddress()`:

https://github.com/code-423n4/2024-08-axelar-network/blob/main/axelar-gmp-sdk-solidity/contracts/libs/AddressBytes.sol#L17-23
```
 function toAddress(bytes memory bytesAddress) internal pure returns (address addr) {
        if (bytesAddress.length != 20) revert InvalidBytesLength(bytesAddress);

        assembly {
            addr := mload(add(bytesAddress, 20))
        }
    }

```

So if the address is not equal to the 20 bytes, the tx will revert. This will cause problems with implementation on Solana, for instance, where 32 bytes addresses are used:

https://solana.com/docs/core/accounts

## Tools Used

Manual review.

## Recommended Mitigation Steps

Handle the address conversion logic differently to ensure chain compatibility.


## Assessed type

Other
msg.value is decoupled from the gasValue parameter
Audit: 2024-08-axelar-network-findings
Severity: MEDIUM

# Lines of code

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


# Vulnerability details

## Description
The InterchainTokenFactory and InterchainTokenService contracts have a bridging payment logic on that decouples the msg.value from the desired payment amount.
Take a look at the deployRemoteInterchainToken function at the InterchainTokenFactory contract:
```solidity
function deployRemoteInterchainToken(
        string calldata originalChainName,
        bytes32 salt,
        address minter,
        string memory destinationChain,
        uint256 gasValue
    ) external payable returns (bytes32 tokenId) {
    ...
    tokenId = _deployInterchainToken(salt, destinationChain, tokenName, tokenSymbol, tokenDecimals, minter_, gasValue);
    }
```

It also happens at the deployTokenManager function at the InterchainTokenFactory contract:
```solidity
function deployTokenManager(
        bytes32 salt,
        string calldata destinationChain,
        TokenManagerType tokenManagerType,
        bytes calldata params,
        uint256 gasValue
    ) external payable whenNotPaused returns (bytes32 tokenId) {
    ...
    _deployRemoteTokenManager(tokenId, destinationChain, gasValue, tokenManagerType, params);
        }
    }
```
It doesn't sanity check msg.value, nor if it is worth at least the gasValue uint256.
## Impact
It is known the gateway will refund the excess payment made to bridge a message - if a user, however, sends a msg.value that is greater than gas value, he/she will not receive refunds for this difference.

Any native token left at the InterchainTokenService and at the InterchainTokenFactory contracts can be permissionless spent by any caller to pay for bridging a message. 
## Tools Used
Manual review
## Recommended Mitigation
Make sure to sanity check if the gasValue uint256 variable is equal to the msg.value, otherwise revert. This option would be optimal if maintaining the function's interface is crucial.
A second option would be to remove the gasValue parameter altogether from the function and utilize the native msg.value as the accounting mechanism.


## Assessed type

ETH-Transfer
TokenManager.sol has no way of handling rewards accrued by tokens that modify balance other than transfers.
Audit: 2024-08-axelar-network-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2024-08-axelar-network/blob/c383cc0e51805357bca8741ec5d1568cacbff6cc/interchain-token-service/contracts/TokenHandler.sol#L108-L111
https://github.com/code-423n4/2024-08-axelar-network/blob/c383cc0e51805357bca8741ec5d1568cacbff6cc/interchain-token-service/contracts/token-manager/TokenManager.sol#L1-L276


# Vulnerability details

### Impact

Rewards from these rebasing tokens will be lost forever. Also on blast, where tokens USDB and WETH have their rewards set automatically to claimable, the protocol has made no configurations to handle the reward collection, which could lead to loss of funds.

### Proof of Concept

For context, the provided readme information states that all tokens are to be used, including tokens with balance modifications.

> Balance changes outside of transfers	In scope


In the `takeToken` function in TokenHandler.sol, we can see that for `LOCK_UNLOCK` token types, the tokens are transferred to the token manager from the sender where they're "locked" until they're unlocked later when needed.

```solidity
        } else if (tokenManagerType == uint256(TokenManagerType.LOCK_UNLOCK)) {
            _transferTokenFrom(tokenAddress, from, tokenManager, amount);
        } else if (tokenManagerType == uint256(TokenManagerType.LOCK_UNLOCK_FEE)) {
            amount = _transferTokenFromWithFee(tokenAddress, from, tokenManager, amount);
```

Since it has been established that rebasing tokens and tokens with balance modifications can be in use, e.g stETH, these tokens when sent to the TokenManager will rabse, accruing rewards. Now, going through TokenMnaager.sol and TokenHandler.sol (or even ITS contracts), we can see that internal accounting is used to track amount transferred and amount received, meaning that the extra rebasing amounts will not be taken into consideration when dealing with these tokens. 

And if we look through TokenManager.sol, we'll see that there's no extra logic or sweep function to help recover any of these excess tokens, which as a result, will be lost.

Also, according to [axelarscan](https://axelarscan.io/resources/chains) which holds information about the chains on which the contracts will be deployed, blast is one of the chains supported, and blast provides yield mode. USDB and WETH on blast are have their yield modes set as automatic by default, so upon deployment to blast and transferring tokens to these tokens to the token manager, the accrued yield due to automatic rebasing is lost as they cannot be claimed. Also, due to the lack of configuration for blast, there's no way to change the yield mode of the tokens.

### Tools Used
Manual code review

### Recommended Mitigation Steps

Recommend implementing a balance tracking system, and potentially a receover token function that can skim off any excess tokens. Also on blast, consider add the ability to set native RebasingERC20 token status, following the [docs](https://docs.blast.io/building/guides/weth-yield).
refund address should not be hardcoded to tx.origin. 
Audit: 2024-08-axelar-network-findings
Severity: MEDIUM

# Lines of code

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


# Vulnerability details

## Impact
Hardcoding refund address to be the tx.origin may cause refunded amount to be lost in some cases 

## Bug Description 
`GasService` is the  smart contract that manages gas payments and refunds for cross-chain communication on the Axelar network. It allows an application to prepay gas fees on the source chain and increase the gas paid for a transaction. If too much gas is paid for a transaction, it can calculate and refund the sender. `gasService.payNativeGasForContractCall()` is called during the execution of interchain token transfers and remote token deployment or remote executions via the `interchainTokenService` contract. The `interchainTokenService` contract's [_callContract()](https://github.com/code-423n4/2024-08-axelar-network/blob/4572617124bed39add9025317d2c326acfef29f1/interchain-token-service/contracts/InterchainTokenService.sol#L816-L835) function actually does a delegate call to `GatewayCaller.callContract()` to achieve this. 

Snippet showing `gasService.payNativeGasForContractCall()` function natspec and param definition below 
https://github.com/code-423n4/2024-08-axelar-network/blob/4572617124bed39add9025317d2c326acfef29f1/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGasService.sol#L210C1-L225C24
```solidity
    /**
     * @notice Pay for gas using native currency for a contract call on a destination chain.
     * @dev This function is called on the source chain before calling the gateway to execute a remote contract.
     * @param sender The address making the payment
     * @param destinationChain The target chain where the contract call will be made
     * @param destinationAddress The target address on the destination chain
     * @param payload Data payload for the contract call
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function payNativeGasForContractCall(
        address sender,
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        address refundAddress
    ) external payable;
```
Snippet from `GatewayCaller.callContract()` below 
https://github.com/code-423n4/2024-08-axelar-network/blob/4572617124bed39add9025317d2c326acfef29f1/interchain-token-service/contracts/utils/GatewayCaller.sol#L93-L101
```solidity
                gasService.payNativeGasForContractCall{ value: gasValue }(
                    address(this),
                    destinationChain,
                    destinationAddress,
                    payload,
                    // solhint-disable-next-line avoid-tx-origin
                    tx.origin //@audit using tx.orgin as refund address is bad for meta transactions. refunds will be sent to a relayer/bundler
                );
```

Hardcoding refund address to be the t
Optional ERC-20 functional required.
Audit: 2024-08-axelar-network-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2024-08-axelar-network/blob/main/interchain-token-service/contracts/InterchainTokenFactory.sol#L198


# Vulnerability details

## Impact
Detailed description of the impact of this finding.
The solution assumes that ERC-20 tokens to be added to deployRemoteInterchainToken to implement optional functions name(),symbol(),decimals().

## Proof of Concept
Provide direct links to all referenced code in GitHub. Add screenshots, logs, or any other relevant proof that illustrates the concept.
 function deployRemoteInterchainToken(
        string calldata originalChainName,
        bytes32 salt,
        address minter,
        string memory destinationChain,
        uint256 gasValue
    ) external payable returns (bytes32 tokenId) {
        string memory tokenName;
        string memory tokenSymbol;
        uint8 tokenDecimals;
        bytes memory minter_ = new bytes(0);

        {
            bytes32 chainNameHash_;
            if (bytes(originalChainName).length == 0) {
                chainNameHash_ = chainNameHash;
            } else {
                chainNameHash_ = keccak256(bytes(originalChainName));
            }

            address sender = msg.sender;
            salt = interchainTokenSalt(chainNameHash_, sender, salt);
            tokenId = interchainTokenService.interchainTokenId(TOKEN_FACTORY_DEPLOYER, salt);

            IInterchainToken token = IInterchainToken(interchainTokenService.interchainTokenAddress(tokenId));

      @>      tokenName = token.name();
       @>     tokenSymbol = token.symbol();
       @>     tokenDecimals = token.decimals();

            if (minter != address(0)) {
                if (!token.isMinter(minter)) revert NotMinter(minter);

                minter_ = minter.toBytes();
            }
        }

        tokenId = _deployInterchainToken(salt, destinationChain, tokenName, tokenSymbol, tokenDecimals, minter_, gasValue);
    }


some ERC20 tokens may not implement these functions or may implement them with different return types.
## Tools Used

## Recommended Mitigation Steps
consider adding an extra mapping from the token address to the token symbol to support non standard tokens like MKR.


## Assessed type

Context
DoS: Gateway can accept only `4_294_967_295` messages of type `CallContract` across all source chains
Audit: 2024-08-axelar-network-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2024-08-axelar-network/blob/main/axelar-amplifier/contracts/axelarnet-gateway/src/state.rs#L30
https://github.com/code-423n4/2024-08-axelar-network/blob/main/axelar-amplifier/contracts/axelarnet-gateway/src/contract/execute.rs#L26
https://github.com/code-423n4/2024-08-axelar-network/blob/main/axelar-amplifier/contracts/axelarnet-gateway/src/contract.rs#L50-L61


# Vulnerability details

## Impact

One of permissionless entry points of `axelarnet-gateway` contract is message `CallContract`. When handling messages of this type, new message id is generated. For this, a single counter is used (for all source chains). Upon reaching the counter limit, the gateway stops registering new `CallContract` messages and can only execute outgoing messages. Migrating state of the exhausted gateway is not possible. Axelar maintainers would have to deploy new version of the gateway with reset counter while keeping the current gateway live for some time to deliver already registered requests.

## Proof of Concept

axelar-amplifier/contracts/axelarnet-gateway/src/state.rs:
```
const COUNTER: Counter<u32> = Counter::new(COUNTER_NAME);
...
pub(crate) fn increment_msg_counter(storage: &mut dyn Storage) -> Result<u32, Error> {
    COUNTER.incr(storage).map_err(Error::from)
}
```

The `Counter` structure is implemented properly (out of scope) and when it reaches the maximum value it returns `OverflowError`. We could add the following test case in axelar-amplifier/packages/axelar-wasm-std/src/counter.rs:
```
#[test]
    fn test_overflow_u8() {
        let mut store = MockStorage::new();

        let counter: Counter<u8> = Counter::new("counter");
        assert_eq!(counter.cur(&store), 0);
        for _ in 1..u8::MAX {
            counter.incr(&mut store).unwrap();
        }
        assert_eq!(counter.incr(&mut store).unwrap(), 255);
        assert!(counter.incr(&mut store).is_err());
    }
```

In `axelarnet-gateway`, this `Counter` is used together with `u32` type (not `u8`), this provides much higher limit of `4_294_967_295`, but this number is still insufficient. This counter is incremented every time new `CallContract` message is processed:
axelar-amplifier/contracts/axelarnet-gateway/src/contract/execute.rs
```
pub(crate) fn call_contract(
    store: &mut dyn Storage,
    router: &Router,
    chain_name: ChainName,
    sender: Addr,
    destination_chain: ChainName,
    destination_address: Address,
    payload: HexBinary,
) -> Result<Response, Error> {
    let counter = state::increment_msg_counter(store).change_context(Error::InvalidStoreAccess)?;
```

This means that over time, especially if the service is actively used, the counter can exhaust without any active attack being performed against the service. When it happens, cross-chain messages will not be accepted anymore. Mitigation with current codebase is difficult, given that migration of the contract state is not implemented:
axelar-amplifier/contracts/axelarnet
Tokens with a maximum transfer logic might not work for InterchainTokenService
Audit: 2024-08-axelar-network-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2024-08-axelar-network/blob/4572617124bed39add9025317d2c326acfef29f1/interchain-token-service/contracts/InterchainTokenService.sol#L454-L478
https://github.com/code-423n4/2024-08-axelar-network/blob/4572617124bed39add9025317d2c326acfef29f1/interchain-token-service/contracts/InterchainTokenService.sol#L488-L511
https://github.com/code-423n4/2024-08-axelar-network/blob/4572617124bed39add9025317d2c326acfef29f1/interchain-token-service/contracts/InterchainTokenService.sol#L527-L551


# Vulnerability details

## Impact
Some tokens (e.g., cUSDCv3) contain a special case for amount == type(uint256).max in their transfer functions that results in only the user's balance being transferred.
While handling those tokens, the protocol will lost tokens.

## Proof of Concept
I will take [InterchainTokenService.interchainTransfer](https://github.com/code-423n4/2024-08-axelar-network/blob/4572617124bed39add9025317d2c326acfef29f1/interchain-token-service/contracts/InterchainTokenService.sol#L454-L478) as an example. 
In `InterchainTokenService.interchainTransfer`, `InterchainTokenService._takeToken` is called.
And in [InterchainTokenService._takeToken](https://github.com/code-423n4/2024-08-axelar-network/blob/4572617124bed39add9025317d2c326acfef29f1/interchain-token-service/contracts/InterchainTokenService.sol#L1189-L1197), `TokenHandler.takeToken`'s implementation is used.

[TokenHandler.takeToken](https://github.com/code-423n4/2024-08-axelar-network/blob/4572617124bed39add9025317d2c326acfef29f1/interchain-token-service/contracts/TokenHandler.sol#L91-L123) is defined as:
```solidity
 91     function takeToken(
 92         bytes32 tokenId,
 93         bool tokenOnly,
 94         address from,
 95         uint256 amount
 96     ) external payable returns (uint256, string memory symbol) {
101 
102         if (tokenManagerType == uint256(TokenManagerType.NATIVE_INTERCHAIN_TOKEN)) {
103             _takeInterchainToken(tokenAddress, from, amount);
104         } else if (tokenManagerType == uint256(TokenManagerType.MINT_BURN)) {
105             _burnToken(tokenManager, tokenAddress, from, amount);
106         } else if (tokenManagerType == uint256(TokenManagerType.MINT_BURN_FROM)) {
107             _burnTokenFrom(tokenAddress, from, amount);
108         } else if (tokenManagerType == uint256(TokenManagerType.LOCK_UNLOCK)) {
109             _transferTokenFrom(tokenAddress, from, tokenManager, amount);
110         } else if (tokenManagerType == uint256(TokenManagerType.LOCK_UNLOCK_FEE)) {
111             amount = _transferTokenFromWithFee(tokenAddress, from, tokenManager, amount);
112         } else if (tokenManagerType == uint256(TokenManagerType.GATEWAY)) {
113             symbol = IERC20Named(tokenAddress).symbol();
114             _transferTokenFrom(tokenAddress, from, address(this), amount);
115         } else {
116             revert UnsupportedTokenManagerType(tokenManagerType);
117         }
	 ...
123     }
```

Whil