Platform: Code4rena
Start Date: 07/09/2022
Pot Size: $20,000 CANTO
Total HM: 7
Participants: 65
Period: 1 day
Judge: 0xean
Total Solo HM: 3
Id: 159
League: ETH
Rank: 3/65
Findings: 1
Award: $2,772.10
🌟 Selected for report: 1
🚀 Solo Findings: 1
🌟 Selected for report: Respx
17164.6802 CANTO - $2,772.10
https://github.com/code-423n4/2022-09-canto/blob/65fbb8b9de22cf8f8f3d742b38b4be41ee35c468/src/Swap/BaseV1-core.sol#L224-L258 https://github.com/code-423n4/2022-09-canto/blob/65fbb8b9de22cf8f8f3d742b38b4be41ee35c468/src/Swap/BaseV1-core.sol#L271-L289 https://github.com/code-423n4/2022-09-canto/blob/65fbb8b9de22cf8f8f3d742b38b4be41ee35c468/src/Swap/BaseV1-core.sol#L187-L194 https://github.com/code-423n4/2022-09-canto/blob/65fbb8b9de22cf8f8f3d742b38b4be41ee35c468/src/Swap/BaseV1-core.sol#L201-L222 https://github.com/code-423n4/2022-09-canto/blob/65fbb8b9de22cf8f8f3d742b38b4be41ee35c468/src/Swap/BaseV1-periphery.sol#L487-L593
There is insufficient resilience in the design for the case where there has been no call to _update()
for a long time. Consider these possible scenarios:
The system has no provision for this issue.
Consider the following attack scenario:
reserves()
to calculate the TWAP price of $CANTO. The values returned are out of date and far too high. The attacker is then able to borrow stablecoins against their $CANTO at too high a rate.https://github.com/code-423n4/2022-09-canto/blob/65fbb8b9de22cf8f8f3d742b38b4be41ee35c468/src/Swap/BaseV1-core.sol#L224-L258
https://github.com/code-423n4/2022-09-canto/blob/65fbb8b9de22cf8f8f3d742b38b4be41ee35c468/src/Swap/BaseV1-core.sol#L271-L289
reserves()
, sampleReserves()
and sampleSupply()
make no use of block.timestamp
. They all measure only the time duration of the observations. There is no awareness of how much time has passed since the most recent observation was made.
https://github.com/code-423n4/2022-09-canto/blob/65fbb8b9de22cf8f8f3d742b38b4be41ee35c468/src/Swap/BaseV1-core.sol#L187-L194
https://github.com/code-423n4/2022-09-canto/blob/65fbb8b9de22cf8f8f3d742b38b4be41ee35c468/src/Swap/BaseV1-core.sol#L201-L222
https://github.com/code-423n4/2022-09-canto/blob/65fbb8b9de22cf8f8f3d742b38b4be41ee35c468/src/Swap/BaseV1-periphery.sol#L487-L593
quote()
and sample()
have the same logic, and these functions are called in getPriceCanto()
and getPriceNote()
. getPriceLP()
relies on sampleReserves()
. They therefore have the same issue.
Manual Inspection
The system could track the average duration time of observations and, if any of the observations in a sample are significantly greater than this average, the system could either refuse to return a sample, or could return a warning flag to indicate that the sample data could be unreliable. There is precedent in the system for refusing to return a sample (see line 242 of BaseV1-core.sol).
#0 - nivasan1
2022-09-09T16:23:42Z
The oracle has been designed specifically for the purpose of use in the lending market, for pairs that have seen a long period of down-time (which is highly unexpected for supported pairs) the collateral factors can be adjusted to scale the price of the asset's collateral value downwards to reflect the volatility after the long period of downtime.
#1 - 0xean
2022-10-13T14:05:56Z
This has a high level of external factors that are required to be realized but knowing that the CANTO network has already suffered downtime, I don't think these are too far out of the realm of possibility. Downgrading to M