Platform: Code4rena
Start Date: 27/05/2022
Pot Size: $75,000 USDC
Total HM: 20
Participants: 58
Period: 7 days
Judge: GalloDaSballo
Total Solo HM: 15
Id: 131
League: ETH
Rank: 15/58
Findings: 3
Award: $909.59
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: peritoflores
https://github.com/code-423n4/2022-05-backd/blob/2a5664d35cde5b036074edef3c1369b984d10010/protocol/contracts/swappers/SwapperRouter.sol#L280 https://github.com/code-423n4/2022-05-backd/blob/2a5664d35cde5b036074edef3c1369b984d10010/protocol/contracts/swappers/SwapperRouter.sol#L140
Using payable(address).transfer
is deprecated in favor of using .call{value:...}("")
as the correct way of sending ETH. Using transfer
or send
will make transactions fail when the address corresponds to a contract that does not implement a payable function using less than 2300 gas (multisigs and proxied contracts). Implementations of this in SwapperRouter.sol
will prevent such contracts from being able to correctly interact with the protocol.
#0 - chase-manning
2022-06-06T11:11:02Z
Duplicate of #180
#1 - GalloDaSballo
2022-06-19T21:10:06Z
Dup of #180
🌟 Selected for report: IllIllI
Also found by: 0x1f8b, 0x29A, 0xNazgul, 0xf15ers, BowTiedWardens, Chom, Funen, Kaiziron, Kumpa, MiloTruck, Picodes, Ruhum, SecureZeroX, Sm4rty, SmartSek, StyxRave, WatchPug, Waze, asutorufos, bardamu, berndartmueller, c3phas, catchup, cccz, codexploder, cryptphi, defsec, delfin454000, dipp, fatherOfBlocks, gzeon, hake, hansfriese, hyh, masterchief, oyc_109, sach1r0, sashik_eth, shenwilly, simon135, unforgiven
113.8755 USDC - $113.88
Redundant greater than 0 checks for uint
When executing pool weight changes in InflationManager.sol
(_executeKeeperPoolWeight, _executeLpPoolWeight, _executeAmmTokenWeight), corresponding total pool weights x
are unsigned int
. As they can't only be x >= 0
, the expression x>0 ? x : 0
does nothing.
Sensible changes, such as adding a Governor should be a two-step process
addGovernance
directly grants Roles.GOVERNANCE
to the newGovernor
. It should be a two-step process (e.g. setGovernance-acceptGovernance) to ensure the input address is correct. Whilst renounceGovernance
checks that there is at least one Governor left, in a single-Governor scenario, back to back execution of addGovernance
with an incorrect address followed by renounceGovernance
will render the protocol ungovernable. Additionally, as there is no way to revoke this role, granting governance to an address means that address will have complete control over the protocol forever after.
Requirement uses external call to user-controlled address in PoolMigrationZap.sol - migrate
require(oldPool_.getWithdrawalFee(msg.sender, lpTokenAmount_) == 0, "withdrawal fee not 0");
makes an external call to oldPoolAddress_
, which is a user-controlled address. It could be a malicious contract, thus reporting any result needed to bypass the guard.
Erring on the safe side for reentrancy in PoolMigrationZap.sol - migrate
While I did not manage to exploit it in any way - I'd recommend against not including a nonReentrant
guard in this function. oldPoolAddress_
could be a malicious contract thus enabling multiple calls to migrate
spanning from the external calls to oldPool
or lpToken_
.
Recommended missing events Modifying key protocol variables or triggering key events should always emit events accordingly to ensure transparency and proper traceability.
Minter.sol
: setToken, startInflation, executeInflationRateUpdateBkdLocker.sol
: migrateController.sol
: setInflationManagerAmmGauge.sol
: killKeeperGauge.sol
: kill, advanceEpoch, reportFees, poolCheckpointInflationManager.sol
: deactivateWeightBasedKeeperDistribution, checkpointAllGaugesVestedEscrow.sol
: setAdmin, setFundAdmin, initializeUnallocatedSupply#0 - GalloDaSballo
2022-06-20T15:29:55Z
Agree as they can at lowest be 0
Personally disagree, but valid find
Because of the architecture it's the callers responsibility to ensure the old contract is safe, as no funds beside the caller are at stake, I don't believe any risk was shown in this finding
Agree that the function doesn't respect CEI
Agree with informational level finding
Overall a concise report, I especially liked the formatted links which make the text way faster to read through
🌟 Selected for report: IllIllI
Also found by: 0x1f8b, 0x29A, 0xKitsune, 0xNazgul, 0xf15ers, 0xkatana, Chom, Dravee, Fitraldys, Funen, Kaiziron, MiloTruck, Picodes, Randyyy, RoiEvenHaim, SecureZeroX, Sm4rty, SmartSek, StyxRave, Tadashi, Tomio, Waze, asutorufos, berndartmueller, c3phas, catchup, csanuragjain, defsec, delfin454000, djxploit, fatherOfBlocks, gzeon, hake, hansfriese, oyc_109, robee, sach1r0, sashik_eth, scaraven, simon135
57.93 USDC - $57.93
PoolMigrationZap.sol
- Use UncheckedMath.uncheckedInc
instead of ++i in loop
FeeBurner.sol
- Use calldata
instead of memory
for read-only function argument array tokens_
.
#0 - GalloDaSballo
2022-06-17T22:43:38Z
20 gas
In lack of explanation will not give it any gas saved
#1 - GalloDaSballo
2022-06-17T22:43:41Z
20 gas saved