업그레이드 가능한 스마트 계약은 사용자가 호출하는 프록시 주소와 상태 저장소를 유지하면서 delegatecall로 실행할 구현 주소를 바꿉니다. 버그 수정이 가능하지만 업그레이드 관리자와 프록시 설계가 코드 규칙을 바꿀 권한을 가지므로 구현 주소, 관리자, 타임록, 초기화·저장 레이아웃을 함께 확인해야 합니다.
주소는 그대로인데 실행 코드는 바뀔 수 있다
사용자는 프록시 주소로 거래를 보낸다. 프록시 fallback은 calldata를 구현 계약에 delegatecall해 구현 코드를 프록시의 저장소·잔액·호출 문맥에서 실행한다. 구현 주소를 바꾸면 같은 토큰 주소와 상태를 유지한 채 동작을 변경할 수 있다.
OpenZeppelin Proxy docs는 ERC1967Proxy, Transparent, UUPS, Beacon 패턴을 구분한다. 프록시 주소의 검증 소스만 읽고 끝내면 실제 비즈니스 로직을 놓칠 수 있다.
탐색기 Proxy 표시는 편의 탐지다. 직접 EIP-1967 구현 슬롯과 이벤트를 확인하고, 구현이 다시 다른 프록시나 다이아몬드 구조를 가리키는지 본다.
| 패턴 | 업그레이드 로직 위치 | 핵심 확인 |
|---|---|---|
| Transparent Proxy | 프록시·ProxyAdmin | admin과 사용자 호출 분리 |
| UUPS | 구현 계약 | _authorizeUpgrade와 UUPS 호환성 |
| Beacon Proxy | 공유 Beacon | 한 변경이 여러 프록시에 영향 |
| 비업그레이드 ERC1967 | 구현 슬롯은 있으나 변경 인터페이스 없음 | 실제 변경 가능 경로 |
| Custom/Diamond | 별도 라우팅·facet | 표준 탐지 한계·선택자 매핑 |
EIP-1967 슬롯은 충돌을 줄이지 권한을 없애지 않는다
프록시 저장소와 구현 저장 변수가 같은 슬롯을 쓰면 상태가 깨질 수 있다. ERC-1967은 구현·beacon·admin 주소를 일반 컴파일러 배치와 충돌하기 어려운 특정 슬롯에 저장하고 변경 이벤트를 권고한다.
표준 슬롯을 쓴다고 업그레이드가 안전해지는 것은 아니다. 누가 슬롯을 바꿀 함수를 호출할 수 있는지, admin이 멀티시그인지, 타임록과 비상 우회가 있는지 확인해야 한다.
Transparent와 UUPS의 권한 위치가 다르다
Transparent 프록시는 관리자 호출을 업그레이드 인터페이스로 처리하고 일반 사용자는 구현에 위임한다. admin이 일반 구현 함수를 호출하지 못하게 분리해 함수 선택자 충돌을 줄인다. 보통 별도 ProxyAdmin이 여러 프록시를 관리할 수 있다.
UUPS는 업그레이드 함수가 구현 계약에 있고 ERC1967Proxy는 위임만 한다. 구현의 _authorizeUpgrade가 핵심 접근 통제다. 잘못된 새 구현이 업그레이드 기능을 제거하거나 권한 검사를 약화할 수 있어 호환성 검사와 롤백 계획이 필요하다.
초기화 함수는 생성자보다 노출되기 쉽다
프록시 문맥에서는 구현 생성자가 프록시 저장소를 초기화하지 않는다. 외부 initialize 함수를 사용하고 한 번만 실행되도록 보호한다. 배포와 초기화를 분리하면 공격자가 먼저 initialize를 호출해 소유권을 가져갈 수 있다.
프록시 생성자의 _data에 초기화 호출을 넣어 원자적으로 배포·초기화하는 방법이 있다. 구현 계약 자체도 초기화되지 않은 채 남으면 직접 호출이나 특정 공격 표면이 생길 수 있어 구현 잠금 패턴을 확인한다.
- 프록시·구현·admin/beacon 주소 확인
- Upgraded·AdminChanged 이벤트 이력 확인
- 관리자 임계값·타임록·비상 우회 확인
- initializer 실행 상태와 재초기화 버전 확인
- 새·이전 구현 저장 레이아웃 비교
저장 레이아웃은 업그레이드의 숨은 호환성 계약이다
기존 변수 순서나 타입을 바꾸면 같은 슬롯의 과거 값이 새 의미로 해석될 수 있다. 상속 순서 변경과 struct 수정도 슬롯 배치를 바꾼다. 새 변수는 호환되는 위치에 추가하고 자동 레이아웃 검사를 사용한다.
검사 도구 통과가 비즈니스 의미 호환을 보장하지 않는다. 단위·소수점·역할 ID·회계 공식이 바뀌면 데이터 형이 같아도 상태 해석이 달라질 수 있다. 마이그레이션 함수의 재실행 방지와 실패 시 복구를 검토한다.
업그레이드 가능한 계약의 현재 코드는 규칙의 전부가 아니라 누가 다음 코드를 선택할 수 있는지까지 포함한다.
JOBCOIN 해설
온체인에서 현재 구현과 지연을 검증한다
탐색기의 Read as Proxy 기능과 raw storageAt 조회로 구현 슬롯을 대조한다. 구현 코드 해시와 검증 소스·컴파일러 설정을 확인하고 공식 저장소 릴리스와 비교한다. admin 주소가 계약이면 그 계약의 소유자·역할을 다시 따라간다.
타임록은 예정된 operation의 대상, calldata hash, ETA, 실행 이벤트를 확인한다. 문서에 48시간 지연이라고 적혀 있어도 긴급 역할이 즉시 업그레이드하거나 프록시를 정지할 수 있는지 본다.
감사 보고서는 특정 구현 커밋과 범위를 다룬다. 현재 프록시 구현이 감사된 커밋과 같은지, 이후 업그레이드와 초기화가 포함됐는지 확인한다. ‘audited’ 배지만으로 현재 코드를 보증하지 않는다.
자주 묻는 질문
프록시 계약이면 위험한가요?
버그 수정 장점과 관리자 위험이 함께 있습니다. 패턴 자체보다 권한, 지연, 저장 호환성과 변경 이력을 확인해야 합니다.
탐색기 소스 검증 배지가 있으면 현재 로직이 맞나요?
프록시 소스만 검증됐을 수 있습니다. 현재 구현 주소와 그 바이트코드·소스 대응을 별도로 확인하세요.
타임록이 있으면 악성 업그레이드를 막나요?
검토·탈출 시간을 주지만 비상 우회, 관리자 변경, 실제 출금 시간에 따라 보호가 달라집니다.



