Platform: Code4rena
Start Date: 15/12/2022
Pot Size: $128,000 USDC
Total HM: 28
Participants: 111
Period: 19 days
Judge: GalloDaSballo
Total Solo HM: 1
Id: 194
League: ETH
Rank: 51/111
Findings: 5
Award: $146.79
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: 0xdeadbeef0x
Also found by: 0Kage, 0xc0ffEE, 0xmint, AkshaySrivastav, Allarious, Ch_301, Franfran, HollaDieWaldfee, IllIllI, Jeiwan, Lirios, Manboy, adriro, ak1, bin2chen, caventa, chaduke, clems4ever, cozzetti, datapunk, imare, immeas, kaliberpoziomka8552, ladboy233, pauliax, peritoflores, rvierdiiev, sces60107, sk8erboy, stealthyz, unforgiven, wagmi, wallstreetvilkas, yixxas
9.9345 USDC - $9.93
https://github.com/code-423n4/2022-12-gogopool/blob/aec9928d8bdce8a5a4efe45f54c39d4fc7313731/contracts/contract/MinipoolManager.sol#L241-L246 https://github.com/code-423n4/2022-12-gogopool/blob/aec9928d8bdce8a5a4efe45f54c39d4fc7313731/contracts/contract/MinipoolManager.sol#L163-L164
By calling the function createMinipool(...)
the minipool with status Withdrawable
may be overwritten to a new minipool with the same minipoolIndex
which will cause losing funds that should be withdrawn.
The function createMinipool(...)
may create a new minipool with the minipoolIndex
the same as existing minipool (here). However, the function requireValidStateTransition(...)
that checks the valid state transition, allows for changing the state to be changed from Withdrawable
to PreLaunch
(here), which is the state that is set by createMinipool(...)
. This effectively allows for overwriting existing pool in Withdrawable
state and makes it impossible to withdraw funds from the minipool by the owner.
Manual review.
Consider not allowing the minipool in Withdrawable
state to be overwritten with the createMinipool(...)
function.
#0 - c4-judge
2023-01-09T12:37:54Z
GalloDaSballo marked the issue as duplicate of #213
#1 - c4-judge
2023-02-03T12:33:01Z
GalloDaSballo changed the severity to 2 (Med Risk)
#2 - c4-judge
2023-02-03T19:26:10Z
GalloDaSballo changed the severity to 3 (High Risk)
#3 - c4-judge
2023-02-08T08:26:45Z
GalloDaSballo changed the severity to 2 (Med Risk)
#4 - c4-judge
2023-02-08T08:50:11Z
GalloDaSballo changed the severity to 3 (High Risk)
#5 - c4-judge
2023-02-08T20:28:51Z
GalloDaSballo marked the issue as satisfactory
#6 - c4-judge
2023-02-09T08:53:06Z
GalloDaSballo changed the severity to QA (Quality Assurance)
#7 - Simon-Busch
2023-02-09T12:53:45Z
Changed severity back from QA to H as requested by @GalloDaSballo
🌟 Selected for report: 0xdeadbeef0x
Also found by: 0Kage, 0xc0ffEE, 0xmint, AkshaySrivastav, Allarious, Ch_301, Franfran, HollaDieWaldfee, IllIllI, Jeiwan, Lirios, Manboy, adriro, ak1, bin2chen, caventa, chaduke, clems4ever, cozzetti, datapunk, imare, immeas, kaliberpoziomka8552, ladboy233, pauliax, peritoflores, rvierdiiev, sces60107, sk8erboy, stealthyz, unforgiven, wagmi, wallstreetvilkas, yixxas
9.9345 USDC - $9.93
Any address may overwrite any existing minipool in the state Finished
, Canceled
, Error
or Withdrawable
.
A malicious user may overwrite the minipool in Withdrawable
state, causing a loss of funds for the current owner of minipool.
The function createMinipool(...)
allows for updating existing minipool (here). However it is not checked if the caller of createMinipool(...)
is the owner of this minipool. That allows any address to overwrite an existing minipool, if this minipool is in state: Finished
, Canceled
, Error
or Withdrawable
, effectively resetting all minipool's data and setting the caller as an owner.
Since minipool in state Withdrawable
may be overwtiten to a new minipool (described in issue: "Minipool with state Withdrawable can be overwritten") this leads to possibility of blocking node operator from withdrawing funds, consider scenario:
nodeID = 1
Withdrawable
createMinipool(...)
with nodeID = 1
Note: malicious user must be staking ggp token.
Manual review
When updating the minipool with createMinipool(...)
, consider asserting that the caller is the owner of updated minipool.
#0 - 0xminty
2023-01-04T00:05:55Z
dupe of #805
#1 - c4-judge
2023-01-09T12:37:29Z
GalloDaSballo marked the issue as duplicate of #213
#2 - c4-judge
2023-02-03T12:33:01Z
GalloDaSballo changed the severity to 2 (Med Risk)
#3 - c4-judge
2023-02-03T19:26:10Z
GalloDaSballo changed the severity to 3 (High Risk)
#4 - c4-judge
2023-02-08T08:26:46Z
GalloDaSballo changed the severity to 2 (Med Risk)
#5 - c4-judge
2023-02-08T08:50:12Z
GalloDaSballo changed the severity to 3 (High Risk)
#6 - c4-judge
2023-02-08T20:28:39Z
GalloDaSballo marked the issue as satisfactory
#7 - c4-judge
2023-02-09T08:53:06Z
GalloDaSballo changed the severity to QA (Quality Assurance)
#8 - Simon-Busch
2023-02-09T12:53:56Z
Changed severity back from QA to H as requested by @GalloDaSballo
🌟 Selected for report: 0xbepresent
Also found by: 0Kage, Atarpara, Ch_301, Manboy, cozzetti, datapunk, immeas, kaliberpoziomka8552, peritoflores, rvierdiiev, sces60107, unforgiven, wagmi, yixxas
57.1995 USDC - $57.20
Using the function finishFailedMinipoolByMultisig(...)
when minipool is in error state, will block the node operator from withdrawing the deposit.
The function finishFailedMinipoolByMultisig(...)
changes the state of minipool from Error
to Finished
. When minipool is in the state Finished
the node operator can't withdraw deposit, since withdrawing deposit is possible only by calling cancelMinipool(...)
or withdrawMinipoolFunds(...)
i.e. from states: Prelaunch
, Withdrawable
or Error
.
Manual review
Consider returning deposit amount to the owner of minipool in function finishFailedMinipoolByMultisig(...)
.
#0 - c4-judge
2023-01-10T10:00:21Z
GalloDaSballo marked the issue as duplicate of #175
#1 - c4-judge
2023-01-29T15:28:54Z
GalloDaSballo marked the issue as duplicate of #723
#2 - c4-judge
2023-02-08T20:13:48Z
GalloDaSballo marked the issue as satisfactory
🌟 Selected for report: imare
Also found by: 0Kage, 0xbepresent, AkshaySrivastav, Faith, HollaDieWaldfee, Jeiwan, Saintcode_, betweenETHlines, btk, dic0de, enckrish, gz627, imare, jadezti, kaliberpoziomka8552, nogo, simon135, sk8erboy
34.7487 USDC - $34.75
https://github.com/code-423n4/2022-12-gogopool/blob/aec9928d8bdce8a5a4efe45f54c39d4fc7313731/contracts/contract/MinipoolManager.sol#L236 https://github.com/code-423n4/2022-12-gogopool/blob/aec9928d8bdce8a5a4efe45f54c39d4fc7313731/contracts/contract/MultisigManager.sol#L80-L91
Most minipools will have the same multisig, which makes one address responsible for most minipools management.
During creation of minipool, the multisig address is returned from multisigManager.requireNextActiveMultisig()
. However, the function requireNextActiveMultisig()
always returns first enabled multisig, which will result in most minipools having the same multisig address.
Manual review
Consider diversifying multisig addresses assigned to minipools.
#0 - c4-judge
2023-01-08T13:26:17Z
GalloDaSballo marked the issue as duplicate of #702
#1 - c4-judge
2023-02-08T19:58:17Z
GalloDaSballo marked the issue as satisfactory
🌟 Selected for report: hansfriese
Also found by: 0Kage, 0xdeadbeef0x, Allarious, Aymen0909, Ch_301, Franfran, HollaDieWaldfee, Jeiwan, Nyx, RaymondFam, SmartSek, adriro, betweenETHlines, bin2chen, cccz, datapunk, immeas, kaliberpoziomka8552, peritoflores, wagmi
10.8565 USDC - $10.86
The node operator may withdraw the same AVAX deposit amount multiple times.
Recreated minipool still has the originally deposited AVAX amount in storage, even though this deposit was already withdrawn by calling withdrawMinipoolFunds(...)
(here). This allows for multiple withdrawals of deposit amount of AVAX but only once sending AVAX to protocol (on creation of minipool). Consider scenario:
Withdrawable
state and the node operator withdraws deposit and rewardsrecreateMinipool(...)
to recreate minipoolWithdrawable
state again, the node operator can withdraw deposit againThe amount of provided deposit is only reset when the minipool is updated with createMinipool(...)
, but not with recreateMinipool(...)
.
Maunal review
Consider resetting the amount of the deposit when recreating the minipool.
#0 - c4-judge
2023-01-09T12:58:11Z
GalloDaSballo marked the issue as duplicate of #484
#1 - c4-judge
2023-01-09T12:58:15Z
GalloDaSballo marked the issue as partial-50
#2 - GalloDaSballo
2023-01-09T12:58:36Z
Less grounded in reality (front-run is necessary), but ultimately shows a wrong FSM state so valid
#3 - c4-judge
2023-02-03T12:41:05Z
GalloDaSballo marked the issue as duplicate of #569
#4 - c4-judge
2023-02-08T08:27:15Z
GalloDaSballo changed the severity to 2 (Med Risk)
#5 - c4-judge
2023-02-09T08:45:54Z
GalloDaSballo changed the severity to QA (Quality Assurance)
#6 - Simon-Busch
2023-02-09T12:37:23Z
Changed the severity back to M as requested by @GalloDaSballo
🌟 Selected for report: HollaDieWaldfee
Also found by: Allarious, Aymen0909, Saintcode_, SmartSek, adriro, bin2chen, cccz, kaliberpoziomka8552, minhtrng, rvierdiiev, sces60107, sk8erboy, wagmi
34.0473 USDC - $34.05
https://github.com/code-423n4/2022-12-gogopool/blob/aec9928d8bdce8a5a4efe45f54c39d4fc7313731/contracts/contract/MinipoolManager.sol#L484-L515 https://github.com/code-423n4/2022-12-gogopool/blob/aec9928d8bdce8a5a4efe45f54c39d4fc7313731/contracts/contract/MinipoolManager.sol#L437
Setting minipool into Error
state and withdrawing funds, would cause incorrect minipool count.
After the function recordStakingError(...)
is called by the multisig, the node operator may withdraw funds only by calling withdrawMinipoolFunds(...)
. This way the minipool count for the node operator is not decreased, because it is only decreased by calling cancelMinipool(...)
and recordStakingEnd(...)
.
Maunal review
Consider decreasing minipool count in the function recordStakingError(...)
or allowing node operator to call cancelMinipool(...)
after the error is registered.
#0 - GalloDaSballo
2023-01-07T10:49:31Z
Similar to other reports, but doesn't show impact / attack, will prob award a small %
#1 - c4-judge
2023-01-10T20:36:52Z
GalloDaSballo marked the issue as duplicate of #235
#2 - GalloDaSballo
2023-01-10T20:37:00Z
50% because it got the issue right, but not the impact
#3 - c4-judge
2023-01-10T20:37:05Z
GalloDaSballo marked the issue as partial-50
#4 - c4-judge
2023-02-08T19:40:31Z
GalloDaSballo marked the issue as satisfactory
#5 - c4-judge
2023-02-08T19:41:00Z
GalloDaSballo marked the issue as partial-50