code4rena-2024-08-axelar-m01

[M-01] Axelar cross chain token transfers balance tracking logic is completely broken for rebasing tokens and the transfers of these type of tokens can be exploited

보고서

Summary

컨테스트 README에서는 리베이스 토큰을 지원한다고 명시했는데, 전체적인 구현은 리베이스 토큰을 정상적으로 지원하지 않았다.

Keyword

bridge, rebase token

Vulnerability

이 컨테스트의 README에서는 리베이스 토큰이 스코프로 포함된다고 명시한다. 하지만 브릿지 시스템이 전체적으로 리베이스 토큰을 지원하지 않는다. 리베이스 토큰은 잔고가 각자의 로직에 따라 변하므로 ITSHub에서의 잔고 추적이 정상적으로 되지 않으며, 브릿지 컨트랙트 구현 역시 전반적으로 리베이스 토큰을 고려하지 않는다.

토큰 매니저는 브릿지에 등록할 토큰의 종류에 따라 정할 수 있다. 그 타입을 지정하는 코드는 다음과 같은데, 이 중 리베이스 토큰을 지원하기 위한 타입은 없다.

    enum TokenManagerType {
        NATIVE_INTERCHAIN_TOKEN, // This type is reserved for interchain tokens deployed by ITS, and can't be used by custom token managers.
        MINT_BURN_FROM, // The token will be minted/burned on transfers. The token needs to give mint permission to the token manager, but burning happens via an approval.
        LOCK_UNLOCK, // The token will be locked/unlocked at the token manager.
        LOCK_UNLOCK_FEE, // The token will be locked/unlocked at the token manager, which will account for any fee-on-transfer behaviour.
        MINT_BURN, // The token will be minted/burned on transfers. The token needs to give mint and burn permission to the token manager.
        GATEWAY // The token will be sent throught the gateway via callContractWithToken
    }

리베이스 토큰이 전송 수수료를 떼지 않는다면 LOCK_UNLOCK 타입을 사용할 것이다. 그런데 토큰을 브릿지에 잠근 후 리베이스가 일어날 수 있으며, 이로 인해 토큰의 양이 감소했다면 추후 다시 토큰을 source 체인으로 브릿지 했을 때 토큰이 모자라 브릿지를 할 수 없게 된다.

또한, ITSHub에서는 브릿지되는 토큰의 양을 추적한다. 원본 체인에서 리베이스가 일어나 잠긴 토큰의 양이 감소하더라도 ITSHub 잔고에는 반영되지 않는다. source 체인으로 다시 토큰을 브릿지하려고 하면 토큰이 모자라 브릿지 할 수 없게 될 수 있다.

fn apply_balance_tracking(
    storage: &mut dyn Storage,
    source_chain: ChainName,
    destination_chain: ChainName,
    message: &ItsMessage,
) -> Result<(), Error> {
    match message {
        ItsMessage::InterchainTransfer {
@>            token_id, amount, ..
        } => {
            // Update the balance on the source chain
            update_token_balance(
                storage,
                token_id.clone(),
                source_chain.clone(),
@>                *amount,
                false,
            )
            .change_context_lazy(|| Error::BalanceUpdateFailed(source_chain, token_id.clone()))?;
 
            // Update the balance on the destination chain
            update_token_balance(
                storage,
                token_id.clone(),
                destination_chain.clone(),
@>                *amount,
                true,
            )
            .change_context_lazy(|| {
                Error::BalanceUpdateFailed(destination_chain, token_id.clone())
            })?
        }

Impact

리베이스 토큰을 정상적으로 브릿지 할 수 없다. 브릿지 요청에 실패하거나, 실제로 받아야 하는 것보다 많은/적은 토큰을 받게 된다.

Mitigation

리베이스 토큰을 지원하는 로직을 새로 구현한다.


tags: bughunting, axelar, smart contract, solidity, rust, cosmwasm, bridge, rebase token, erc20, severity medium