Platform: Code4rena
Start Date: 23/02/2024
Pot Size: $36,500 USDC
Total HM: 2
Participants: 39
Period: 7 days
Judge: Dravee
Id: 338
League: ETH
Rank: 22/39
Findings: 1
Award: $80.57
🌟 Selected for report: 0
🚀 Solo Findings: 0
80.5733 USDC - $80.57
https://github.com/code-423n4/2024-02-spectra/blob/main/src/tokens/PrincipalToken.sol#L460-L462 https://github.com/code-423n4/2024-02-spectra/blob/main/src/tokens/PrincipalToken.sol#L806-L808 https://github.com/code-423n4/2024-02-spectra/blob/main/src/tokens/PrincipalToken.sol#L829-L831
The PrincipalToken
contract was intended to adhere to the standards outlined in EIP5095 regarding yield tokenization and principal token contract architecture. However, it has been found that PrincipalToken
deviates from the directives specified in EIP5095 in the following ways:
maxWithdraw
function contains the whenNotPaused
modifier. According to EIP5095, this function must not revert but should instead return 0 to indicate that withdrawals are disabled (which is the case when the protocol is paused). However, in the current implementation, it reverts when the contract is paused.function maxWithdraw(address owner) public view override whenNotPaused returns (uint256) { return convertToUnderlying(_maxBurnable(owner)); }
withdraw
and redeem
functions are expected to be callable by either the owner or any user who has EIP-20 approval over the principal tokens of the owner. However, in the PrincipalToken
contract, these functions are restricted to only the PT token owner. This restriction is enforced by checks present in both _beforeWithdraw
and _beforeRedeem
respectively:function _beforeRedeem(uint256 _shares, address _owner) internal nonReentrant whenNotPaused { if (_owner != msg.sender) { revert UnauthorizedCaller(); } ... } function _beforeWithdraw(uint256 _assets, address _owner) internal whenNotPaused nonReentrant { if (_owner != msg.sender) { revert UnauthorizedCaller(); } ... }
The failure of the PrincipalToken
contract to fully comply with EIP5095 standards may pose difficulties or even render it impossible for external protocols to build on top of it or integrate it into their business logic. This non-compliance could significantly impede protocol development.
The inability of external protocols to integrate with the PrincipalToken
contract due to its lack of full compliance with EIP5095 poses a potential hindrance to its adoption and interoperability.
Manual review, VS Code
A straightforward solution to address the aforementioned issues is as follows:
Modify the maxWithdraw
function to return 0 when the contract is paused instead of reverting.
Amend both the _beforeWithdraw
and _beforeRedeem
functions to allow both the owner and any user with EIP-20 approval over the principal tokens of the owner to call withdraw
and redeem
.
Context
#0 - c4-pre-sort
2024-03-03T09:20:42Z
gzeon-c4 marked the issue as duplicate of #33
#1 - c4-pre-sort
2024-03-03T09:20:45Z
gzeon-c4 marked the issue as sufficient quality report
#2 - c4-judge
2024-03-11T00:30:08Z
JustDravee marked the issue as partial-75
#3 - c4-judge
2024-03-11T00:30:11Z
JustDravee marked the issue as satisfactory
#4 - c4-judge
2024-03-14T06:21:53Z
JustDravee marked the issue as partial-75