code-423n4 / 2024-02-spectra-findings

4 stars 2 forks source link

Post-Expiry Rate Manipulation in PrincipalToken due to Lack of Access Control #282

Closed c4-bot-6 closed 6 months ago

c4-bot-6 commented 6 months ago

Lines of code

https://github.com/code-423n4/2024-02-spectra/blob/main/src/tokens/PrincipalToken.sol#L409

Vulnerability details

Impact

Attackers can exploit the reliance on calling storeRatesAtExpiry() to lock rates after expiry to extract additional value or manipulate user redemptions.

Proof of Concept

File: PrincipalToken.sol
409:     function storeRatesAtExpiry() public override afterExpiry {
410:         if (ratesAtExpiryStored) {
411:             revert RatesAtExpiryAlreadyStored();
412:         }
413:         ratesAtExpiryStored = true;
414:         // PT rate not rounded up here
415:         (ptRate, ibtRate) = _getCurrentPTandIBTRates(false);
416:         emit RatesStoredAtExpiry(ibtRate, ptRate);
417:     }

Lines of code

The contract relies on this being called to set rates after expiry but there is no control on when it can be called.

An attacker could wait until favourable rate moves after expiry and then call storeRatesAtExpiry() to lock in rates benefiting themselves or causing maximum damage.

Recommended Mitigation Steps

  1. Add onlyOwner access control to storeRatesAtExpiry()
  2. Emit event on expiry block timestamp passed without valid rate store
  3. Compute rate derivation from fixed oracle sources rather than calling contract states

Assessed type

Access Control

c4-pre-sort commented 6 months ago

gzeon-c4 marked the issue as primary issue

c4-pre-sort commented 6 months ago

gzeon-c4 marked the issue as insufficient quality report

gzeon-c4 commented 6 months ago

intended behavior, anyone can lock the rate after expiry

c4-judge commented 6 months ago

JustDravee marked the issue as unsatisfactory: Invalid