❗ Note for participants: The sponsor's repo, scope definition, and contents herein are all subject to change.
All issues submitted via wardens and the Blue Team during this Code4rena Blue engagement will be added to this project list weekly.
Centralization Risks: Some methods (such as emergencyWithdraw
) are only accessible by the Redacted DAO multisig, which is the sole owner of the contracts. This is acceptable as the multisig is controlled by the Redacted DAO, which is a decentralized organization. These methods would only be used for emergency purposes, such as in the event of a critical bug or a hack.
ERC-1155 Mint Re-entrancy: The contract is not vulnerable to reentrancy attacks because the contract does not hold any funds and does not call any external contracts in the same transaction as the mint call. The contract is also not vulnerable to re-entrancy attacks because the contract does not use any state variables that can be modified by an external contract in the same transaction as the mint call.
Deposit Front Running: This issue is mitigated by pushing all validators into queue via access control once they have an effective balance of 1 ETH, meaning they have already been registered with the canonical beacon chain deposit contract.
Allowances and OPERATOR_ROLE
: The OPERATOR_ROLE
is able to set allowances for pxETH
. This role only given to the PirexETH
contract and is used to facilitate fee distribution. The OPERATOR_ROLE
is not given to any external contracts or accounts.
Effects of setContract
on State: Changing withdrawal credentials aka the rewardRecipient
contract address could corrupt state. For example, if there are initialised validators and rewardRecipient
is changed via setContract
, then functions like getInitializedValidatorAt
may return incorrect withdrawal credentials. This is mitigated by the fact that setContract
can ony be called by the owner (Redacted DAO multisig) which does extensive due diligence before executing any transactions, and rewardRecipient
is not expected to change.
Note: We have acknowledged all findings in referenced Audits and have either fixed them or have mitigated them. These functions are required for the protocol to work as intended.
Pirex ETH is built on top of the Redacted DAO’s Pirex platform and forms the foundation of the Dinero protocol. It is a two-token system built around ETH staking, consisting of pxETH and apxETH, tailored for different user preferences. This design gives users a choice: pxETH for liquidity or apxETH for boosted ETH staking yield.
pxETH
and apxETH
When depositing ETH, users can choose between holding pxETH or depositing to an auto compounding rewards vault for apxETH.
pxETH is for those willing to forgo staking yield for liquidity. When users choose to hold pxETH, they’re opting to hold an ETH-pegged asset that can take advantage of opportunities throughout DeFi. These include providing liquidity, participating in lending protocols, and more. The Redacted DAO will be using its treasury and BTRFLY incentives to expand such opportunities for pxETH holders.
apxETH is for users focused on maximizing their staking yields. After minting pxETH, users can deposit to Dinero's auto-compounding rewards vault to enjoy boosted staking yields without the hassle of running their own validators. Since some users will choose to hold pxETH, each apxETH benefits from staking rewards from more than one staked ETH, amplifying the yield for apxETH users.
Most ETH deposited into the Dinero protocol via Pirex ETH is staked on the Ethereum network. However, a small fraction remains in an "ETH buffer" instead of being staked. This buffer facilitates smooth staking and unstaking, allows faster ETH withdrawals when it has funds, and will support self-contained meta transactions through the Redacted Relayer RPC in the future.
There are limits on the rate at which validators can enter and exit the Ethereum network, based on the total number of validators. Therefore, if there is a significant ETH unstaking queue, this can hamper the timeliness of ETH withdrawals from the Dinero protocol from the spinning down of validators. In these circumstances, an incentivized withdrawal pool can be used to improve pxETH liquidity from ETH unstaking.
Users can deposit ETH into a pool and receive rewards whilst they provide liquidity to that pool. Where there is an unstaking queue and ETH from the spinning down of validators is not readily available, ETH from this pool is provided to users in exchange for pxETH, with the exchange rate or price being determined by demand for ETH from the pool. As pxETH is redeemed and validators are spun down, ETH is replenished in the pool. Depositors into the withdrawal pool therefore receive rewards in exchange for potential ETH illiquidity.
As pricing depends on the demand for ETH in the pool, rewards on deposited ETH increase during periods of high demand, allowing the pool to scale when demand is high. This makes liquidity provision more efficient and cost effective.
Yield from apxETH can be tokenized via yield stripping. For example, if a user wants to tokenize 1 year of yield for 1 pxETH deposited in the rewards vault, they can exchange 1 pxETH for:
Users decide how many reward cycles they tokenize. These tokens can be used throughout DeFi and are tradable. Yield stripping provides users the ability to leverage, hedge, and speculate on future pxETH price and future yield.
This is the complete list of what's in scope for this contest:
Contract | SLOC | Purpose | Libraries used |
---|---|---|---|
src/AutoPxEth.sol | 489 | This contract enables autocompounding for pxETH assets and includes various fee mechanisms. | openzeppelin-contracts, solmate |
src/DineroERC20.sol | 77 | A Standard ERC20 token with minting and burning with access control. | openzeppelin-contracts, solmate |
src/OracleAdapter.sol | 112 | This contract facilitates interactions between PirexEth, the reward recipient, and oracles for managing validators. | openzeppelin-contracts |
src/PirexEth.sol | 552 | This contract manages various interactions with pxETH, such as deposits, redemptions, and fee adjustments. | solmate |
src/PirexEthValidators.sol | 1063 | This contract includes functionality for handling validator-related operations and deposits. | openzeppelin-contracts, solmate |
src/PirexFees.sol | 86 | This contract manages the distribution of protocol fees to assigned recipient. | openzeppelin-contracts, solmate |
src/PxEth.sol | 51 | This contract manages the PxEth token, the main token for the PirexEth system used in the Dinero ecosystem. It extends the DineroERC20 contract and includes additional functionality. | None |
src/RewardRecipient.sol | 158 | This contract manages rewards for validators and handles associated functionalities. | openzeppelin-contracts |
src/interfaces/IDepositContract.sol | 24 | This is the Ethereum 2.0 deposit contract interface. | None |
src/interfaces/IOracleAdapter.sol | 18 | This interface defines the methods for interacting with OracleAdapter. | None |
src/interfaces/IPirexEth.sol | 61 | This interface defines the methods for interacting with PirexEth. | None |
src/interfaces/IPirexFees.sol | 23 | This interface defines functions related to the distribution of fees in the Pirex protocol. | None |
src/interfaces/IRewardRecipient.sol | 40 | This interface defines functions related to dissolving and slashing validators in the Pirex protocol. | None |
src/libraries/DataTypes.sol | 87 | This library provides data structures and enums crucial for the functionality of the Pirex protocol. | None |
src/libraries/Errors.sol | 204 | This interface defines errors that might occur in the PirexEth system. | None |
src/libraries/ValidatorQueue.sol | 347 | This library provides functions for adding, swapping, and removing validators in the validator queue. It also includes functions for popping validators from the end of the queue, retrieving validator information, and clearing the entire queue. | openzeppelin-contracts |
src/tokens/UpxEth.sol | 127 | This is a semi-fungible ERC1155 token contract with minting and burning capabilities, using AccessControl for role-based access. | openzeppelin-contracts, solmate |
Total | 3519 |
This is a list of mainnet contract deployments:
Contracts:
ChainlinkFunctionsOracleAdapter.sol
Vendor Libraries:
chainlink
solidty-cborutils
@ensdomains/buffer
Trusted Roles
DEFAULT_ADMIN_ROLE
: Set external contract addressesGOVERNANCE_ROLE
: Manages validator queue, set fee params, pause deposits to beacon chain deposit contractKEEPER_ROLE
: Harvest rewards, update status when a validator is slashed and top up validator stake when active balance goes below effective balanceOPERATOR_ROLE
: Allows PirexETH
to perform specific internal actions (eg. approve allowances for fee distribution)ORACLE_ROLE
: Updates the state of the validator when it is dissolvedMINTER_ROLE
: Allows PirexETH
to mint pxETH
and apxETH
BURNER_ROLE
: Allows PirexETH
to burn pxETH
and apxETH
EIP Specifications:
pxETH
: Should comply with ERC-20
standardapxEth
: Should comply with ERC-4626
standardupxETH
(Unlocking) and RFN
(Yield Stripping): Should comply with ERC-1155
standardIn the event of DOS, we would consider a finding to be valid if it is reproducible for a minimum duration of 4 hours.
pxETH
address, etc) which are controlled by the DEFAULT_ADMIN_ROLE
pxETH
and apxETH
are minted and burned in a 1:1 ratiooutstandingRedemptions
pendingWithdrawal
pendingDeposits
Employees of Redacted Finance, and employees' family members are ineligible for bounties.