배경 소개
최근 우리는 Arbitrum 체인에 대한 공격을 감지했습니다.
https://arbiscan.io/tx/0xb91c4e0debaf0feb1f20c979eebc1282c8024ae299ef5903591badcf1f4938bb
공격을 받은 프로젝트는 Ramses Exchange 였으며, 공격으로 인해 총 약 27 ETH, 약 70,000 USD의 손실이 발생했습니다. Ramses는 Arbitrum에서 출시된 새로운 분산형 자동화 시장 메이커(AMM)입니다. 프로토콜은 RAM 토큰과 veNFT를 통해 작동합니다.
공격 및 사고 분석
이 공격은 두 개의 트랜잭션으로 나누어집니다. 첫 번째 트랜잭션은 사전 작업이며 트랜잭션 해시는 다음과 같습니다.
https://arbiscan.io/tx/0xa0795952a09f4aeaacf0abb213dedeaa7b7dd71c04eaa3fd22db33957e1c724c, 우리는 이를 트랜잭션 A라고 부릅니다.
두 번째 트랜잭션은 정식 공격 트랜잭션이며 트랜잭션 해시는
https://arbiscan.io/tx/0xb91c4e0debaf0feb1f20c979eebc1282c8024ae299ef5903591badcf1f4938bb, 우리는 이를 트랜잭션 B라고 부릅니다.
거래 A의 주요 활동:
먼저, 공격자는 예금을 사용하여 0.0001 ETH를 WETH로 교환합니다.
그런 다음 공격자는 Ramses Exchange를 사용하여 0.0001 WETH를 RAM으로 교환했습니다.
마지막으로 공격자는 create_lock을 사용하여 RAM 1개를 잠그고 잠금 자격 증명으로 ID가 18785(공격에 사용됨)인 veNFT를 획득했습니다.
거래 B의 주요 활동:
공격자는 먼저 Ramses Exchange 전체 풀의 WETH 잔액을 확인했고,
그리고 플래시론을 이용하여 uniswapV3에서 12.2 WETH를 빌렸습니다.
그 후, 공격자는 Ramses의 뇌물 메커니즘을 사용하여 WETH 잔액과 동일한 WETH를 각 풀로 전송합니다(나중에 풀에서 모든 WETH를 인출하기 위해).
그런 다음 공격자는 투표를 통해 해당 트랜잭션 풀에 투표합니다.
다음으로 공격자는 getPeriodReward를 통해 투표 인센티브를 획득하고,
getPeriodReward의 구체적인 구현을 살펴보겠습니다.
공격자는 공격 트랜잭션 A에서 ID 18785의 veNFT를 획득했으므로 IVotingEscrow(_ve).isApprovedOrOwner(msg.sender, 18785)는 true입니다. 다음으로, 다음과 같이 _getReward 코드를 볼 수 있습니다.
그런 다음 공격자는 재설정을 사용하여 위 거래 풀에 대한 투표를 철회했습니다.
그런 다음, 분할을 사용하여 ID가 18785인 veNFT의 0.99999 RAM을 ID가 18787인 새로운 veNFT로 분할합니다. 취약점은 여기에 있습니다. 공격자가 분할을 사용하여 새로운 veNFT를 분할하면 이 잠금에 있는 자금이 이미 보상을 받았는지 확인하지 않고도 잠금에 해당하는 RAM을 사용하여 투표하고 보상을 얻을 수 있습니다. 따라서 공격자는 반복적으로 재설정을 사용하여 투표를 재설정한 다음 분할을 사용하여 새 veNFT를 분할한 다음 투표를 사용하여 투표하고 마지막으로 getPeriodReward를 사용하여 투표 보상을 얻을 수 있습니다.
공격자는 USDC와 ARB에 해당하는 거래쌍에 대해서도 동일한 공격을 수행했습니다.
요약
이 취약점의 원인은 Ramses Exchange가 Lock RAM에 해당하는 보상을 발행할 때 Locked 자금이 보상을 받았는지 확인하지 않았기 때문입니다. 결과적으로 공격자는 재설정 및 분할을 사용하여 veNFT를 분할하고 반복적으로 보상을 받을 수 있습니다. 프로젝트 당사자는 경제 모델 및 코드 운영 논리를 설계할 때 다자간 검증을 수행하고 계약이 온라인화되기 전에 교차 감사를 위해 여러 감사 회사를 선택하는 것이 좋습니다.