codehawks-2023-07-codehawks-escrow-contract-m03
[M-03] Funds can be lost if any participant is blacklisted
Summary
블락리스트 기능이 있는 토큰을 이용하는 경우, 참여자 중 하나가 블락되면 토큰을 분배할 수 없다.
Keyword
blocklisting token, erc20, asset lock, dos
Vulnerability
이 프로젝트는 WETH, USDC, LINK, DAI 등의 토큰을 이용한다고 했다. 이 중 USDC 토큰은 토큰 자체에 블락리스트 기능이 있다. 이외에 많은 유명한 토큰들이 블락리스트 기능을 이용한다.
다음은 USDC 토큰 함수이다. notBlacklisted modifier로 인해 호출자 또는 토큰을 주고받는 이들이 블락된 경우 거래할 수 없다.
function transferFrom(
address from,
address to,
uint256 value
)
external
override
whenNotPaused
notBlacklisted(msg.sender)
notBlacklisted(from)
notBlacklisted(to)
returns (bool)
{...}Escrow에 예치된 토큰이 움직이는 시나리오는 두가지 있다.
confirmReceipt함수를 이용해 거래 성립. 구매자가 미리 컨트랙트에 예치해둔 토큰을 판매자에게 전송함.- 분쟁이 발생한 경우 중재자가
resolveDispute함수를 호출해 분배. 중개자는 수수료를 받고 판매자, 구매자에게 토큰을 분배해준다.
confirmReceipt의 경우 판매자, 구매자 주소 중 하나라도 토큰의 블락리스트에 올랐다면 토큰을 옮길 수 없어 프로토콜이 정상적으로 작동하지 않는다. resolveDispute의 경우 중재자 주소까지 포함된다.
일반적으로 불법활동에 참여한 계정은 블락되고, 단순히 토네이도 캐시를 이용한 것으로 블락되기도 한다. 불만을 품은 참여자(판매/구매/중재자)가 토네이도 캐시 등을 이용해 의도적으로 자신을 블락리스트에 올려 자금 분배를 차단하는 시나리오도 충분히 가능하다.
Impact
참여자중 하나가 블락리스트에 오르면 토큰을 옮길 수 없어 자금이 영원히 잠기게 된다.
Mitigation
confirmReceipt와resolveDispute함수에서 바로 토큰을 옮기는 대신, 각 참여자가 가져갈 수 있는 토큰 양을 상태 변수에 저장해둔다. 이후 각자가 토큰을 인출해가면 블락된 참여자 외 나머지는 분배받을 수 있다.- 또는 블락된 유저가 출금할 수 없는 문제를 해결하기 위해 토큰을 분배할 주소를 재설정하는 기능을 제공한다.
Memo
불만을 품은 참여자가 토네이도 캐시 등을 이용해 의도적으로 자신을 블락리스트에 올려 DoS한다는 공격 시나리오 아이디어가 괜찮다.
tags: bughunting, codehawks, smart contract, solidity, blocklisting token, erc20, dos, asset lock, severity medium