Spectra - Aymen0909's results

A permissionless interest rate derivatives protocol on Ethereum.

General Information

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

Spectra

Findings Distribution

Researcher Performance

Rank: 22/39

Findings: 1

Award: $80.57

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

80.5733 USDC - $80.57

Labels

bug
2 (Med Risk)
partial-75
sufficient quality report
:robot:_33_group
duplicate-210

External Links

Lines of code

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

Vulnerability details

Issue Description

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:

  1. The 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));
}
  1. In EIP5095, the 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.

Impact

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.

Tools Used

Manual review, VS Code

A straightforward solution to address the aforementioned issues is as follows:

  1. Modify the maxWithdraw function to return 0 when the contract is paused instead of reverting.

  2. 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.

Assessed type

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

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter