PoCs

코드는 맞았고 배치가 틀렸다

공격자가 **스토리지 슬롯 충돌**로 Enjin의 관리자 권한을 탈취해 약 **16만 2천 달러**를 빼갔습니다 — 어댑터들과 그것을 관리하는 컨트랙트가 **같은 저장 공간을 다른 의미로** 썼습니다. **개별 함수는 전부 올바랐습니다.** 결함은 **모듈들 사이의 공간**에 있었습니다.

아직 만들지 않았습니다

이 페이지는 카드에 적힌 내용을 펼쳐 보여줄 뿐입니다 — 돌아가는 코드도, 열어볼 데모도 아직 없습니다. 무엇을 왜 만들려는지가 아래에 있습니다.

어떻게 보나

아직 범위 미정 — 첫 작업은 감사가 아니라 **목록 만들기**입니다. **다른 컨트랙트의 스토리지 문맥에서 코드가 실행되는** 시스템이라면, 그런 모듈을 전부 나열하고 각각의 스토리지 레이아웃을 계산해, **어느 두 모듈도 같은 슬롯을 다른 의미로 주장하지 않는다**를 단언합니다. 레이아웃 대조 도구는 이미 있지만 **업그레이드 시 한 컨트랙트의 연속된 버전**을 겨냥합니다 — 여기서의 빈틈은 **꽂아 넣는 어댑터 집합은 버전의 연속이 아니라서** 아무도 검사하지 않는다는 것입니다. 더 싼 두 번째 작업: **관리자 주소는 관리자 변경 트랜잭션 안에서만 바뀔 수 있다**는 불변식을 쓰고, 지금이라면 무단 변경이 **얼마나 오래 눈에 띄지 않을지**를 재는 것. 출처: SlowMist(X), 디지털애셋 2026-08-26 — 약 16만 2천 달러 탈취, ENJ 6.39% 하락해 $0.02625, 보도 시점 Enjin 입장 없음. 사후 보고서가 나오면 확인할 것.

기술 노트

각 항목이 실제로 무엇을 보여주고 어떻게 동작하는지 — 위 카드보다 자세한 기술 설명입니다.

코드는 맞았고 배치가 틀렸다준비 중

목적: **아무것도 고장 나지 않았습니다.** revert 도 없고, assertion 실패도 없고, 키 유출도 없고, **개별적으로 틀린 코드 한 줄도 없습니다.** 두 모듈이 **같은 스토리지 슬롯에 서로 다른 의미로** 썼고, 그 의미 중 하나가 하필 ***누가 관리자인가*** 였습니다. **파일 하나를 아무리 꼼꼼히 읽어도 아무것도 못 찾는** 버그 종류입니다 — 결함이 파일 안에 있지 않고 **파일들 사이의 관계**에 있으며, **조합된 뒤에야 존재**하기 때문입니다. **어댑터 패턴의 대가가 사건 하나로 진술된 것입니다.** Enjin의 설계는 **호스트의 일부로 실행되는 별도 프로그램**을 연결합니다. 바로 그것이 시스템을 확장 가능하게 만듭니다 — 코어를 재배포하지 않고 기능 추가. 같은 메커니즘이 뜻하는 것은 **추가되는 모든 모듈이 하나의 공유 주소 공간에 대한 또 하나의 주장**이라는 것입니다. **확장성과 스토리지 안전성은 서로 정면으로 잡아당기고**, 어댑터가 늘수록 그 힘이 세집니다 — 플러그인 추가를 생각하는 보통의 방식과 **정반대**입니다. **도구의 빈틈은 구체적이고 이름 붙일 값이 있습니다.** 스토리지 레이아웃 검사는 **업그레이드에 대해서는** 풀린 문제입니다 — 한 컨트랙트의 버전 N과 N+1을 비교해 불일치를 거부합니다. **어댑터 집합은 버전의 연속이 아닙니다.** 하나의 레이아웃을 공유하는 **동료들의 집합**이고, *이 중 어느 둘이 슬롯 k에 대해 의견이 다른가* 라는 **쌍별 질문**은 표준 도구가 겨냥하는 것이 아닙니다. 그러니 실패는 기법이 없어서가 아닙니다. **기법이 같은 문제의 다른 모양을 겨냥하고 있어서**입니다. **그리고 이건 그것을 위해 쓴 줄에 정확히 떨어집니다.** `plumbing-skills-buyback` 은 감시가 **아무도 지켜보지 않아도 도는 코드**여야 한다고 적었고, *관리자 주소가 관리자 변경 트랜잭션 밖에서 바뀌었다* 는 온체인 불변식 중 가장 단순한 축입니다. 여기 피해는 16만 2천 달러로, **싸게 배우는 교훈**이 될 만큼 작습니다. **같은 버그 종류가 정산 컨트랙트 아래에 있으면 그렇지 않습니다.** `governance-capture-cost` 는 **시장가 주문처럼 보이는** 익스플로잇을 찾았고, 이건 **스토리지 쓰기처럼 보입니다.** **둘 다 절차적으로 평범하기 때문에 모든 검사를 통과하는 공격입니다.**

동작 방식: ### 왜 파일 하나를 리뷰해서는 못 찾는가 | 층위 | 리뷰어에게 보이는 것 | 결함이 실제로 있는 곳 | |---|---|---| | **어댑터 하나** | 올바른 코드, 합리적인 변수 | **없음** — 단독으로는 문제없음 | | **관리 컨트랙트** | 올바른 코드, admin 변수 | **없음** — 이쪽도 단독으로는 문제없음 | | **둘을 조합한 것** | **어떤 파일에도 표현되지 않음** | **둘 다 슬롯 k를 주장하고, 한쪽 의미가 `admin`** | | **익스플로잇 트랜잭션** | 평범한 상태 변경 호출 | 관리자를 재지정하는 그 쓰기 | ### 검사 둘, 비용 순서로 **싸고 즉시 — 불변식.** *관리자 주소는 관리자 변경 트랜잭션 안에서만 바뀐다.* 한 줄, 새 인프라 없음, 이 종류를 사후에 정확히 잡고, **모든 시스템이 이미 답할 수 있어야 하는 질문**에 답합니다 — **여기서 무단 관리자 변경은 얼마나 오래 눈에 안 띄는가.** 탐지는 **외부 보안 업체**에서 왔고 보도 시점까지 입장이 없었습니다 — **그 자체가 이 시스템의 답**입니다. **구조적 — 쌍별 레이아웃 단언.** 호스트의 스토리지 문맥에서 실행되는 모든 모듈을 나열하고, 각 레이아웃을 계산해, **어느 둘도 같은 슬롯에 다른 의미를 주지 않는다**를 단언합니다. 도구는 있지만 **동료 집합이 아니라 업그레이드 연속**을 겨냥하므로, **일의 대부분은 발명이 아니라 겨냥을 바꾸는 것**입니다. ### 남겨 둘 일반화 **공유된 가변 주소 공간은 조합 버그의 가장 오래된 원천**이고, 체인이 그걸 새롭게 만들지 않습니다 — **비싸고 공개적으로** 만들 뿐입니다. 남의 스토리지 문맥에서 코드가 돌게 하는 모든 설계가 이걸 물려받습니다 — 프록시, delegatecall 모듈, 플러그인 시스템, 다이아몬드 패싯, 훅 아키텍처. 안전성 질문은 결코 *이 모듈이 올바른가* 가 아니라 ***이 모듈이 메모리의 의미에 대해 다른 모든 모듈과 합의하는가*** 이고, **누군가를 지정해 두지 않으면 그 질문에는 주인이 없습니다.** ### 피해액을 정직하게 읽기 16만 2천 달러 탈취, ENJ 6.39% 하락. **토큰 움직임은 과대 해석하지 말아야 할 부분**입니다 — 소형주에 6%는 정상 범위 안이므로 **피해의 측정치가 아니라 동시에 일어난 사실**입니다. 중요한 숫자는 아무도 발표하지 않는 쪽입니다 — **그 공간을 공유한 어댑터가 몇 개였고, 남은 것 중 몇 개를 사후에 점검했는가.**