Platform: Code4rena
Start Date: 17/03/2022
Pot Size: $30,000 USDC
Total HM: 8
Participants: 43
Period: 3 days
Judge: gzeon
Total Solo HM: 5
Id: 100
League: ETH
Rank: 6/43
Findings: 2
Award: $2,073.31
🌟 Selected for report: 1
🚀 Solo Findings: 1
🌟 Selected for report: Ruhum
2021.4346 USDC - $2,021.43
https://github.com/code-423n4/2022-03-prepo/blob/main/contracts/core/SingleStrategyController.sol#L51-L72 https://github.com/code-423n4/2022-03-prepo/blob/main/contracts/core/interfaces/IStrategy.sol#L52
When migrating from one strategy to another, the controller pulls out the funds of the old strategy and deposits them into the new one. But, it doesn't verify that both strategies use the same base token. If the new one uses a different base token, it won't "know" about the tokens it received on migration. It won't be able to deposit and transfer them. Effectively they would be lost.
The migration is done by the owner. So the owner must make a mistake and migrate to the wrong strategy by accident. In a basic protocol with 1 controller and a single active strategy managing that should be straightforward. There shouldn't be a real risk of that mistake happening. But, if you have multiple controllers running at the same time each with a different base token, it gets increasingly likelier.
According to the IStrategy
interface, there is a function to retrieve the strategy's base token: getBaseToken()
. I'd recommend adding a check in the migrate()
function to verify that the new strategy uses the correct base token to prevent this issue from being possible.
https://github.com/code-423n4/2022-03-prepo/blob/main/contracts/core/interfaces/IStrategy.sol#L52
none
Add require(_baseToken == _newStrategy.getBaseToken());
to the beginning of migrate()
#0 - ramenforbreakfast
2022-03-23T00:59:53Z
Valid claim, in addition to #27, illustrates why we should probably not have a fixed migration function due to the complexity of such an operation.
#1 - gzeoneth
2022-04-03T13:27:40Z
Agree with sponsor
🌟 Selected for report: defsec
Also found by: 0x1f8b, 0xDjango, 0xNazgul, 0xkatana, 0xwags, CertoraInc, Funen, GeekyLumberjack, GreyArt, IllIllI, Kenshin, Ruhum, TerrierLover, WatchPug, berndartmueller, bugwriter001, cccz, cmichel, csanuragjain, hake, kenta, kirk-baird, leastwood, minhquanym, oyc_109, peritoflores, rayn, remora, rfa, robee, saian, samruna, sorrynotsorry, wuwe1
51.8842 USDC - $51.88
The initialize()
function of the deployed contracts isn't called within the same transaction according to the deployment scripts. Thus, someone could frontrun the initialize call forcing you to redeploy.
grep -n "init" deploy/*.ts
The PrePOMarketFactory.initialize()
function doesn't initialize ReentrancyGuardUpgradeable
.
https://github.com/code-423n4/2022-03-prepo/blob/main/contracts/core/PrePOMarketFactory.sol#L21
Add __ReentrancyGuard_init_unchained();
#0 - ramenforbreakfast
2022-03-23T01:01:14Z
First claim is duplicate of #4 Second claim is duplicate of #14