SlideShare a Scribd company logo
1 of 33
Download to read offline
Code4rena Audit Analysis
Axelar 22.04
2023.10.07
J.J
Axelar Contest
• Contest 요약
• 컨테스트: https://code4rena.com/contests/2022-04-axelar-network-contest
• 보고서: https://code4rena.com/reports/2022-04-axelar
• 코드: https://github.com/code-423n4/2022-04-axelar
• 2022.04.07~2022.04.12 Code4rena
• 포상 총액 $50,000
• High 1개, Medium 4개
Axelar
• Axelar 란?
• 브릿지 서비스
• 코스모스 및 EVM 체인 간 토큰 전송을 할 수 있으며 체인 간에 임의의 메시지를 보낼 수 있다.
• 기본적인 브릿지 플로우
• 출발지 체인의 게이트웨이 컨트랙트에 컨트랙트콜을 하여 이동 요청
• 토큰을 이동하는 경우 이동할 토큰을 게이트웨이 컨트랙트에 전달하거나 burn
출처: https://docs.axelar.dev/dev/general-message-passing/overview
Axelar
• Axelar 란?
• Axelar 네트워크는 Cosmos SDK를 이용해 구현한 PoS를 이용하는 블록체인
• Axelar 네트워크를 이루는 탈중앙된 Validator가 출발지 체인에서 생성한 이벤트를 확인하고 서명
• 이 서명으로 유효함을 인증하며 목적지 체인의 게이트웨이 컨트랙트에 명령을 요청하거나 메시지를 전달
• Validator는 Axelar 노드 운영자가 AXL 토큰을 스테이킹하고 외부 EVM 호환 체인과 연결하면 될 수 있음
• 검증된 브릿징 요청이 목적지 체인에서 실행되기 위해서는 Executor 서비스를 이용해야 함
• 출발지 체인의 Gas Receiver 컨트랙트에게 가스 비용을 선불하면 Validator 검증을 마친 후 자동으로 목적지 체인의 게이트웨이에 전달해주는 서비스
• https://docs.axelar.dev/dev/general-message-passing/gas-services/intro
• Executor 서비스를 이용하지 않는다면 유저가 직접 컨트랙트콜을 해야함
• Axelarscan 익스플로러에서 찾아서 지갑을 연결하고, 목적지 체인의 게이트웨이에 직접 컨트랙트콜 하면 된다.
• 여타 작업은 완료되었지만 최종 작업인 목적지 체인으로의 트랜잭션이 실패했을 시 유저가 직접 컨트랙트콜을 재시도 하여 복구할 수 있다.
출처: https://axelarscan.io/gmp/0xdad17967df1600120b76eb6e6b1ea4dc177f4b9c4afc78887334ccafeb21bf2f:2
Axelar
• Axelar 란?
• validator 로직을 간단히 살펴보기
• ProcessGatewayTxConfirmation 함수
• https://github.com/axelarnetwork/axelar-
core/blob/v0.17.3/cmd/axelard/cmd/vald/evm/evm.go#L318
-L398
• 출발지 체인의 이벤트를 잡아 파싱하고,
TokenSentSig/ContractCallSig/ContractCallWithTokenSig
를 나누어 처리한다.
• 이들은 유저가 브릿징을 요청하기 위해 출발지 체인의 게이
트웨이에 호출하는 함수와 매칭되는 이벤트이다.
• 마지막에 Broadcast 함수를 호출해 Axelar 체인의 다른 노
드들에게 전달한다.
func (mgr Mgr) ProcessGatewayTxConfirmation(e tmEvents.Event) error {
chain, gatewayAddress, txID, confHeight, pollKey, err := parseGatewayTxConfirmationParams(mgr.cdc, e.Attributes)
if err != nil {
return sdkerrors.Wrap(err, "EVM gateway transaction confirmation failed")
}
rpc, found := mgr.rpcs[strings.ToLower(chain)]
if !found {
return sdkerrors.Wrap(err, fmt.Sprintf("Unable to find an RPC for chain '%s'", chain))
}
var events []evmTypes.Event
_ = mgr.validate(rpc, txID, confHeight, func(_ *geth.Transaction, txReceipt *geth.Receipt) bool {
for i, log := range txReceipt.Logs {
if !bytes.Equal(gatewayAddress.Bytes(), log.Address.Bytes()) {
continue
}
switch log.Topics[0] {
case ContractCallSig:
…
case ContractCallWithTokenSig:
…
case TokenSentSig:
…
default:
}
}
return true
})
v, err := packEvents(events)
if err != nil {
return err
}
msg := voteTypes.NewVoteRequest(mgr.cliCtx.FromAddress, pollKey, v)
mgr.logger.Info(fmt.Sprintf("broadcasting vote %v for poll %s", events, pollKey.String()))
_, err = mgr.broadcaster.Broadcast(context.TODO(), msg)
return err
}
Axelar
• 오딧팅 범위 로직 분석
• AxelarGateway
• 브릿지로 넘기고자 하는 토큰과 메시지를 수신, 발신하는 컨트랙트
• Axelar 네트워크의 Validator에서 출발지 체인에서 발생한 이벤트를 감지하고, 검증하여 서명함
• 서명을 얻으면 목적지 체인의 AxelarGateway 컨트랙트 함수를 호출하여 토큰을 이동하거나 메시지를 전달한다.
• AxelarGateway는 기본적인 기능을 구현한 abstract 컨트랙트이다.
• 이를 상속하고 기능을 추가해 구현한 단일 서명(Singlesig)와 다중 서명(Multisig) 컨트랙트가 있다.
Axelar
• 오딧팅 범위 로직 분석
• AxelarGateway
• 출발지 체인에서 작업 생성
• 브릿지를 이용하고 싶은 유저가 출발지 체인에 배포된 AxelarGateway 컨트랙트의 함수를 호출하여 이벤트를 발생하는 것에서 브릿지 플로우가 시작
• sendToken, callContract, callContractWithToken 세 개의 엔트리포인트가 있다. 유저가 용도에 따라 함수를 선택해 호출하면 된다.
• sendToken: 추가적인 메시지 없이 단순히 ERC20을 이동
• callContract: ERC20 이동 없이 메시지만 전송
• callContractWithToken: ERC20을 이동하며 메시지도 전송
Axelar
• 오딧팅 범위 로직 분석
• AxelarGateway
• 출발지 체인에서 작업 생성
• 토큰을 이동하는 sendToken와 callContractWithToken는 _burnTokenFrom 함수를 호출
• 옮기는 토큰이 Axelar에서 자체 배포한 wrapped 토큰이라면 타 체인으로 이동
할 때 burn 하고, 목적지 체인에서 새로 발행 또는 이동된다.
• burn/mint 권한이 없는 외부 토큰이라면 transferFrom 으로 끌어온다.
• Axelar wrapped 토큰에는 InternalBurnable와 InternalBurnableFrom 타입이 있다.
• InternalBurnable 타입
• 1.0.0 버전 wrapped 토큰으로
• 그 예로는 Avalanche의 UST(native to Terra) 토큰이 있다.
• 이 토큰을 burn할 때는 salt 값을 이용해 DepositHandler 컨트랙트가
배포될 주소를 계산하고, 그 주소로 토큰을 보내야 한다. 이후 토큰의
burn 함수를 호출하면 salt값을 이용해 DepositHandler 컨트랙트 주소
를 계산, 해당 주소의 토큰을 burn 한다.
• InternalBurnableFrom 타입
• 최신 wrapped 토큰
• 그 예로는 Avalanche의 axlATOM, axlUSDC 등이 있다
• burnFrom 함수를 호출해 바로 burn 한다.
Axelar
• 오딧팅 범위 로직 분석
• AxelarGateway
• 목적지 체인에서 작업 처리
• Validator에서 확인을 마치고, 그 서명을 이용하여 목적지 체인에서 작업을 처리한다. 크게 2가지 종류로 나눌 수 있다.
• 단순히 토큰을 이동
• 메시지 전송
• 단순히 토큰을 보내는 경우(유저가 sendToken을 호출) _mintToken 함수를 호출해 Axelar wrapped 토큰으로 발행해주거나, 외부 토큰이라면 게이트웨이
에 예치된 토큰을 보내준다.
Axelar
• 오딧팅 범위 로직 분석
• AxelarGateway
• 목적지 체인에서 작업 처리
• _mintToken
• 메시지 없이 단순히 토큰을 이동하는 경우 호출
• 이동한 토큰이 Axelar wrapped 토큰으로 새로 발행되어야 하는 경우 토큰을 발행하고, 외부 토큰인 경우 게이트웨이에 예치된 토큰을 보내준다.
Axelar
• 오딧팅 범위 로직 분석
• AxelarGateway
• 목적지 체인에서 작업 처리
• 메시지를 전송은 Approve 단계와 Execute 단계로 나뉜다.
• Approve 단계는 마치 편지를 우편함에 넣는 것과 유사하다.
• Execute 단계는 우편함에서 자신의 편지를 꺼내고 반응하는 것에 비유할 수 있다.
• 메시지 전달은 다시 두 종류로 나뉜다.
• 단순 메시지 전달 (유저가 callContract를 호출)
• 토큰과 메시지 전달 (유저가 callContractWithToken를 호출)
Axelar
• 오딧팅 범위 로직 분석
• AxelarGateway
• 목적지 체인에서 작업 처리 - Approve
• 다음은 Approve 단계에 해당하는 함수들이다.
• 목적지 체인 게이트웨이에 출발지로부터 생성된 메시지를 등록한다.
• 등록된 이 메시지는 보낼 당시 메시지를 수신자로 지정한 컨트랙트만 가져다 사용할 수 있다.
• 이들은 internal 함수로, AxelarGateway 컨트랙트를 상속해 구현하는 AxelarGatewaySinglesig, AxelarGatewayMultisig
에서 external 함수에서 호출된다.
• _approveContractCall: 단순 메시지 전달 (유저가 callContract를 호출)
• _approveContractCallWithMint: 토큰과 메시지 전달 (유저가 callContractWithToken를 호출)
Axelar
• 오딧팅 범위 로직 분석
• AxelarGateway
• 목적지 체인에서 작업 처리 - Execute
• Execute 단계에서는 게이트웨이의 함수를 호출하는 게 아니라, 메시지를 소비할 컨트랙트의 함수를 호출해야 한다.
• 메시지를 수신할 컨트랙트는 IAxelarExecutable 인터페이스를 준수하여 개발해야 한다. (그래야 Relayer 서비스를 이용할 때 인터페이스가 맞음)
• 다음은 abstract 로 정의된 IAxelarExecutable 컨트랙트이다.
• 게이트웨이에 등록된(Approve) 메시지를 가져와 처리한다. 마치 우편함을 열어 자신의 편지를 가져오고 처리하는 것과 같다.
• IAxelarExecutable를 상속한 구현 컨트랙트는 메시지를 받아 처리할 로직을 _execute 또는 _executeWithToken 함수에 구현해야 한다.
• 또한, 출발지 체인에서 메시지를 생성할 당시 메시지를 수신할 목적지 컨트랙트 주소를 이 구현 컨트랙트로 지정해야 한다.
Axelar
• 오딧팅 범위 로직 분석
• AxelarGateway
• 목적지 체인에서 작업 처리 – Execute
• 메시지가 게이트웨이에 등록되었는지(Approve 되었는지) 확인하기
위해 게이트웨이의 validateContractCall와
validateContractCallAndMint를 호출한다.
• execute 또는 executeWithToken 함수 콜은 유저가 직접 Approve
단계가 끝난 것을 확인하고 호출하든가, 가스를 미리 납부하여
Executor 서비스(Relayer 서비스 또는 Gas 서비스)를 이용해 호출해
야 한다.
• Executor 서비스를 이용한다면 Axelar의 Relayer가
ContractCallApproved 또는
ContractCallApprovedWithMint 이벤트를 감지하고
execute 또는 executeWithToken 함수를 호출해준다.
• 서비스를 이용하지 않는다면 유저가 직접 이벤트를 감지하
고 반응하도록 프로그램을 짜든가 직접 호출해야 한다.
Axelar
• 오딧팅 범위 로직 분석
• AxelarGateway
• 목적지 체인에서 작업 처리 - Execute
• validateContractCall
• 유저가 callContract를 호출하여 메시지만 전달한 경우
• validateContractCallAndMint
• 유저가 callContractWithToken를 호출하여 토큰과 메시지를 함께 전달한 경우.
• 이 시점에 브릿징된 토큰을 IAxelarExecutable 구현 컨트랙트에게 전달한다.
Axelar
• 오딧팅 범위 로직 분석
• AxelarGateway
• 목적지 체인에서 작업 처리 - Execute
• 다음은 예시로 주어진 컨트랙트이다. 브릿지를 통해 받은 토큰과 메시지를 이용하여
정해진 작업을 수행한다. 플로우는 다음과 같다.
• 먼저 출발지 체인의 게이트웨이에서 callContractWithToken를 호출한다.
• Validator에서 처리를 완료하고, Apporve 단계에 도착지 체인 게이트웨이의
approveContractCallWithMint 함수를 호출하여 출발지로부터 전달된 메시
지를 등록한다.
• 이후 Relayer에 의해 상속한 IAxelarGateway 컨트랙트의 executeWithToken
가 실행된다.
• validateContractCallAndMint가 호출되어 메시지가 게이트웨이에
등록되어 있는지 확인한다. 등록되어 있다면
DestinationSwapExecutable 컨트랙트에게 Axelar wrapped 토큰을
발행한다 (브릿지를 통해 토큰을 옮겨온 토큰)
• DestinationSwapExecutable에서 override하여 정의한
_executeWithToken 함수가 호출된다. 원하는 작업을 진행한다. 예시
에서는 브릿지로 넘겨받은 토큰을 swap하였다.
Axelar
• 오딧팅 범위 로직 분석
• AxelarGatewaySinglesig
• AxelarGateway를 상속하고 구체화한 컨트랙트. 메시지를 전달할 때 단일 서명(Singlesig)을 이용한다.
• 목적지 체인의 게이트웨이로 동작하기 위한 작업은 모두 execute 함수를 통해 호출된다.
• _execute 함수에서 먼저 서명을 확인한 후 요청 작업을 확인, 해당하는 함수를 호출한다.
• Operator로 등록된 유저의 서명을 받은 경우 mintToken, approveContractCall, approveContractCallWithMint, burnToken 함수를 호출할 수 있다.
• Owner 서명을 받은 경우 Operator가 가능한 작업과 더불어 관리자 함수를 호출할 수 있다.
• 잘못된 서명 또는 자격이 없는 서명을 이용한다면 작업을 수행할 수 없다.
Axelar
• 오딧팅 범위 로직 분석
• AxelarGatewaySinglesig
• Operator의 서명을 받아 다음과 같은 작업을 처리한다.
• SELECTOR_MINT_TOKEN
• 출발지 체인에서 호출한 토큰 전송 요청 sendToken에 대한 반응.
• Axelar wrapped 토큰을 발행하거나 게이트웨이에 에치된 외부 토큰을
보내줌. mintToken 함수 호출.
• SELECTOR_APPROVE_CONTRACT_CALL
• 출발지 체인에서 호출한 메시지 전달 요청 callContract에 대한
Approve 단계 실행.
• approveContractCall 함수 호출.
• SELECTOR_APPROVE_CONTRACT_CALL_WITH_MINT
• 출발지 체인에서 호출한 메시지 전달 요청 callContractWithToken에
대한 Apporve 단계 실행.
• approveContractCallWithMint 함수 호출
Axelar
• 오딧팅 범위 로직 분석
• AxelarGatewaySinglesig
• 다음은 단순 토큰 이동 요청(sendToken)를 처리하는 함수이다.
• onlySelf modifier를 붙여 execute 함수를 통해서만 호출되도록 제한한다.
• 내용은 단순히 AxelarGateway의 internal 함수를 호출하는 것이 전부이다.
• 토큰 전송 또는 mint
Axelar
• 오딧팅 범위 로직 분석
• AxelarGatewaySinglesig
• 다음은 메시지 전송의 Approve 단계를 처리하는 함수들이다
• onlySelf modifier를 붙여 execute 함수를 통해서만 호출되도록 제한한다.
• 내용은 단순히 AxelarGateway의 internal 함수를 호출하는 것이 전부이다.
Axelar
• 오딧팅 범위 로직 분석
• AxelarGatewayMultisig
• AxelarGateway를 상속하고 구체화했다.
• 메시지를 전달할 때 다중 서명(Multisig)을
이용한다.
• 기본적인 흐름은 AxelarGatewaySinglesig
와 동일하다.
• execute 실행시 여러개의 서명을 받아 확인
한다는 점이 다르다.
Audit report 분석
• [H-01] Cross-chain smart contract calls can revert but source chain tokens remain
burnt and are not refunded
• Summary
• Axelar wrapped 토큰을 다른 체인으로 이동할 때, 출발지 체인의 토큰을 burn하고 도착지 체인에서 새로 발행 또는 전송한다.
• 이 때, 도착지 체인 측의 작업이 잘못되어 트랜잭션이 취소되어도 출발지 체인 측에서 burn한 토큰을 돌려받을 방법이 없다.
• Keyword
• bridge, cross chain, business logic vul
• Vulnerability
• callContractWithToken 함수를 호출하면 ERC20 토큰을 타 체인으로 이동하며 메시지를 전달할 수 있다.
• 출발지 체인 측의 토큰이 Axelar에서 배포한 ERC20 컨트랙트가 아닌 외부 토큰이라면 transferFrom을 이용해 Gateway 컨트랙트로 토큰을 전송
• Axelar에서 제작한 wrapped 토큰이라면 출발지 체인측 토큰을 burn 하고 도착지 체인측에서 새로 발행 또는 전송한다(도착지 체인 토큰이 Axelar
wrapped 토큰인지 여부에 따라 다름)
• callContractWithToken로 보낸 토큰과 메시지는 이를 보내고자 한 목적지 체인 상의 목적지 컨트랙트(IAxelarExecutable를 상속해 구현)
의 executeWithToken 함수를 호출해 수령한다.
• 목적지 체인에서 executeWithToken를 호출하는 트랜잭션은 여러가지 이유로 실패할 수 있다.
• 하지만 목적지 체인에서 실패하여도 출발지 체인에서 이미 burn 또는 transfer한 토큰을 복구할 방법은 없다.
• 따라서 도착지 체인에서 토큰을 받지 못해 유저가 자산을 잃을 수 있다.
Audit report 분석
• [H-01] Cross-chain smart contract calls can revert but source chain tokens remain
burnt and are not refunded
• Impact
• 유저가 목적지에서 토큰을 받지 못하여 자산을 잃는다.
• Mitigation
• 목적지 체인에서 컨트랙트 콜이 실패할 경우 출발지 체인의 토큰을 다시 돌려준다.
• Memo
• 주최측은 목적지 체인의 트랜잭션이 revert 되었더라도 다시 실행하면 된다고 하였다. 이 컨테스트를 열 때는 아직 공식적인 방법을 제
공하지 않았던 것 같다. 현재는 Axelar의 익스플로러에서 유저의 지갑을 연결에 목적지 체인에서 트랜잭션을 재시도할 수 있는 방법을
제공한다.
• 주최측이 이렇게 설명했지만, 심판은 그래도 문제 자체가 존재하며, 이 시점에는 공식적인 방법이 없었으므로 High로 인정했다.
Audit report 분석
• [M-01] Low level call returns true if the address doesn’t exist
• Summary
• 로우레벨 call은 해당 주소에 컨트랙트가 배포되지 않았다면 revert 되지 않고, true를 리턴한다.
• 따라서 로우레벨 call을 하기 전 해당 주소에 컨트랙트가 배포되었는지 확인해야 한다.
• Keyword
• low level call
• Vulnerability
• solidity docs를 참고하면 로우레벨 call, delegatecall, staticcall은 해당 주소에 컨트랙트가 배포되지 않았다면 true를 리턴한다 명시한
다.
• https://docs.soliditylang.org/en/develop/control-structures.html#error-handling-assert-require-revert-and-exceptions
Audit report 분석
• [M-01] Low level call returns true if the address doesn’t exist
• Vulnerability
• AxelarGateway의 _callERC20Token 함수에서 컨트랙트 배포 여부를 확인하지 않는다.
• 또한 AxelarGatewayProxy의 constructor 에서도 확인하지 않는다.
Audit report 분석
• [M-01] Low level call returns true if the address doesn’t exist
• Impact
• 로우레벨 call이 실패했음에도 revert 되지 않는다.
• Mitigation
• 로우레벨 call을 하기 전에 해당 주소에 컨트랙트가 배포되었는지 확인한다.
Audit report 분석
• [M-02] User’s funds can get lost when transferring to other chain
• Summary
• 도착지 체인 측의 게이트웨이에 토큰이 부족하면 도착지 체인에서 토큰을 줄 수 없고 트랜잭션이 revert 된다.
• 출발지 체인에서 유저는 이미 토큰을 burn 또는 transfer 했기 때문에 목적지에서 받지 못하면 자산을 잃게 된다.
• Keyword
• bridge, cross chain, business logic vul
• Vulnerability
• 도착지 체인에서 토큰을 줄 때, Axelar wrapped 토큰이 아닌 외부 토큰을 주어야 한다면 게이트웨이에 예치된 토큰을 transfer 한다.
• 이 때, 게이트웨이에 토큰이 필요한 만큼 예치되어 있지 않다면 도착지 체인 측 트랜잭션이 revert 될 것이다.
• 따라서 출발지 체인에서 유저의 토큰은 burn 또는 transfer 되었지만 도착지에서는 토큰을 받지 못해 유저가 자산을 잃을 수 있다.
Audit report 분석
• [M-02] User’s funds can get lost when transferring to other chain
• Vulnerability
Audit report 분석
• [M-02] User’s funds can get lost when transferring to other chain
• Impact
• 도착지에서는 토큰을 받지 못해 유저가 자산을 잃을 수 있다.
• Mitigation
• 목적지 체인에서 토큰을 전송하는데 실패했다면 출발지 체인의 토큰을 반환한다.
Audit report 분석
• [M-03] _execute can potentially reorder a batch of commands while executing,
breaking any assumptions on command orders
• Summary
• 재진입을 통해 배치로 처리되는 작업의 실행 순서를 조작할 수 있다.
• Keyword
• reordering, reentrancy, replay attack, signature
• Vulnerability
• AxelarGatewayMultisig.execute 함수는 여러가지 커맨드를 배치로 실행한다.
• 각 커맨드는 고유한 commandId가 붙어있다. _execute 함수는 기존에 실행했던 commandId를 재시도하는 것을 허용한다 (revert 하지
않는다).
• 공격자는 배치 실행되는 커맨드의 실행 순서를 재배열할 수 있다.
• 재진입으로 execute 함수를 호출하면 원래 나중에 호출될 커맨드를 먼저 실행할 수 있다.
• 이를 통해 컨텍스트에 대한 가정(순서대로 실행될 것이란 가정)을 깨뜨릴 수 있다.
Audit report 분석
• [M-03] _execute can potentially reorder a batch of commands while executing,
breaking any assumptions on command orders
• Impact
• 재진입을 통해 커맨드의 실행 순서를 조작할 수 있다.
• Mitigation
• execute 함수를 재진입 불가하게 한다. 또한 서명을 재전송할 수 없도록 nonce를 추가하라 했다.
• Memo
• High로 제출했지만 Medium으로 조정되었다.
• 주최자 측은 Axelar와 게이트웨이가 명령 실행 순서를 구체적으로 보장하지는 않으므로 순서를 섞는 취약점(reordering)이 논쟁의 여지
가 있다 했다. 이를 악용하는 시나리오가 없기 때문에 Low 또는 non-risk 라고 주장했다.
• 심판은 위험도가 높은 문제는 아니지만, 재진입과 서명 재전송이 가능하기 때문에 이를 완화할 필요가 있다고 하며 Medium으로 인정
했다.
Audit report 분석
• [M-04] Unsupported fee-on-transfer tokens
• Summary
• fee-on-transfer 토큰을 고려하지 않았다. 출발지 체인에 실제로 예치된 토큰보다 많은 양의 토큰을 목적지 체인에서 받을 수 있다.
• Keyword
• fee-on-transfer token, erc20
• Vulnerability
• 출발지 체인에서 토큰을 이동할 시, 외부 토큰을 이용한다면 유저의 토큰을 transferFrom으로 게이트웨이에 예치한다.
• fee-on-transfer 토큰은 transfer 할 때 수수료를 뗀다. 따라서 실제로 게이트웨이에 예치되는 토큰은 요청한 것보다 적어진다.
Audit report 분석
• [M-04] Unsupported fee-on-transfer tokens
• Impact
• 실제로 예치된 토큰보다 많은 토큰을 목적지 체인에서 받을 수 있다.
• Mitigation
• 목적지 체인에서 토큰을 보내줄 때, 수수료를 제한 만큼(실제로 예치된 만큼) 보낸다.

More Related Content

Similar to Axelar 22.04 bughunting case study

NDC12_Lockless게임서버설계와구현
NDC12_Lockless게임서버설계와구현NDC12_Lockless게임서버설계와구현
NDC12_Lockless게임서버설계와구현noerror
 
코어 이더리움
코어 이더리움 코어 이더리움
코어 이더리움 Jay JH Park
 
세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍
세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍
세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍Jay JH Park
 
Blockchain 3rd smart contract programming
Blockchain 3rd smart contract programmingBlockchain 3rd smart contract programming
Blockchain 3rd smart contract programmingihpark92
 
[164] pinpoint
[164] pinpoint[164] pinpoint
[164] pinpointNAVER D2
 
(C#,네트워크강좌)간단한 TCP 클라이언트/서버 구현, 멀티쓰레드 기반 에코우 클라이언트/서버_C추천#/WPF/자마린실무교육학원
(C#,네트워크강좌)간단한 TCP 클라이언트/서버 구현, 멀티쓰레드 기반 에코우 클라이언트/서버_C추천#/WPF/자마린실무교육학원(C#,네트워크강좌)간단한 TCP 클라이언트/서버 구현, 멀티쓰레드 기반 에코우 클라이언트/서버_C추천#/WPF/자마린실무교육학원
(C#,네트워크강좌)간단한 TCP 클라이언트/서버 구현, 멀티쓰레드 기반 에코우 클라이언트/서버_C추천#/WPF/자마린실무교육학원탑크리에듀(구로디지털단지역3번출구 2분거리)
 
Clova extension에서 OAuth 계정 연동 구현
Clova extension에서 OAuth 계정 연동 구현Clova extension에서 OAuth 계정 연동 구현
Clova extension에서 OAuth 계정 연동 구현Gosu Ok
 
Scope and Closure of JavaScript
Scope and Closure of JavaScript Scope and Closure of JavaScript
Scope and Closure of JavaScript Dahye Kim
 
JSP 프로그래밍 #03 서블릿
JSP 프로그래밍 #03 서블릿JSP 프로그래밍 #03 서블릿
JSP 프로그래밍 #03 서블릿Myungjin Lee
 
TXGX 2019_Jesse_Klaytn API Service
TXGX 2019_Jesse_Klaytn API ServiceTXGX 2019_Jesse_Klaytn API Service
TXGX 2019_Jesse_Klaytn API ServiceKlaytn
 
20130329 tomcat ssl
20130329 tomcat ssl20130329 tomcat ssl
20130329 tomcat sslSukjin Yun
 
ECS+Locust로 부하 테스트 진행하기
ECS+Locust로 부하 테스트 진행하기ECS+Locust로 부하 테스트 진행하기
ECS+Locust로 부하 테스트 진행하기Yungon Park
 
Clova Tech Summit 세션3 :Clova extension에서 OAuth 계정 연동 구현
Clova Tech Summit 세션3 :Clova extension에서 OAuth 계정 연동 구현Clova Tech Summit 세션3 :Clova extension에서 OAuth 계정 연동 구현
Clova Tech Summit 세션3 :Clova extension에서 OAuth 계정 연동 구현Clova Platform
 
Service mesh(istio) monitoring
Service mesh(istio) monitoringService mesh(istio) monitoring
Service mesh(istio) monitoringJeong-Ho Na
 
Mastering ethereum(smart contract)
Mastering ethereum(smart contract)Mastering ethereum(smart contract)
Mastering ethereum(smart contract)제호 송
 
동기화, 스케줄링
동기화, 스케줄링동기화, 스케줄링
동기화, 스케줄링xxbdxx
 

Similar to Axelar 22.04 bughunting case study (19)

NDC12_Lockless게임서버설계와구현
NDC12_Lockless게임서버설계와구현NDC12_Lockless게임서버설계와구현
NDC12_Lockless게임서버설계와구현
 
코어 이더리움
코어 이더리움 코어 이더리움
코어 이더리움
 
Clean code appendix 1
Clean code appendix 1Clean code appendix 1
Clean code appendix 1
 
세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍
세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍
세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍
 
tcp ip study
tcp ip studytcp ip study
tcp ip study
 
Servlet3
Servlet3Servlet3
Servlet3
 
Blockchain 3rd smart contract programming
Blockchain 3rd smart contract programmingBlockchain 3rd smart contract programming
Blockchain 3rd smart contract programming
 
[164] pinpoint
[164] pinpoint[164] pinpoint
[164] pinpoint
 
(C#,네트워크강좌)간단한 TCP 클라이언트/서버 구현, 멀티쓰레드 기반 에코우 클라이언트/서버_C추천#/WPF/자마린실무교육학원
(C#,네트워크강좌)간단한 TCP 클라이언트/서버 구현, 멀티쓰레드 기반 에코우 클라이언트/서버_C추천#/WPF/자마린실무교육학원(C#,네트워크강좌)간단한 TCP 클라이언트/서버 구현, 멀티쓰레드 기반 에코우 클라이언트/서버_C추천#/WPF/자마린실무교육학원
(C#,네트워크강좌)간단한 TCP 클라이언트/서버 구현, 멀티쓰레드 기반 에코우 클라이언트/서버_C추천#/WPF/자마린실무교육학원
 
Clova extension에서 OAuth 계정 연동 구현
Clova extension에서 OAuth 계정 연동 구현Clova extension에서 OAuth 계정 연동 구현
Clova extension에서 OAuth 계정 연동 구현
 
Scope and Closure of JavaScript
Scope and Closure of JavaScript Scope and Closure of JavaScript
Scope and Closure of JavaScript
 
JSP 프로그래밍 #03 서블릿
JSP 프로그래밍 #03 서블릿JSP 프로그래밍 #03 서블릿
JSP 프로그래밍 #03 서블릿
 
TXGX 2019_Jesse_Klaytn API Service
TXGX 2019_Jesse_Klaytn API ServiceTXGX 2019_Jesse_Klaytn API Service
TXGX 2019_Jesse_Klaytn API Service
 
20130329 tomcat ssl
20130329 tomcat ssl20130329 tomcat ssl
20130329 tomcat ssl
 
ECS+Locust로 부하 테스트 진행하기
ECS+Locust로 부하 테스트 진행하기ECS+Locust로 부하 테스트 진행하기
ECS+Locust로 부하 테스트 진행하기
 
Clova Tech Summit 세션3 :Clova extension에서 OAuth 계정 연동 구현
Clova Tech Summit 세션3 :Clova extension에서 OAuth 계정 연동 구현Clova Tech Summit 세션3 :Clova extension에서 OAuth 계정 연동 구현
Clova Tech Summit 세션3 :Clova extension에서 OAuth 계정 연동 구현
 
Service mesh(istio) monitoring
Service mesh(istio) monitoringService mesh(istio) monitoring
Service mesh(istio) monitoring
 
Mastering ethereum(smart contract)
Mastering ethereum(smart contract)Mastering ethereum(smart contract)
Mastering ethereum(smart contract)
 
동기화, 스케줄링
동기화, 스케줄링동기화, 스케줄링
동기화, 스케줄링
 

More from Jinkyoung Kim

Nouns DAO bughunting case study
Nouns DAO bughunting case studyNouns DAO bughunting case study
Nouns DAO bughunting case studyJinkyoung Kim
 
해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기
해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기
해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기Jinkyoung Kim
 
Web hacking introduction
Web hacking introductionWeb hacking introduction
Web hacking introductionJinkyoung Kim
 
Linux reversing study_basic_4
Linux reversing study_basic_4Linux reversing study_basic_4
Linux reversing study_basic_4Jinkyoung Kim
 
Linux reversing study_basic_3
Linux reversing study_basic_3Linux reversing study_basic_3
Linux reversing study_basic_3Jinkyoung Kim
 
Linux reversing study_basic_2
Linux reversing study_basic_2Linux reversing study_basic_2
Linux reversing study_basic_2Jinkyoung Kim
 
Linux reversing study_basic_1
Linux reversing study_basic_1Linux reversing study_basic_1
Linux reversing study_basic_1Jinkyoung Kim
 
Pwnable study basic_3
Pwnable study basic_3Pwnable study basic_3
Pwnable study basic_3Jinkyoung Kim
 
Pwnable study basic_2
Pwnable study basic_2Pwnable study basic_2
Pwnable study basic_2Jinkyoung Kim
 
Pwnable study basic_1
Pwnable study basic_1Pwnable study basic_1
Pwnable study basic_1Jinkyoung Kim
 
Windows reversing study_basic_9
Windows reversing study_basic_9Windows reversing study_basic_9
Windows reversing study_basic_9Jinkyoung Kim
 
Windows reversing study_basic_8
Windows reversing study_basic_8Windows reversing study_basic_8
Windows reversing study_basic_8Jinkyoung Kim
 

More from Jinkyoung Kim (20)

Nouns DAO bughunting case study
Nouns DAO bughunting case studyNouns DAO bughunting case study
Nouns DAO bughunting case study
 
해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기
해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기
해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기
 
Web hacking introduction
Web hacking introductionWeb hacking introduction
Web hacking introduction
 
Linux reversing study_basic_4
Linux reversing study_basic_4Linux reversing study_basic_4
Linux reversing study_basic_4
 
Linux reversing study_basic_3
Linux reversing study_basic_3Linux reversing study_basic_3
Linux reversing study_basic_3
 
Linux reversing study_basic_2
Linux reversing study_basic_2Linux reversing study_basic_2
Linux reversing study_basic_2
 
Linux reversing study_basic_1
Linux reversing study_basic_1Linux reversing study_basic_1
Linux reversing study_basic_1
 
Pwnable study basic_3
Pwnable study basic_3Pwnable study basic_3
Pwnable study basic_3
 
Pwnable study basic_2
Pwnable study basic_2Pwnable study basic_2
Pwnable study basic_2
 
Pwnable study basic_1
Pwnable study basic_1Pwnable study basic_1
Pwnable study basic_1
 
Python
PythonPython
Python
 
System+os study 7
System+os study 7System+os study 7
System+os study 7
 
System+os study 6
System+os study 6System+os study 6
System+os study 6
 
System+os study 5
System+os study 5System+os study 5
System+os study 5
 
System+os study 4
System+os study 4System+os study 4
System+os study 4
 
System+os study 3
System+os study 3System+os study 3
System+os study 3
 
System+os study 2
System+os study 2System+os study 2
System+os study 2
 
System+os study 1
System+os study 1System+os study 1
System+os study 1
 
Windows reversing study_basic_9
Windows reversing study_basic_9Windows reversing study_basic_9
Windows reversing study_basic_9
 
Windows reversing study_basic_8
Windows reversing study_basic_8Windows reversing study_basic_8
Windows reversing study_basic_8
 

Axelar 22.04 bughunting case study

  • 1. Code4rena Audit Analysis Axelar 22.04 2023.10.07 J.J
  • 2. Axelar Contest • Contest 요약 • 컨테스트: https://code4rena.com/contests/2022-04-axelar-network-contest • 보고서: https://code4rena.com/reports/2022-04-axelar • 코드: https://github.com/code-423n4/2022-04-axelar • 2022.04.07~2022.04.12 Code4rena • 포상 총액 $50,000 • High 1개, Medium 4개
  • 3. Axelar • Axelar 란? • 브릿지 서비스 • 코스모스 및 EVM 체인 간 토큰 전송을 할 수 있으며 체인 간에 임의의 메시지를 보낼 수 있다. • 기본적인 브릿지 플로우 • 출발지 체인의 게이트웨이 컨트랙트에 컨트랙트콜을 하여 이동 요청 • 토큰을 이동하는 경우 이동할 토큰을 게이트웨이 컨트랙트에 전달하거나 burn 출처: https://docs.axelar.dev/dev/general-message-passing/overview
  • 4. Axelar • Axelar 란? • Axelar 네트워크는 Cosmos SDK를 이용해 구현한 PoS를 이용하는 블록체인 • Axelar 네트워크를 이루는 탈중앙된 Validator가 출발지 체인에서 생성한 이벤트를 확인하고 서명 • 이 서명으로 유효함을 인증하며 목적지 체인의 게이트웨이 컨트랙트에 명령을 요청하거나 메시지를 전달 • Validator는 Axelar 노드 운영자가 AXL 토큰을 스테이킹하고 외부 EVM 호환 체인과 연결하면 될 수 있음 • 검증된 브릿징 요청이 목적지 체인에서 실행되기 위해서는 Executor 서비스를 이용해야 함 • 출발지 체인의 Gas Receiver 컨트랙트에게 가스 비용을 선불하면 Validator 검증을 마친 후 자동으로 목적지 체인의 게이트웨이에 전달해주는 서비스 • https://docs.axelar.dev/dev/general-message-passing/gas-services/intro • Executor 서비스를 이용하지 않는다면 유저가 직접 컨트랙트콜을 해야함 • Axelarscan 익스플로러에서 찾아서 지갑을 연결하고, 목적지 체인의 게이트웨이에 직접 컨트랙트콜 하면 된다. • 여타 작업은 완료되었지만 최종 작업인 목적지 체인으로의 트랜잭션이 실패했을 시 유저가 직접 컨트랙트콜을 재시도 하여 복구할 수 있다. 출처: https://axelarscan.io/gmp/0xdad17967df1600120b76eb6e6b1ea4dc177f4b9c4afc78887334ccafeb21bf2f:2
  • 5. Axelar • Axelar 란? • validator 로직을 간단히 살펴보기 • ProcessGatewayTxConfirmation 함수 • https://github.com/axelarnetwork/axelar- core/blob/v0.17.3/cmd/axelard/cmd/vald/evm/evm.go#L318 -L398 • 출발지 체인의 이벤트를 잡아 파싱하고, TokenSentSig/ContractCallSig/ContractCallWithTokenSig 를 나누어 처리한다. • 이들은 유저가 브릿징을 요청하기 위해 출발지 체인의 게이 트웨이에 호출하는 함수와 매칭되는 이벤트이다. • 마지막에 Broadcast 함수를 호출해 Axelar 체인의 다른 노 드들에게 전달한다. func (mgr Mgr) ProcessGatewayTxConfirmation(e tmEvents.Event) error { chain, gatewayAddress, txID, confHeight, pollKey, err := parseGatewayTxConfirmationParams(mgr.cdc, e.Attributes) if err != nil { return sdkerrors.Wrap(err, "EVM gateway transaction confirmation failed") } rpc, found := mgr.rpcs[strings.ToLower(chain)] if !found { return sdkerrors.Wrap(err, fmt.Sprintf("Unable to find an RPC for chain '%s'", chain)) } var events []evmTypes.Event _ = mgr.validate(rpc, txID, confHeight, func(_ *geth.Transaction, txReceipt *geth.Receipt) bool { for i, log := range txReceipt.Logs { if !bytes.Equal(gatewayAddress.Bytes(), log.Address.Bytes()) { continue } switch log.Topics[0] { case ContractCallSig: … case ContractCallWithTokenSig: … case TokenSentSig: … default: } } return true }) v, err := packEvents(events) if err != nil { return err } msg := voteTypes.NewVoteRequest(mgr.cliCtx.FromAddress, pollKey, v) mgr.logger.Info(fmt.Sprintf("broadcasting vote %v for poll %s", events, pollKey.String())) _, err = mgr.broadcaster.Broadcast(context.TODO(), msg) return err }
  • 6. Axelar • 오딧팅 범위 로직 분석 • AxelarGateway • 브릿지로 넘기고자 하는 토큰과 메시지를 수신, 발신하는 컨트랙트 • Axelar 네트워크의 Validator에서 출발지 체인에서 발생한 이벤트를 감지하고, 검증하여 서명함 • 서명을 얻으면 목적지 체인의 AxelarGateway 컨트랙트 함수를 호출하여 토큰을 이동하거나 메시지를 전달한다. • AxelarGateway는 기본적인 기능을 구현한 abstract 컨트랙트이다. • 이를 상속하고 기능을 추가해 구현한 단일 서명(Singlesig)와 다중 서명(Multisig) 컨트랙트가 있다.
  • 7. Axelar • 오딧팅 범위 로직 분석 • AxelarGateway • 출발지 체인에서 작업 생성 • 브릿지를 이용하고 싶은 유저가 출발지 체인에 배포된 AxelarGateway 컨트랙트의 함수를 호출하여 이벤트를 발생하는 것에서 브릿지 플로우가 시작 • sendToken, callContract, callContractWithToken 세 개의 엔트리포인트가 있다. 유저가 용도에 따라 함수를 선택해 호출하면 된다. • sendToken: 추가적인 메시지 없이 단순히 ERC20을 이동 • callContract: ERC20 이동 없이 메시지만 전송 • callContractWithToken: ERC20을 이동하며 메시지도 전송
  • 8. Axelar • 오딧팅 범위 로직 분석 • AxelarGateway • 출발지 체인에서 작업 생성 • 토큰을 이동하는 sendToken와 callContractWithToken는 _burnTokenFrom 함수를 호출 • 옮기는 토큰이 Axelar에서 자체 배포한 wrapped 토큰이라면 타 체인으로 이동 할 때 burn 하고, 목적지 체인에서 새로 발행 또는 이동된다. • burn/mint 권한이 없는 외부 토큰이라면 transferFrom 으로 끌어온다. • Axelar wrapped 토큰에는 InternalBurnable와 InternalBurnableFrom 타입이 있다. • InternalBurnable 타입 • 1.0.0 버전 wrapped 토큰으로 • 그 예로는 Avalanche의 UST(native to Terra) 토큰이 있다. • 이 토큰을 burn할 때는 salt 값을 이용해 DepositHandler 컨트랙트가 배포될 주소를 계산하고, 그 주소로 토큰을 보내야 한다. 이후 토큰의 burn 함수를 호출하면 salt값을 이용해 DepositHandler 컨트랙트 주소 를 계산, 해당 주소의 토큰을 burn 한다. • InternalBurnableFrom 타입 • 최신 wrapped 토큰 • 그 예로는 Avalanche의 axlATOM, axlUSDC 등이 있다 • burnFrom 함수를 호출해 바로 burn 한다.
  • 9. Axelar • 오딧팅 범위 로직 분석 • AxelarGateway • 목적지 체인에서 작업 처리 • Validator에서 확인을 마치고, 그 서명을 이용하여 목적지 체인에서 작업을 처리한다. 크게 2가지 종류로 나눌 수 있다. • 단순히 토큰을 이동 • 메시지 전송 • 단순히 토큰을 보내는 경우(유저가 sendToken을 호출) _mintToken 함수를 호출해 Axelar wrapped 토큰으로 발행해주거나, 외부 토큰이라면 게이트웨이 에 예치된 토큰을 보내준다.
  • 10. Axelar • 오딧팅 범위 로직 분석 • AxelarGateway • 목적지 체인에서 작업 처리 • _mintToken • 메시지 없이 단순히 토큰을 이동하는 경우 호출 • 이동한 토큰이 Axelar wrapped 토큰으로 새로 발행되어야 하는 경우 토큰을 발행하고, 외부 토큰인 경우 게이트웨이에 예치된 토큰을 보내준다.
  • 11. Axelar • 오딧팅 범위 로직 분석 • AxelarGateway • 목적지 체인에서 작업 처리 • 메시지를 전송은 Approve 단계와 Execute 단계로 나뉜다. • Approve 단계는 마치 편지를 우편함에 넣는 것과 유사하다. • Execute 단계는 우편함에서 자신의 편지를 꺼내고 반응하는 것에 비유할 수 있다. • 메시지 전달은 다시 두 종류로 나뉜다. • 단순 메시지 전달 (유저가 callContract를 호출) • 토큰과 메시지 전달 (유저가 callContractWithToken를 호출)
  • 12. Axelar • 오딧팅 범위 로직 분석 • AxelarGateway • 목적지 체인에서 작업 처리 - Approve • 다음은 Approve 단계에 해당하는 함수들이다. • 목적지 체인 게이트웨이에 출발지로부터 생성된 메시지를 등록한다. • 등록된 이 메시지는 보낼 당시 메시지를 수신자로 지정한 컨트랙트만 가져다 사용할 수 있다. • 이들은 internal 함수로, AxelarGateway 컨트랙트를 상속해 구현하는 AxelarGatewaySinglesig, AxelarGatewayMultisig 에서 external 함수에서 호출된다. • _approveContractCall: 단순 메시지 전달 (유저가 callContract를 호출) • _approveContractCallWithMint: 토큰과 메시지 전달 (유저가 callContractWithToken를 호출)
  • 13. Axelar • 오딧팅 범위 로직 분석 • AxelarGateway • 목적지 체인에서 작업 처리 - Execute • Execute 단계에서는 게이트웨이의 함수를 호출하는 게 아니라, 메시지를 소비할 컨트랙트의 함수를 호출해야 한다. • 메시지를 수신할 컨트랙트는 IAxelarExecutable 인터페이스를 준수하여 개발해야 한다. (그래야 Relayer 서비스를 이용할 때 인터페이스가 맞음) • 다음은 abstract 로 정의된 IAxelarExecutable 컨트랙트이다. • 게이트웨이에 등록된(Approve) 메시지를 가져와 처리한다. 마치 우편함을 열어 자신의 편지를 가져오고 처리하는 것과 같다. • IAxelarExecutable를 상속한 구현 컨트랙트는 메시지를 받아 처리할 로직을 _execute 또는 _executeWithToken 함수에 구현해야 한다. • 또한, 출발지 체인에서 메시지를 생성할 당시 메시지를 수신할 목적지 컨트랙트 주소를 이 구현 컨트랙트로 지정해야 한다.
  • 14. Axelar • 오딧팅 범위 로직 분석 • AxelarGateway • 목적지 체인에서 작업 처리 – Execute • 메시지가 게이트웨이에 등록되었는지(Approve 되었는지) 확인하기 위해 게이트웨이의 validateContractCall와 validateContractCallAndMint를 호출한다. • execute 또는 executeWithToken 함수 콜은 유저가 직접 Approve 단계가 끝난 것을 확인하고 호출하든가, 가스를 미리 납부하여 Executor 서비스(Relayer 서비스 또는 Gas 서비스)를 이용해 호출해 야 한다. • Executor 서비스를 이용한다면 Axelar의 Relayer가 ContractCallApproved 또는 ContractCallApprovedWithMint 이벤트를 감지하고 execute 또는 executeWithToken 함수를 호출해준다. • 서비스를 이용하지 않는다면 유저가 직접 이벤트를 감지하 고 반응하도록 프로그램을 짜든가 직접 호출해야 한다.
  • 15. Axelar • 오딧팅 범위 로직 분석 • AxelarGateway • 목적지 체인에서 작업 처리 - Execute • validateContractCall • 유저가 callContract를 호출하여 메시지만 전달한 경우 • validateContractCallAndMint • 유저가 callContractWithToken를 호출하여 토큰과 메시지를 함께 전달한 경우. • 이 시점에 브릿징된 토큰을 IAxelarExecutable 구현 컨트랙트에게 전달한다.
  • 16. Axelar • 오딧팅 범위 로직 분석 • AxelarGateway • 목적지 체인에서 작업 처리 - Execute • 다음은 예시로 주어진 컨트랙트이다. 브릿지를 통해 받은 토큰과 메시지를 이용하여 정해진 작업을 수행한다. 플로우는 다음과 같다. • 먼저 출발지 체인의 게이트웨이에서 callContractWithToken를 호출한다. • Validator에서 처리를 완료하고, Apporve 단계에 도착지 체인 게이트웨이의 approveContractCallWithMint 함수를 호출하여 출발지로부터 전달된 메시 지를 등록한다. • 이후 Relayer에 의해 상속한 IAxelarGateway 컨트랙트의 executeWithToken 가 실행된다. • validateContractCallAndMint가 호출되어 메시지가 게이트웨이에 등록되어 있는지 확인한다. 등록되어 있다면 DestinationSwapExecutable 컨트랙트에게 Axelar wrapped 토큰을 발행한다 (브릿지를 통해 토큰을 옮겨온 토큰) • DestinationSwapExecutable에서 override하여 정의한 _executeWithToken 함수가 호출된다. 원하는 작업을 진행한다. 예시 에서는 브릿지로 넘겨받은 토큰을 swap하였다.
  • 17. Axelar • 오딧팅 범위 로직 분석 • AxelarGatewaySinglesig • AxelarGateway를 상속하고 구체화한 컨트랙트. 메시지를 전달할 때 단일 서명(Singlesig)을 이용한다. • 목적지 체인의 게이트웨이로 동작하기 위한 작업은 모두 execute 함수를 통해 호출된다. • _execute 함수에서 먼저 서명을 확인한 후 요청 작업을 확인, 해당하는 함수를 호출한다. • Operator로 등록된 유저의 서명을 받은 경우 mintToken, approveContractCall, approveContractCallWithMint, burnToken 함수를 호출할 수 있다. • Owner 서명을 받은 경우 Operator가 가능한 작업과 더불어 관리자 함수를 호출할 수 있다. • 잘못된 서명 또는 자격이 없는 서명을 이용한다면 작업을 수행할 수 없다.
  • 18. Axelar • 오딧팅 범위 로직 분석 • AxelarGatewaySinglesig • Operator의 서명을 받아 다음과 같은 작업을 처리한다. • SELECTOR_MINT_TOKEN • 출발지 체인에서 호출한 토큰 전송 요청 sendToken에 대한 반응. • Axelar wrapped 토큰을 발행하거나 게이트웨이에 에치된 외부 토큰을 보내줌. mintToken 함수 호출. • SELECTOR_APPROVE_CONTRACT_CALL • 출발지 체인에서 호출한 메시지 전달 요청 callContract에 대한 Approve 단계 실행. • approveContractCall 함수 호출. • SELECTOR_APPROVE_CONTRACT_CALL_WITH_MINT • 출발지 체인에서 호출한 메시지 전달 요청 callContractWithToken에 대한 Apporve 단계 실행. • approveContractCallWithMint 함수 호출
  • 19. Axelar • 오딧팅 범위 로직 분석 • AxelarGatewaySinglesig • 다음은 단순 토큰 이동 요청(sendToken)를 처리하는 함수이다. • onlySelf modifier를 붙여 execute 함수를 통해서만 호출되도록 제한한다. • 내용은 단순히 AxelarGateway의 internal 함수를 호출하는 것이 전부이다. • 토큰 전송 또는 mint
  • 20. Axelar • 오딧팅 범위 로직 분석 • AxelarGatewaySinglesig • 다음은 메시지 전송의 Approve 단계를 처리하는 함수들이다 • onlySelf modifier를 붙여 execute 함수를 통해서만 호출되도록 제한한다. • 내용은 단순히 AxelarGateway의 internal 함수를 호출하는 것이 전부이다.
  • 21. Axelar • 오딧팅 범위 로직 분석 • AxelarGatewayMultisig • AxelarGateway를 상속하고 구체화했다. • 메시지를 전달할 때 다중 서명(Multisig)을 이용한다. • 기본적인 흐름은 AxelarGatewaySinglesig 와 동일하다. • execute 실행시 여러개의 서명을 받아 확인 한다는 점이 다르다.
  • 22. Audit report 분석 • [H-01] Cross-chain smart contract calls can revert but source chain tokens remain burnt and are not refunded • Summary • Axelar wrapped 토큰을 다른 체인으로 이동할 때, 출발지 체인의 토큰을 burn하고 도착지 체인에서 새로 발행 또는 전송한다. • 이 때, 도착지 체인 측의 작업이 잘못되어 트랜잭션이 취소되어도 출발지 체인 측에서 burn한 토큰을 돌려받을 방법이 없다. • Keyword • bridge, cross chain, business logic vul • Vulnerability • callContractWithToken 함수를 호출하면 ERC20 토큰을 타 체인으로 이동하며 메시지를 전달할 수 있다. • 출발지 체인 측의 토큰이 Axelar에서 배포한 ERC20 컨트랙트가 아닌 외부 토큰이라면 transferFrom을 이용해 Gateway 컨트랙트로 토큰을 전송 • Axelar에서 제작한 wrapped 토큰이라면 출발지 체인측 토큰을 burn 하고 도착지 체인측에서 새로 발행 또는 전송한다(도착지 체인 토큰이 Axelar wrapped 토큰인지 여부에 따라 다름) • callContractWithToken로 보낸 토큰과 메시지는 이를 보내고자 한 목적지 체인 상의 목적지 컨트랙트(IAxelarExecutable를 상속해 구현) 의 executeWithToken 함수를 호출해 수령한다. • 목적지 체인에서 executeWithToken를 호출하는 트랜잭션은 여러가지 이유로 실패할 수 있다. • 하지만 목적지 체인에서 실패하여도 출발지 체인에서 이미 burn 또는 transfer한 토큰을 복구할 방법은 없다. • 따라서 도착지 체인에서 토큰을 받지 못해 유저가 자산을 잃을 수 있다.
  • 23. Audit report 분석 • [H-01] Cross-chain smart contract calls can revert but source chain tokens remain burnt and are not refunded • Impact • 유저가 목적지에서 토큰을 받지 못하여 자산을 잃는다. • Mitigation • 목적지 체인에서 컨트랙트 콜이 실패할 경우 출발지 체인의 토큰을 다시 돌려준다. • Memo • 주최측은 목적지 체인의 트랜잭션이 revert 되었더라도 다시 실행하면 된다고 하였다. 이 컨테스트를 열 때는 아직 공식적인 방법을 제 공하지 않았던 것 같다. 현재는 Axelar의 익스플로러에서 유저의 지갑을 연결에 목적지 체인에서 트랜잭션을 재시도할 수 있는 방법을 제공한다. • 주최측이 이렇게 설명했지만, 심판은 그래도 문제 자체가 존재하며, 이 시점에는 공식적인 방법이 없었으므로 High로 인정했다.
  • 24. Audit report 분석 • [M-01] Low level call returns true if the address doesn’t exist • Summary • 로우레벨 call은 해당 주소에 컨트랙트가 배포되지 않았다면 revert 되지 않고, true를 리턴한다. • 따라서 로우레벨 call을 하기 전 해당 주소에 컨트랙트가 배포되었는지 확인해야 한다. • Keyword • low level call • Vulnerability • solidity docs를 참고하면 로우레벨 call, delegatecall, staticcall은 해당 주소에 컨트랙트가 배포되지 않았다면 true를 리턴한다 명시한 다. • https://docs.soliditylang.org/en/develop/control-structures.html#error-handling-assert-require-revert-and-exceptions
  • 25. Audit report 분석 • [M-01] Low level call returns true if the address doesn’t exist • Vulnerability • AxelarGateway의 _callERC20Token 함수에서 컨트랙트 배포 여부를 확인하지 않는다. • 또한 AxelarGatewayProxy의 constructor 에서도 확인하지 않는다.
  • 26. Audit report 분석 • [M-01] Low level call returns true if the address doesn’t exist • Impact • 로우레벨 call이 실패했음에도 revert 되지 않는다. • Mitigation • 로우레벨 call을 하기 전에 해당 주소에 컨트랙트가 배포되었는지 확인한다.
  • 27. Audit report 분석 • [M-02] User’s funds can get lost when transferring to other chain • Summary • 도착지 체인 측의 게이트웨이에 토큰이 부족하면 도착지 체인에서 토큰을 줄 수 없고 트랜잭션이 revert 된다. • 출발지 체인에서 유저는 이미 토큰을 burn 또는 transfer 했기 때문에 목적지에서 받지 못하면 자산을 잃게 된다. • Keyword • bridge, cross chain, business logic vul • Vulnerability • 도착지 체인에서 토큰을 줄 때, Axelar wrapped 토큰이 아닌 외부 토큰을 주어야 한다면 게이트웨이에 예치된 토큰을 transfer 한다. • 이 때, 게이트웨이에 토큰이 필요한 만큼 예치되어 있지 않다면 도착지 체인 측 트랜잭션이 revert 될 것이다. • 따라서 출발지 체인에서 유저의 토큰은 burn 또는 transfer 되었지만 도착지에서는 토큰을 받지 못해 유저가 자산을 잃을 수 있다.
  • 28. Audit report 분석 • [M-02] User’s funds can get lost when transferring to other chain • Vulnerability
  • 29. Audit report 분석 • [M-02] User’s funds can get lost when transferring to other chain • Impact • 도착지에서는 토큰을 받지 못해 유저가 자산을 잃을 수 있다. • Mitigation • 목적지 체인에서 토큰을 전송하는데 실패했다면 출발지 체인의 토큰을 반환한다.
  • 30. Audit report 분석 • [M-03] _execute can potentially reorder a batch of commands while executing, breaking any assumptions on command orders • Summary • 재진입을 통해 배치로 처리되는 작업의 실행 순서를 조작할 수 있다. • Keyword • reordering, reentrancy, replay attack, signature • Vulnerability • AxelarGatewayMultisig.execute 함수는 여러가지 커맨드를 배치로 실행한다. • 각 커맨드는 고유한 commandId가 붙어있다. _execute 함수는 기존에 실행했던 commandId를 재시도하는 것을 허용한다 (revert 하지 않는다). • 공격자는 배치 실행되는 커맨드의 실행 순서를 재배열할 수 있다. • 재진입으로 execute 함수를 호출하면 원래 나중에 호출될 커맨드를 먼저 실행할 수 있다. • 이를 통해 컨텍스트에 대한 가정(순서대로 실행될 것이란 가정)을 깨뜨릴 수 있다.
  • 31. Audit report 분석 • [M-03] _execute can potentially reorder a batch of commands while executing, breaking any assumptions on command orders • Impact • 재진입을 통해 커맨드의 실행 순서를 조작할 수 있다. • Mitigation • execute 함수를 재진입 불가하게 한다. 또한 서명을 재전송할 수 없도록 nonce를 추가하라 했다. • Memo • High로 제출했지만 Medium으로 조정되었다. • 주최자 측은 Axelar와 게이트웨이가 명령 실행 순서를 구체적으로 보장하지는 않으므로 순서를 섞는 취약점(reordering)이 논쟁의 여지 가 있다 했다. 이를 악용하는 시나리오가 없기 때문에 Low 또는 non-risk 라고 주장했다. • 심판은 위험도가 높은 문제는 아니지만, 재진입과 서명 재전송이 가능하기 때문에 이를 완화할 필요가 있다고 하며 Medium으로 인정 했다.
  • 32. Audit report 분석 • [M-04] Unsupported fee-on-transfer tokens • Summary • fee-on-transfer 토큰을 고려하지 않았다. 출발지 체인에 실제로 예치된 토큰보다 많은 양의 토큰을 목적지 체인에서 받을 수 있다. • Keyword • fee-on-transfer token, erc20 • Vulnerability • 출발지 체인에서 토큰을 이동할 시, 외부 토큰을 이용한다면 유저의 토큰을 transferFrom으로 게이트웨이에 예치한다. • fee-on-transfer 토큰은 transfer 할 때 수수료를 뗀다. 따라서 실제로 게이트웨이에 예치되는 토큰은 요청한 것보다 적어진다.
  • 33. Audit report 분석 • [M-04] Unsupported fee-on-transfer tokens • Impact • 실제로 예치된 토큰보다 많은 토큰을 목적지 체인에서 받을 수 있다. • Mitigation • 목적지 체인에서 토큰을 보내줄 때, 수수료를 제한 만큼(실제로 예치된 만큼) 보낸다.