Platform: Code4rena
Start Date: 18/10/2023
Pot Size: $36,500 USDC
Total HM: 17
Participants: 77
Period: 7 days
Judge: MiloTruck
Total Solo HM: 5
Id: 297
League: ETH
Rank: 11/77
Findings: 3
Award: $524.08
π Selected for report: 0
π Solo Findings: 0
461.5931 USDC - $461.59
Judge has assessed an item in Issue #246 as 2 risk. The relevant finding follows:
[L-03] The tokenURI is not compatible with the ERC721 standard Description function tokenURI(uint256 _safeId) public view override returns (string memory uri) { uri = nftRenderer.render(_safeId); } tokenURI will call nftRenderer directly to render the data, and it will not detect whether the ID has been minted, which violates the ERC721 standard. Malicious attackers can forge NFTs to deceive users, causing users to think that the corresponding NFTs are real.
Recommendations Check the id is real before return tokenURI
#0 - c4-judge
2023-11-03T17:05:31Z
MiloTruck marked the issue as duplicate of #243
#1 - c4-judge
2023-11-03T17:05:35Z
MiloTruck marked the issue as satisfactory
54.1911 USDC - $54.19
Judge has assessed an item in Issue #246 as 2 risk. The relevant finding follows:
[L-01] Use the factory constant address of the testnet Description import {UNISWAP_V3_FACTORY, GOERLI_UNISWAP_V3_FACTORY} from '@script/Registry.s.sol';
contract UniV3Relayer is IBaseOracle, IUniV3Relayer { // --- Registry --- address internal constant _UNI_V3_FACTORY = GOERLI_UNISWAP_V3_FACTORY; }
import {CAMELOT_V3_FACTORY, GOERLI_CAMELOT_V3_FACTORY} from '@script/Registry.s.sol';
contract CamelotRelayer is IBaseOracle, ICamelotRelayer { // --- Registry --- address internal constant _CAMELOT_FACTORY = GOERLI_CAMELOT_V3_FACTORY; } CamelotRelayer and UniV3Relayer use the testnetβs factory constant address, which should be used for testing purposes. But considering that the contract will be deployed to the production environment, I mark this here.
Recommendations Pass in the addresses of different environments through parameters instead of using hard-coded addresses.
#0 - c4-judge
2023-11-03T17:05:55Z
MiloTruck marked the issue as duplicate of #187
#1 - c4-judge
2023-11-03T17:06:02Z
MiloTruck marked the issue as satisfactory
π Selected for report: MrPotatoMagic
Also found by: 0xMosh, 0xPsuedoPandit, 0xhacksmithh, 8olidity, Al-Qa-qa, Baki, Bughunter101, Krace, Stormreckson, T1MOH, Tendency, eeshenggoh, fibonacci, hals, immeas, kutugu, lsaudit, m4k2, mrudenko, okolicodes, phoenixV110, spark, twicek, xAriextz
8.3007 USDC - $8.30
ID | Title | Severity |
---|---|---|
[L-01] | Use the factory constant address of the testnet | Low |
[L-02] | Single point oracle prices remain vulnerable to manipulation | Low |
[L-03] | The tokenURI is not compatible with the ERC721 standard | Low |
import {UNISWAP_V3_FACTORY, GOERLI_UNISWAP_V3_FACTORY} from '@script/Registry.s.sol'; contract UniV3Relayer is IBaseOracle, IUniV3Relayer { // --- Registry --- address internal constant _UNI_V3_FACTORY = GOERLI_UNISWAP_V3_FACTORY; } import {CAMELOT_V3_FACTORY, GOERLI_CAMELOT_V3_FACTORY} from '@script/Registry.s.sol'; contract CamelotRelayer is IBaseOracle, ICamelotRelayer { // --- Registry --- address internal constant _CAMELOT_FACTORY = GOERLI_CAMELOT_V3_FACTORY; }
CamelotRelayer
and UniV3Relayer
use the testnet's factory constant address, which should be used for testing purposes.
But considering that the contract will be deployed to the production environment, I mark this here.
Pass in the addresses of different environments through parameters instead of using hard-coded addresses.
function getResultWithValidity() external view returns (uint256 _result, bool _validity) { // If the pool doesn't have enough history return false if (OracleLibrary.getOldestObservationSecondsAgo(uniV3Pool) < quotePeriod) { return (0, false); } // Consult the query with a TWAP period of quotePeriod (int24 _arithmeticMeanTick,) = OracleLibrary.consult(uniV3Pool, quotePeriod); // Calculate the quote amount uint256 _quoteAmount = OracleLibrary.getQuoteAtTick({ tick: _arithmeticMeanTick, baseAmount: baseAmount, baseToken: baseToken, quoteToken: quoteToken }); // Process the quote result to 18 decimal quote _result = _parseResult(_quoteAmount); _validity = true; }
UniV3Relayer
and CamelotRelayer
will read the pool price at quotePeriod
time point, and quotePeriod
is immutable.
If an attacker wants to take risks manipulating the pool price, the attack is still possible.
The attacker only needs to manipulate the pool price at any time and perform arbitrage after the quotePeriod
time.
Of course, the precise time difference is difficult to control, but the possibility of attack still exists.
function tokenURI(uint256 _safeId) public view override returns (string memory uri) { uri = nftRenderer.render(_safeId); }
tokenURI
will call nftRenderer
directly to render the data, and it will not detect whether the ID has been minted, which violates the ERC721 standard.
Malicious attackers can forge NFTs to deceive users, causing users to think that the corresponding NFTs are real.
Check the id is real before return tokenURI
#0 - c4-pre-sort
2023-10-27T00:50:34Z
raymondfam marked the issue as sufficient quality report
#1 - c4-judge
2023-11-03T16:49:36Z
MiloTruck marked the issue as grade-b