원문: EIP-7702 업그레이드 보안: EOA에서 스마트 지갑으로의 안전한 전환을 위한 프록시 패턴
원저자: Amie Corso
원문 번역: Foresight News
EIP-7702는 일반 이더리움 지갑(EOA)을 스마트 계약 지갑으로 업그레이드하여 더욱 강화된 보안, 고급 기능, Gas 후원 기회 및 기타 이점을 제공합니다. 과거에는 스마트 지갑을 처음부터 개발해야 했지만, EIP-7702가 도입되면서 기존 지갑도 업그레이드하여 모든 자산과 온체인 기록을 그대로 유지하면서 동일한 지갑 주소를 유지할 수 있습니다. 마치 새 번호 없이 유선 전화에서 스마트폰으로 바꾸는 것과 같습니다.
EOA는 위임 스마트 계약을 가리키는 "위임 지정"을 설정하여 업그레이드됩니다. 위임 지정은 스마트 계약의 로직을 위임하여 EOA를 관리합니다. 결과적으로 업그레이드된 EOA는 스마트 계약이 수행할 수 있는 모든 기능을 포함하고, 저장소를 설정하고, 이벤트를 발생시키고, 스마트 계약이 수행할 수 있는 모든 작업을 수행할 수 있습니다. EOA는 새롭게 서명된 EIP-7702 권한을 통해 언제든지 이 위임을 변경하거나 제거할 수 있습니다. 이는 많은 새로운 가능성을 열어주지만, 이 강력한 기능은 신중한 고려와 혁신적인 솔루션이 필요한 새로운 보안 문제를 야기합니다.
EOA가 스마트 계약 지갑 역할을 할 수 있도록, EOA의 EIP-7702 위임으로 사용하도록 설계된 경량 ERC-1967 프록시 계약인 EIP7702Proxy를 개발했습니다. 프록시에서 실행되는 기본 로직 전달 외에도 EIP7702Proxy는 EIP-7702 위임 계정의 고유한 몇 가지 문제를 해결하는 다른 기능과 설계 옵션을 포함하고 있습니다. EIP7702Proxy를 설계하는 한 가지 목표는 "표준으로 배포된" Coinbase Smart Wallet과 EIP-7702 위임 Coinbase Smart Wallet 간의 동등성을 최대한 유지하는 것입니다. 즉, EIP-7702 메커니즘에 필요한 추가적인 복잡성을 전용 프록시로 추상화하고 CoinbaseSmartWallet의 기존 구현을 계속 사용하는 것을 의미합니다. 이 문제에 대한 해결책은 CoinbaseSmartWallet 구현뿐만 아니라 모든 구현 로직에 효과적으로 적용할 수 있으며, 7702 지원 환경에서 EOA의 보안을 유지하는 데에도 도움이 됩니다.
아래에서는 EIP-7702 업그레이드에 맞춰 기존 스마트 계약 지갑 구현을 안전하게 수정할 수 있도록 하는 구체적인 과제와 해당 설계 솔루션을 설명합니다.
EIP-7702 구현의 첫 번째 주요 장애물은 초기화 제약 조건입니다. 기존 스마트 계약 지갑(CoinbaseSmartWallet 포함)은 일반적으로 배포 과정에서 별도의 팩토리 계약을 통해 보안 초기화(계정 소유권 설정)를 원자적으로 처리합니다. 이러한 원자성으로 인해 이러한 구현에는 한 번만 호출될 수 있는 보호되지 않은 초기화 함수가 많이 있습니다. 그러나 EIP-7702의 설계는 코드 위임 프로세스("배포"에 해당하는 단계) 중에 초기화 호출 데이터를 수행할 수 없도록 설계되어 있어 원자적으로 수행할 수 없습니다.
이러한 단계 분리는 심각한 취약점 발생 가능성을 야기합니다. 구현 계약이 EIP-7702를 통해 EOA에 "배포"될 때, 이 7702 업그레이드 및 지갑 초기화를 위한 표준 EVM 트랜잭션이 원자적으로 실행된다는 보장은 없습니다. 기술적으로, 권한을 설정하는 코드는 초기화 트랜잭션과 동시에 제출되더라도 독립적으로 적용될 수 있으며, 이는 공격자가 초기화 트랜잭션을 선제적으로 실행하고 스마트 계정의 소유권을 주장할 수 있도록 허용합니다.
해결책: EOA 서명을 통해 구현을 원자적으로 설정하고 초기화하도록 요구
기존 Coinbase Smart Wallet은 UUPSUpgradeable 구현(실제 CoinbaseSmartWallet 로직)을 사용하는 ERC-1967 프록시 뒤에 배포됩니다. 실제 계정 주소의 코드는 ERC-1967에 정의된 일반적인 저장 위치를 사용하여 구현 로직에 대한 포인터를 저장하는 프록시입니다. 7702와 관련된 초기화 취약점에 대한 저희의 해결책은 모든 구현 로직이 프록시가 실제로 연결을 설정할 때만 활성화(따라서 위험)된다는 점을 인식하는 것입니다. 따라서 원자적 배포 및 초기화를 강제할 수 없는 경우, 원자적 구현 설정 및 초기화를 강제할 수 있습니다.

EIP-7702CoinbaseSmartWallet 계약 아키텍처 및 논리적 위임 프로세스
EIP-7702 맥락에서 EOA 자체는 계정 변경을 수행하는 최초 권한자이며, 모든 소유자에게 새로운 스마트 계정을 초기화하고 설정할 수 있는 권한을 부여하는 서명을 제공해야 합니다. EIP7702Proxy 계약은 새로운 논리 구현을 원자적으로 설정하고 계정을 초기화하는 setImplementation 함수를 구현합니다. setImplementation 함수는 다음과 같습니다.
새로운 구현 계약의 주소, 초기화 호출 데이터, 최종 계정 상태의 안전성을 평가할 검증자 계약의 주소, 그리고 nonce 및 만료 시간과 같은 기본 서명 재생 보호와 같은 주요 데이터를 포함하는 EOA의 서명을 검증합니다.
ERC-1967 지표 값을 새로운 구현으로 설정하고 제공된 호출 데이터를 새로운 논리 구현에 대해 실행합니다. 서명에 포함된 검증자가 구현해야 하는 validateAccountState 함수를 호출합니다. 검증자는 최종 계정 상태가 안전한지 여부를 평가하는 로직을 포함하는 구현별 계약입니다. 예를 들어, CoinbaseSmartWallet의 경우, CoinbaseSmartWalletValidator는 계정의 소유권 상태가 null이 아닌지 확인하여 임의 초기화에 더 이상 취약하지 않은지 확인합니다.
EIP-7702의 가장 복잡한 과제는 스토리지 관리와 관련이 있습니다. EOA는 언제든지 로직을 다른 계약에 다시 위임하거나 위임을 완전히 제거할 수 있습니다. 모든 위임은 EOA 주소에서 동일한 스토리지 공간을 공유합니다. 시간이 지남에 따라 여러 계약이 동일한 스토리지에 대한 액세스를 공유하면 "스토리지 충돌" 문제가 발생할 수 있습니다. 스토리지 충돌은 두 계약이 동일한 스토리지 위치에 대해 서로 다른 변경 사항을 적용하거나 서로 다른 가정을 할 때 발생하며, 이로 인해 예측할 수 없는 오류가 발생할 수 있습니다.
저장소 충돌 관리는 공유 저장소를 관리하기 위해 변경 가능한 구현 로직을 사용하는 프록시 설계 분야에서 이미 익숙한 문제입니다. 업그레이드 가능한 프록시는 구현을 변경할 수 있지만, 프록시 코드 자체(7702 주소가 아닌 경우)는 변경할 수 없습니다. 이는 업그레이드 프로세스에 결정성과 안정성을 제공합니다. 7702 재위임은 이 공유 저장소를 관리하는 기본 로직에 완전한 가변성을 제공하는 또 다른 계층을 도입합니다. 이는 임의 위임이 저장소에 미칠 수 있는 영향에 대한 모든 안정성을 근본적으로 제거합니다. 예를 들어, EOA가 A 대리자에서 B로, 그리고 다시 A로 위임하는 경우, 반환되는 대리자는 저장소 상태에 대해 가정할 수 없으며, B 대리자가 저장소를 삭제했거나 대리자 A의 로직만으로는 달성할 수 없는 상태로 조작했을 수 있습니다. 이는 위임 모드와 관계없이 모든 7702 위임에 해당합니다. 이전 위임이 모든 저장소 위치에 무언가를 저장하거나 삭제했을 수 있기 때문입니다.
A → B → A 위임 패턴으로 인해 위임자 A의 유효하지 않은 상태 발생 사례

해결책: 보안에 중요한 저장 값의 외부화
EOA 위임은 계정 상태에 임의로 영향을 미칠 수 있습니다. EOA가 악의적이거나 파괴적인 계약에 위임된 경우, 어떤 현직 위임자도 이러한 시나리오를 방지할 수 없습니다. 드레인 트랜잭션 서명과 마찬가지로, 악의적인 7702 위임을 승인하는 것은 치명적인 결과를 초래할 수 있으며, 이러한 결과로부터 보호하는 것은 본 설계의 범위를 벗어납니다. EXIP7702Proxy는 선의를 가지고 있지만 잠재적으로 혼란스러운 참여자들로 구성된 다중 지갑 7702 기반 생태계에서 예측 가능한 문제에 대해 자체 방어 기능을 제공하도록 설계되었습니다. 실제로 악의적이거나 버그가 있는 위임을 승인하는 EOA로부터는 보호할 수 없습니다.
예상 가능한 문제 중 하나는 setImplementation 호출 서명과 변경 가능한 계정 상태로 인한 위험입니다. EIP7702Proxy는 EOA 서명을 사용하여 구현 로직을 설정하고 안전한 상태로 초기화합니다. 이러한 서명이 재사용될 수 있다면 문제가 될 수 있습니다. 예를 들어, 서명이 초기 소유자에게 권한을 부여했지만 나중에 침해되어 삭제된 경우, 재생 가능한 서명은 침해된 소유자를 재생성하거나 구현을 다운그레이드할 수 있습니다.
서명 재사용을 방지하는 일반적인 방법은 서명 메시지에 nonce를 사용하고 검증 후 사용됨으로 표시하는 것입니다. 7702 계정에 대한 위험: 다른 위임이 이 nonce 추적 저장소를 손상시킬 수 있습니다. 저장소 추적 nonce 사용이 삭제되면 EOA의 setImplementation 서명(mempool에서 공개적으로 사용 가능)이 EIP7702Proxy로 다시 위임될 때 다시 적용될 수 있습니다.
서명이 재생되지 않도록 하기 위해 계정 저장소 외부의 변경 불가능한 계약 위치에 nonce 상태를 유지하는 별도의 NonceTracker 싱글턴을 구현했습니다. EOA만 nonce에 영향을 미칠 수 있으며(점진적으로만), 다른 위임이 이러한 보안 중요 값을 조작하는 것을 방지합니다. NonceTracker는 계정 저장소에 어떤 일이 발생하든 각 setImplementation 서명이 한 번만 작동하도록 보장합니다.
ERC-1967에서 정의한 것과 같은 표준 스토리지 슬롯은 여러 대리자 구현에서 사용할 수 있는 일반적인 위치이기 때문에 잠재적인 스토리지 충돌에 특히 취약합니다. ERC-1967 구현 슬롯은 EIP7702Proxy에서 사용되는 유일한 표준 스토리지 위치이며, 프록시가 가리키는 로직 구현의 주소를 저장합니다. 저희 설계는 이 스토리지 위치의 값(계정에서 사용 가능한 로직의 대부분을 결정함)에 관계없이 EIP7702Proxy가 항상 EOA에서 기대하는 계약에 구현 로직을 성공적으로 설정할 수 있도록 보장합니다.
해결 방법을 더 명확하게 설명하기 위해, 계정이 서로 다른 대리자(A→B→A) 간에 전환되고 두 대리자 모두 ERC-1967 프록시 패턴을 구현할 때, 대리자 B는 자연스럽게 대리자 A가 구현 주소를 저장하는 데 사용하는 것과 동일한 스토리지 슬롯을 사용합니다. 대리자 B는 작업 기간 동안 의도적으로 또는 자체 프록싱의 정상적인 일부로 이 슬롯을 수정하거나 덮어쓸 수 있습니다. UUPSUpgradeable 프록시 패턴에서 구현을 업그레이드하는 로직은 구현 계약 자체에 정의됩니다. 대리자 B가 이 포인터 위치에 배치한 구현에 해당 구현에 예상되는 upgradeToAndCall 인터페이스가 포함되어 있지 않으면, 대리자 A로 돌아갈 때 현재 사용 가능한 로직에 구현을 변경하는 메커니즘이 존재하지 않을 수 있습니다.
공유 레거시 저장소 위치를 덮어쓰는 새 대리자의 예

해결책: EIP7702Proxy에서 업그레이드 메커니즘 사용 가능
EIP7702Proxy는 구현에 독립적인 업그레이드 메커니즘을 프록시 자체에 직접 제공하는 setImplementation 함수를 통해 이 문제를 해결합니다. 이를 통해 중간 대리자가 ERC-1967 구현을 잘못된 구현으로 가리키거나 완전히 제거한 경우에도 EIP7702Proxy로 다시 위임한 후 원래 EOA는 프록시의 ERC-1967 포인터를 재구성하여 선택한 논리적 구현을 가리킬 수 있는 기능을 유지합니다.
EIP7702Proxy의 설계 목표 중 하나는 새로운 스마트 계약 기능 외에도 계정 EOA 기능과의 하위 호환성을 유지하는 것이었습니다. 주소에 코드가 있는지 없는지는 해당 주소와 상호 작용하는 프로토콜의 실행 흐름에 영향을 미치는데, 프로토콜은 이 특징을 사용하여 EOA와 스마트 계약을 구분하기 때문입니다. 고려해야 할 주요 동작은 서명 검증과 토큰 수신 동작, 두 가지입니다.
스마트 계약의 서명 검증 표준은 표준 EOA의 서명 검증 표준과 다릅니다. 스마트 계약은 ERC-1271에서 정의한 isValidSignature 인터페이스를 구현하며, 계약에서 서명의 유효성을 판단하는 임의의 로직을 자유롭게 정의할 수 있습니다. 표준 EOA의 경우, 서명은 표준 ecrecover 검사를 통해 검증되며, 이를 통해 서명자가 예상 EOA 주소로 복귀하는지 확인합니다.
7702 업그레이드 후에도 기존 또는 향후 EOA 서명이 EOA에서 계속 인식되도록 EIP7702Proxy는 isValidSignature 버전을 구현합니다. 이 버전은 먼저 서명 검증을 로직 구현에 정의되어야 하는 isValidSignature 함수에 위임합니다. 검증이 실패하면 최종 ecrecover 검사를 수행합니다. 이 검사가 통과되면 서명은 유효한 것으로 간주됩니다. 이러한 방식으로 EIP7702Proxy를 사용하는 EOA는 스마트 계약 지갑의 isValidSignature 구현 여부와 관계없이 간단한 EOA 서명이 항상 해당 주소에서 인식되도록 보장할 수 있습니다.
일부 토큰 표준(특히 ERC-1155 및 ERC-721)은 토큰을 관리할 수 없는 스마트 계약에 토큰이 묶이는 것을 방지합니다. 이러한 토큰은 토큰을 수신하는 모든 스마트 계약이 토큰 전송 중에 토큰 계약에서 호출하는 표준 토큰 수신자 인터페이스를 구현하여 이러한 기능을 알리도록 요구합니다. 업그레이드된 EOA의 로직에 네이티브 토큰을 수신할 수 있는 표준 수신 함수 또는 지불 가능한 폴백을 포함하는 것도 중요합니다. 계정은 단기간이라도 ETH 또는 기타 토큰을 수신할 수 없는 상태로 방치되어서는 안 됩니다.
프록시에는 초기 구현이 없으므로, ERC-1967 지표가 없는 경우 EIP7702Proxy의 기본 로직으로 변경 불가능한 DefaultReceiver 구현을 포함했습니다. 이 수신기는 이러한 공통 토큰에 대한 수신 함수와 표준 수신기 후크를 구현하여 계정이 새로운 구현을 명시적으로 설정하기 전에 토큰 전송을 수락할 수 있도록 보장합니다.
EIP7702Proxy 설계를 통해 표준 배포된 CoinbaseSmartWallet과 긴밀하게 협력하면서 기존 CoinbaseSmartWallet 구현을 계속 사용하는 동시에 EIP-7702와 관련하여 발생하는 고유한 보안 문제를 해결할 수 있습니다. 초기화 보안, 스토리지 시간성 및 간섭의 영향, 중단 없는 토큰 처리의 필요성, 그리고 표준 EOA 서명 검증과의 하위 호환성을 신중하게 고려하여 EIP-7702 스마트 계약 지갑을 안전하게 위임하고 관리하기 위한 프록시를 구축했습니다. EIP7702Proxy는 CoinbaseSmartWallet V1 구현을 염두에 두고 설계되었지만, 이 프록시는 궁극적으로 구현 방식에 구애받지 않습니다. 개발자 여러분께서 다른 스마트 계약 지갑 구현의 7702 검증을 위해 이 솔루션을 평가해 보시기를 권장합니다.
BlockBeats 공식 커뮤니티에 참여하세요:
Telegram 구독 그룹:https://t.me/theblockbeats
Telegram 토론 그룹:https://t.me/BlockBeats_App
Twitter 공식 계정:https://twitter.com/BlockBeatsAsia