"Puffer는 Eigenlayer 위에 구축된 분산형 네이티브 리퀴드 리스테이킹 프로토콜(nLRP)입니다". 이 프로토콜은 단 며칠 만에 6억 달러 이상의 TVL(총 예치 자산)을 유치했습니다. 접근 제어는 프로토콜에서 악의적인 작업을 방지하기 위한 중요한 보안 고려 사항입니다.
이 블로그에서는 Puffer 프로토콜의 접근 제어 메커니즘과 현재 구성의 전체 아키텍처를 검토합니다. 이를 통해 커뮤니티가 프로토콜을 더 잘 이해할 수 있기를 바랍니다. 분석 결과는 이더리움의 현재 상태(블록 19177155, 2024년 2월 7일 오후 03:17:35 +UTC)를 기준으로 합니다.
컨트랙트 주소
아래 표는 이 블로그에서 사용된 스마트 컨트랙트 목록입니다.
| 주소 | 구현 | |
|---|---|---|
| PufferDepositor | 0x4aa799c5dfc01ee7d79 0e3bf1a7c2257ce1dceff | 0x7276925e42f9c4054af a2fad80fa79520c453d6a |
| PufferVault | 0xD9A442856C234a39a81 a089C06451EBAa4306a72 | 0x39ca0a6438b6050ea2a c909ba65920c7451305c1 |
| AccessManager | 0x8c1686069474410E624 3425f4a10177a94EBEE11 | - |
| TimeLock | 0x3c28b7c7ba1a1f55c9c e66b263b33b204f2126ea | - |
| Operation SafeWallet | 0xC0896ab1A8cae8c2C1d 27d011eb955Cca955580d | 0xd9db270c1b5e3bd161e 8c8503c55ceabee709552 |
| Community SafeWallet | 0x446d4d6b26815f9bA78 B5D454E303315D586Cb2a | 0xd9db270c1b5e3bd161e 8c8503c55ceabee709552 |
| Pausing SafeWallet | 0x1ba8e3aA853F73ae809 3E26B7B8F2520c3620Df4 | 0xd9db270c1b5e3bd161e 8c8503c55ceabee709552 |
아키텍처
전체 프로토콜은 주로 사용자 자산과 관련된 두 개의 스마트 컨트랙트로 구성됩니다. 첫 번째는 PufferDepositor이고, 두 번째는 PufferVault입니다.

PufferDepositor의 주요 기능은 사용자의 자산을 수락한 후 PufferVault에 예치하는 것입니다. 사용자의 예치 자산이 stETH가 아닌 경우, 프로토콜이 자동으로 DEX에서 스왑을 수행합니다.
PufferVault는 사용자 자산을 보유하는 메인 컨트랙트입니다. 또한 EigenLayer에 예치하기 위한 진입점이기도 합니다. 전체 프로토콜의 주요 접근 제어는 이 스마트 컨트랙트에서 구현됩니다.
접근 제어 메커니즘
전체 접근 제어는 OpenZeppelin의 AccessManager 모듈을 활용하여 구현됩니다. AccessManager 스마트 컨트랙트는 PufferDepositor 및 PufferVault 컨트랙트의 권한을 관리합니다.
AccessManager는 서로 다른 주소를 포함하는 다양한 역할(Role)을 정의합니다. 각 역할은 AccessManaged 컨트랙트(즉, PufferDepositor 및 PufferVault) 내의 서로 다른 함수를 호출하도록 지정될 수 있습니다. AccessManager는 특정 함수의 지연 실행을 지원합니다. 즉, 주소에 역할을 부여할 때, 해당 주소에서 이 역할로 발행된 작업이 즉시 실행될지 또는 시간 지연을 두고 실행될지 지정할 수 있습니다.
현재 접근 제어 구성
그럼에도 불구하고, 접근 제어의 효과는 구성에 따라 달라집니다. ACL(액세스 제어 목록) 규칙의 잘못된 구성이 보안 취약점으로 이어진 사례를 다수 확인했습니다.
이를 해결하기 위해 Puffer 프로토콜의 현재 구성을 검토하고 아래에 결과를 제시합니다. 이 결과는 블록 19177155(2024년 2월 7일 오후 03:17:35 +UTC) 기준의 상태만을 반영합니다.
역할(Roles)
아래는 시스템 내 현재 역할 및 관련 주소를 정리한 표입니다.
| 역할 ID | 이 역할을 가진 주소 | 지연 실행 | 비고 |
|---|---|---|---|
| 0 | TimeLock 0x3c28b7c7ba1a1f55c9ce66b263b33b204f2126ea | 아니오 | ADMIN 역할 |
| 1 | Operation SafeWallet 0xc0896ab1a8cae8c2c1d27d011eb955cca955580d | 예, 604800초(7일) | 대상 컨트랙트(PufferDepositor 및 PufferVault) 업그레이드 |
| 1 | Community SafeWallet 0x446d4d6b26815f9ba78b5d454e303315d586cb2a | 아니오 | 대상 컨트랙트(PufferDepositor 및 PufferVault) 업그레이드 |
| 22 | Operation SafeWallet 0xc0896ab1a8cae8c2c1d27d011eb955cca955580d | 아니오 | EigenLayer로 자산 이동 및 EigenLayer에서 출금 요청 시작 |
PufferVault 컨트랙트 내 함수를 실행하기 위한 여러 실행 경로가 있습니다. 하나는 TimeLock 컨트랙트를 통한 경로(ADMIN 역할 포함 – 그림의 경로 1 참조)이고, 다른 하나는 호출자에게 할당된 역할로 Vault 내 함수를 직접 호출하는 경로입니다. 두 경우 모두 AccessManager를 통해야 합니다.

유형 I: TimeLock 컨트랙트를 통한 호출
TimeLock 컨트랙트에서 함수를 호출할 때 지정된 역할은 ADMIN입니다. 이는 Vault의 관점에서 호출자가 ADMIN 역할을 보유한 TimeLock 컨트랙트이기 때문입니다. 결과적으로, TimeLock 컨트랙트는 추가적인 지연 실행 메커니즘 계층을 포함합니다.
- Operation SafeWallet: 이 구성 요소는 604,800초(약 7일)의 지연 후 대상 컨트랙트 내 함수를 호출할 수 있습니다.
- Community SafeWallet: 이 구성 요소는 대상 컨트랙트 내 함수를 즉시 호출할 수 있습니다. 또한 Operation SafeWallet이 제출한 대기 중인 실행을 취소할 권한도 보유합니다.
- Pausing SafeWallet: 이 구성 요소는 대상 컨트랙트 일시 중지만 허용되며, 다른 함수를 실행할 권한은 없습니다.
유형 II: Vault 컨트랙트 직접 호출
다음 방법은 Vault 컨트랙트 내 함수를 직접 호출하는 것입니다. AccessManager가 각 역할과 연결된 주소가 호출할 수 있는 함수를 결정한다는 점에 유의해야 합니다.
| 역할 ID | 대상 컨트랙트 | 대상 함수 |
| 1 | PufferValut | upgradeToAndCall(address,bytes)
0x4f1ef286 |
| 22 | PufferValut | depositToEigenLayer (0x008e0590)
initiateETHWithdrawalsFromLido (0x593961de) initiateStETHWithdrawalFromEigenLayer (0x402064a7) |
Operation SafeWallet과 Community SafeWallet 모두 upgradeToAndCall 함수를 직접 호출하여 대상 컨트랙트를 업그레이드할 수 있습니다. 핵심 차이는 타이밍에 있습니다. Community SafeWallet은 지연 없이 이 작업을 실행하는 반면, Operation SafeWallet은 지연이 적용됩니다.
또한, Operation SafeWallet은 EigenLayer로 자산을 이전하고 출금 요청을 시작하는 함수를 즉시 실행할 수 있습니다.
[2024년 2월 8일 오전 10:02:59 +UTC] 업데이트
Operation SafeWallet을 역할 1에서 제거하는 작업이 예약되었습니다. 이 작업은 블록 1707940908 이후에 실행될 예정이며, 약 7일의 지연이 예상됩니다. 대기 중인 트랜잭션의 시뮬레이션은 BlockSec Phalcon을 사용하여 수행되었습니다.

- 시뮬레이션된 트랜잭션: Phalcon Fork에서 2024-02-18 17:59:07 (UTC), 10일 후에 대기 중인 실행을 수행합니다.
- Operation SafeWallet이 여전히 역할 1을 보유하는지 조회하는 시뮬레이션된 트랜잭션(false 반환)
[2024년 2월 16일 오후 08:10:23 +UTC] 업데이트:

Safe Wallet 구성
Safe Wallet의 구성도 프로토콜 보안에 영향을 미칩니다.
| 지갑 | 소유자 | 임계값 |
|---|---|---|
| 0xC0896ab1A8cae8c2C1d 27d011eb955Cca955580d | [0xb7d83623906AC3fa577F45B7D2b9D4BD26BC5d76] [0xD6475ce37d964d4816715FdafFEeAAf2958948bE] [0xD70aa9d7280E6FEe89B86f53c0B2A363478D5e94] [0xa5F84b556d5FD8959165Eff0324DCFEa164fA089] [0xf061f1FceFa32b3bbD5d18c5A623DB64bfBc107D] [0x206846dE1F372A9a603e672ba97A5238cC89aeAA] | 3 |
| 0x446d4d6b26815f9bA78 B5D454E303315D586Cb2a | [0xb7d83623906AC3fa577F45B7D2b9D4BD26BC5d76] [0x3B16821A5dBBFF86E4a88eA0621EC6be016cd79A] [0x648aA14e4424e0825A5cE739C8C68610e143FB79] [0x27c7CEd729280060577A68A54A94075D18614D19] [0xa9aE3B8FC1CBaAed74fE5889260f7cD743c50363] [0x161f479021044cB1C9e3DEF98aF945A8D972D3B2] | 3 |
| 0x1ba8e3aA853F73ae809 3E26B7B8F2520c3620Df4 | [0xb7d83623906AC3fa577F45B7D2b9D4BD26BC5d76] [0x3B16821A5dBBFF86E4a88eA0621EC6be016cd79A] [0x648aA14e4424e0825A5cE739C8C68610e143FB79] [0x27c7CEd729280060577A68A54A94075D18614D19] [0xa9aE3B8FC1CBaAed74fE5889260f7cD743c50363] [0x161f479021044cB1C9e3DEF98aF945A8D972D3B2] [0xD6475ce37d964d4816715FdafFEeAAf2958948bE] [0xD70aa9d7280E6FEe89B86f53c0B2A363478D5e94] [0xa5F84b556d5FD8959165Eff0324DCFEa164fA089] [0xf061f1FceFa32b3bbD5d18c5A623DB64bfBc107D] [0x206846dE1F372A9a603e672ba97A5238cC89aeAA] [0xaACA1eDbb656206Ce2a82Da7d7BD3e1Bb8138F22] | 1 |
[2024년 2월 8일 오전 10:02:59 +UTC] 업데이트:
- 주소 0xb7d83623906AC3fa577F45B7D2b9D4BD26BC5d76이 Operation SafeWallet에서 제거되어 권한이 3/5로 조정되었습니다.
- Community SafeWallet에서 0xb7d83623906AC3fa577F45B7D2b9D4BD26BC5d76을 제거하는 트랜잭션이 시작되었으며, 현재 커뮤니티의 멀티시그 승인을 기다리고 있습니다.
- Pausing SafeWallet에서 세 개의 지갑이 제거되어 구성이 1/9로 조정되었습니다.
요약
이 블로그 게시물에서는 Puffer 프로토콜이 활용하는 보안 메커니즘을 검토했습니다. 전반적으로 전체 권한 시스템의 설계는 포괄적입니다.
커뮤니티는 잠재적 위험을 적극적으로 모니터링해야 합니다:
- Community SafeWallet 소유자의 개인 키 보안이 가장 중요합니다. 세 개의 개인 키가 탈취될 경우, 공격자가 Vault를 업그레이드할 수 있습니다.
- EigenLayer와 같은 의존 프로토콜의 보안도 적극적으로 모니터링해야 합니다.



