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: 31/77
Findings: 4
Award: $142.75
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: 0xmystery
Also found by: 0x6d6164616e, 0xWaitress, 0xsurena, Tendency, ZanyBonzy, cryptothemex, hals, lsaudit, ni8mare, niki, phoenixV110, spark, tnquanghuy0512, twcctop
26.0735 USDC - $26.07
https://github.com/open-dollar/od-contracts/blob/v1.5.5-audit/src/contracts/oracles/CamelotRelayer.sol#L58 https://github.com/open-dollar/od-contracts/blob/v1.5.5-audit/src/contracts/oracles/UniV3Relayer.sol#L64
The current oracle relayers will not support the Camelot/UniV3 pair with more than 18 decimals
baseAmount = uint128(10 ** IERC20Metadata(_baseToken).decimals()); multiplier = 18 - IERC20Metadata(_quoteToken).decimals(); // @audit the decimal can be custom which may exceed 18 quotePeriod = _quotePeriod; symbol = string(abi.encodePacked(IERC20Metadata(_baseToken).symbol(), ' / ', IERC20Metadata(_quoteToken).symbol()));
Assume the _quoteToken
supports the decimal()
, and once the quote token has more than 18 decimals(since no specific limitation on token), the corresponding multiplier calculation will revert due to the underflow.
Reference: Tokens with more than 18 decimal points will cause issues
Manual
Recommend setting limitations on supported tokens and using dynamic value to config the relayer.
ERC20
#0 - c4-pre-sort
2023-10-26T17:11:10Z
raymondfam marked the issue as sufficient quality report
#1 - c4-pre-sort
2023-10-26T17:11:19Z
raymondfam marked the issue as duplicate of #18
#2 - c4-pre-sort
2023-10-27T05:08:05Z
raymondfam marked the issue as duplicate of #323
#3 - c4-judge
2023-11-02T08:45:36Z
MiloTruck marked the issue as satisfactory
54.1911 USDC - $54.19
Judge has assessed an item in Issue #320 as 2 risk. The relevant finding follows:
constructor( address _token, TimelockController _timelock ) Governor('ODGovernor') GovernorSettings(1, 15, 0) //@audit voting period too short -> 15 block GovernorVotes(IVotes(_token)) GovernorVotesQuorumFraction(3) GovernorTimelockControl(_timelock) {} Reference: https://officercia.mirror.xyz/d798TVQyA1ALq3qr1R9vvujdF7x-erXxK2wQWwbgRKY
#0 - c4-judge
2023-11-03T17:08:21Z
MiloTruck marked the issue as duplicate of #202
#1 - c4-judge
2023-11-03T17:08:26Z
MiloTruck marked the issue as satisfactory
54.1911 USDC - $54.19
Judge has assessed an item in Issue #320 as 2 risk. The relevant finding follows:
address internal constant _CAMELOT_FACTORY = GOERLI_CAMELOT_V3_FACTORY; //@audit stale address may affect the contract during deployment
#0 - c4-judge
2023-11-03T17:07:30Z
MiloTruck marked the issue as satisfactory
#1 - c4-judge
2023-11-03T18:21:20Z
MiloTruck marked the issue as duplicate of #187
🌟 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
Since there is no limit to duplicate relayer creation, which will allow multiple relayers for a single camelot pair, which may generate chaos if the interaction party for camelotRelayersList
is intended to have a unique relayer for each pair.
function deployCamelotRelayer( address _baseToken, address _quoteToken, uint32 _quotePeriod ) external isAuthorized returns (IBaseOracle _camelotRelayer) { _camelotRelayer = new CamelotRelayerChild(_baseToken, _quoteToken, _quotePeriod);//@audit multiple relayers for the same pair _camelotRelayers.add(address(_camelotRelayer)); emit NewCamelotRelayer(address(_camelotRelayer), _baseToken, _quoteToken, _quotePeriod); }
Also, inside the relayer, the symbol for each relayer may have collision, since different token may share the same name.
Recommend using mapping instead to record the relayer and additional existence check may needed.
The initial setting for the voting period in ODGovernor
is 15 block, which can be too tight for the governance. Based on Arbitrum block time, which is about ~0.26 seconds, which can be too short.
constructor( address _token, TimelockController _timelock ) Governor('ODGovernor') GovernorSettings(1, 15, 0) //@audit voting period too short -> 15 block GovernorVotes(IVotes(_token)) GovernorVotesQuorumFraction(3) GovernorTimelockControl(_timelock) {}
Reference: https://officercia.mirror.xyz/d798TVQyA1ALq3qr1R9vvujdF7x-erXxK2wQWwbgRKY
In CamelotRelayer
, _CAMELOT_FACTORY
is assigned with Goerli testnet address, which may cause issue during the mainnet launch
address internal constant _CAMELOT_FACTORY = GOERLI_CAMELOT_V3_FACTORY; //@audit stale address may affect the contract during deployment
For the execute
function in ODProxy
, there is no validation if the _target
is a contract.
Reference: https://solodit.xyz/issues/l-02-missing-contract-existence-checks-before-low-level-calls-code4rena-llama-llama-git
#0 - c4-pre-sort
2023-10-27T00:36:48Z
raymondfam marked the issue as sufficient quality report
#1 - c4-judge
2023-11-03T16:40:06Z
MiloTruck marked the issue as grade-b