“Puffer is a decentralized native liquid restaking protocol (nLRP) built on Eigenlayer”. It has attracted more than 600 million USD in TVL (Total Value Locked) in just a few days. Access control is an important security consideration to prevent malicious operations on the protocol.
In this blog, we review the entire architecture of the access control mechanism and its current configuration in the Puffer protocol. This can help the community better understand the protocol. Note that the analysis result is based on the current status (Block 19177155, Feb 07, 2024, 03:17:35 PM +UTC) on Ethereum.
Contract addresses
The following table lists the smart contracts used in this blog.
Address | Implementation | |
---|---|---|
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 |
Architecture
The whole protocol mainly includes two smart contracts related to users’ assets. The first one is PufferDepositor
, and the second one is PufferVault
.
The main functionality of PufferDepositor is to accept users’ assets and then deposit them into PufferVault. If the users' deposit assets are not stETH, the swap into a DEX is automatically performed by the protocol.
PufferVault is the main contract that holds users' assets. It’s also the entry point for deposits into EigenLayer. The main access control of the entire protocol is implemented in this smart contract."
Access Control Mechanism
The whole access control is implemented by leveraging OpenZeppelin’s AccessManager module. The AccessManager
smart contract manages the authority of the PufferDepositor
and PufferVault
contracts.
The AccessManager defines different Roles, which contain different addresses. Each Role can be assigned to invoke different functions inside the AccessManaged contracts (i.e., PufferDepositor and PufferVault). The AccessManager supports the delayed execution of a particular function. That’s when granting a Role to an address, it can specify whether the operations issued from this address in this Role are executed immediately or executed with a time delay.
Current Access Control Configurations
Nevertheless, the effectiveness of the access control depends on its configuration. We have observed numerous instances where a flawed configuration of ACL (Access Control List) rules has led to security vulnerabilities.
To address this, we have reviewed the current configuration of the Puffer protocol and present the results below. Please note that these results only reflect the status as of Block 19177155 (Feb 07, 2024, 03:17:35 PM +UTC).
Roles
Below is a table outlining the current roles within the system and their associated addresses.
Role ID | Addresses with this Role | Delayed Execution | Note |
---|---|---|---|
0 | TimeLock 0x3c28b7c7ba1a1f55c9ce66b263b33b204f2126ea | No | ADMIN Role |
1 | Operation SafeWallet 0xc0896ab1a8cae8c2c1d27d011eb955cca955580d | Yes with 604800 seconds (7 days) | Upgrade the target contracts (PufferDepositor and PufferVault) |
1 | Community SafeWallet 0x446d4d6b26815f9ba78b5d454e303315d586cb2a | No | Upgrade the target contracts (PufferDepositor and PufferVault) |
22 | Operation SafeWallet 0xc0896ab1a8cae8c2c1d27d011eb955cca955580d | No | Move assets to EigenLayer and initiate withdrawal request from EigenLayer |
There are different execution paths to execute functions inside the PufferValut contract. One path involves the TimeLock contract (with the ADMIN Role – as shown in Path 1 in the figure), and the other path allows direct invocation of functions inside the Vault, with the role assigned to the caller. In both cases, the invocation must go through the AccessManager.
Type I: Invocation from TimeLock Contract
Note that when invoking a function from the TimeLock contract, the assigned Role is ADMIN. This designation arises because, from the Vault's perspective, the caller is the TimeLock contract, which possesses the ADMIN Role. Consequently, the TimeLock contract incorporates an additional layer of delayed execution mechanism.
- Operation SafeWallet: This component can invoke functions within the target contract after a delay of 604,800 seconds (approximately 7 days).
- Community SafeWallet: This component has the capability to immediately invoke functions within the target contract. It also possesses the authority to cancel any pending execution in the queue submitted by the Operation SafeWallet.
- Pausing SafeWallet: This component is restricted to pausing the target contract and is not authorized to execute any other functions.
Type II: Direct Invocation of the Vault Contract
The subsequent method involves directly invoking functions within the Vault contract. It's important to note that the AccessManager dictates which functions can be invoked by the addresses associated with each Role.
RoleID | Target Contract | Target Function |
1 | PufferValut | upgradeToAndCall(address,bytes)
0x4f1ef286 |
22 | PufferValut | depositToEigenLayer (0x008e0590)
initiateETHWithdrawalsFromLido (0x593961de) initiateStETHWithdrawalFromEigenLayer (0x402064a7) |
Both the Operation and Community SafeWallets have the capability to directly invoke the upgradeToAndCall
function to upgrade the target contract. The key distinction lies in the timing: the Community SafeWallet executes this action without any delay, whereas the Operation SafeWallet is subject to a delay.
Moreover, the Operation SafeWallet is equipped to immediately execute functions that transfer assets into EigenLayer and initiate withdrawal requests.
Updated on [Feb-08-2024 10:02:59 AM +UTC]
An operation aiming to remove the Operation SafeWallet from Role 1 has been scheduled. This operation is slated for execution after block 1707940908, which corresponds to an estimated delay of approximately 7 days. The simulation of these queued transactions was conducted using BlockSec Phalcon.
- The simulated transaction in Phalcon Fork to execute the queued execution on 2024-02-18 17:59:07 (UTC), ten days later.
- The simulated transaction to query whether the Operation SafeWallet still has Role 1 (return false)
See all transactions in this Fork.
Updated on [Feb-16-2024 20:10:23 AM +UTC]:
- The transaction to remove the Operation SafeWallet from Role 1 has been executed. We can check the result from Etherscan.
Safe Wallet Configurations
The configuration of a safe wallet also affects the protocol’s security.
Wallet | Owners | Threshold |
---|---|---|
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 |
Updated on [Feb-08-2024 10:02:59 AM +UTC]:
- The address 0xb7d83623906AC3fa577F45B7D2b9D4BD26BC5d76 has been removed from the Operation SafeWallet, adjusting its authorization to 3/5.
- A transaction to remove 0xb7d83623906AC3fa577F45B7D2b9D4BD26BC5d76 from the Community SafeWallet has been initiated and is currently awaiting multisig approval from the community.
- Three wallets have been removed from the Pausing SafeWallet, now adjusting its configuration to 1/9.
Summary
In this blog post, we have reviewed the security mechanisms utilized by the Puffer protocol. Overall, the design of the entire permission system is comprehensive.
The community should actively monitor for potential risks:
- The security of the private keys of the Community SafeWallet owners is paramount. If three private keys are compromised, it could allow an attacker to upgrade the vault.
- The security of dependent protocols, such as EigenLayer, should also be actively monitored.