Spectra's ibtRate calculation relies solely on the IBT contract's state - specifically totalAssets and balanceOf Spectra's contract. This leaves it vulnerable to manipulation if the IBT contract's state is changed unexpectedly.
If ibtRate is reduced, users depositing IBT into Spectra would get more shares than they should. If ibtRate then corrects back, those users could withdraw and profit.
There are several IBT external functions that could alter the critical state values used by Spectra:
If any user calls these functions, it would change the IBT's totalAssets and Spectra's balance - thus directly affecting ibtRate.
For example, let's imagine Spectra holds 100 IBT initially. The ibtRate will be calculated based on 100 IBT totalAssets and Spectra's balanceOf 100 IBT.
But if another user calls IBT.transferFrom(Spectra, user, 50):
This allows an attacker to arbitrarily manipulate the ibtRate used by the Spectra protocol. By changing ibtRate, they can extract profits or cause loss of funds for Spectra users.
The ibtRate relies solely on the IBT contract's state
By solely relying on the IBT contract's state, ibtRate can be manipulated via IBT's external functions.
An attacker can call IBT external functions to alter its state and corrupt ibtRate:
IBT.transferFrom(Spectra, attacker, 50 IBTs)
// Spectra balance now 50 IBT
// totalAssets still 100 IBT
// ibtRate cut in half!
This allows the attacker to extract profit. For example:
Attacker reduces ibtRate by 50% using transferFrom
User deposits 100 IBT into Spectra when ibtRate is artificially reduced
User gets double the normal shares due to reduced ibtRate
Attacker restores ibtRate to normal
User can now withdraw and profit
Tools Used
Manual review
Recommended Mitigation Steps
Spectra should only integrate with trusted, standardized IBTs without risky features.
Validate totalAssets matches Spectra's deposit/withdraw accounting expectations.
Possibly read balanceOf(spectrasContract) from IBT after sensitive operations as a sanity check.
Consider using a price oracle or Chainlink as redundancy on ibtRate.
Lines of code
https://github.com/code-423n4/2024-02-spectra/blob/383202d0b84985122fe1ba53cfbbb68f18ba3986/src/tokens/PrincipalToken.sol#L641-L651 https://github.com/code-423n4/2024-02-spectra/blob/383202d0b84985122fe1ba53cfbbb68f18ba3986/src/tokens/PrincipalToken.sol#L152 https://github.com/code-423n4/2024-02-spectra/blob/383202d0b84985122fe1ba53cfbbb68f18ba3986/src/tokens/PrincipalToken.sol#L902
Vulnerability details
Impact
Spectra's
ibtRate
calculation relies solely on the IBT contract's state - specificallytotalAssets
andbalanceOf
Spectra's contract. This leaves it vulnerable to manipulation if the IBT contract's state is changed unexpectedly.If ibtRate is reduced, users depositing IBT into Spectra would get more shares than they should. If ibtRate then corrects back, those users could withdraw and profit.
There are several IBT external functions that could alter the critical state values used by Spectra:
function transfer
function transferFrom
function withdraw
function redeem
function mint
If any user calls these functions, it would change the IBT's
totalAssets
and Spectra's balance - thus directly affectingibtRate
.For example, let's imagine Spectra holds 100 IBT initially. The
ibtRate
will be calculated based on 100 IBTtotalAssets
and Spectra'sbalanceOf
100 IBT.But if another user calls IBT.transferFrom(Spectra, user, 50):
This would cut the
ibtRate
in half unexpectedly!Proof of Concept
function _previewDepositIBT
This allows an attacker to arbitrarily manipulate the
ibtRate
used by the Spectra protocol. By changingibtRate
, they can extract profits or cause loss of funds for Spectra users.The
ibtRate
relies solely on the IBT contract's statePrincipalToken.sol#L 152
PrincipalToken.sol#L 902
By solely relying on the IBT contract's state,
ibtRate
can be manipulated via IBT's external functions.An attacker can call IBT external functions to alter its state and corrupt ibtRate:
This allows the attacker to extract profit. For example:
Attacker reduces ibtRate by 50% using transferFrom User deposits 100 IBT into Spectra when ibtRate is artificially reduced User gets double the normal shares due to reduced ibtRate Attacker restores ibtRate to normal User can now withdraw and profit
Tools Used
Manual review
Recommended Mitigation Steps
Spectra should only integrate with trusted, standardized IBTs without risky features. Validate
totalAssets
matches Spectra's deposit/withdraw accounting expectations. Possibly readbalanceOf(spectrasContract)
from IBT after sensitive operations as a sanity check. Consider using a price oracle or Chainlink as redundancy onibtRate
.Assessed type
Governance