Slashing mechanism can be manipulated #215
Labels
2 (Med Risk)
Assets not at direct risk, but function/availability of the protocol could be impacted or leak value
bug
Something isn't working
downgraded by judge
Judge downgraded the risk level of this issue
duplicate-492
satisfactory
satisfies C4 submission criteria; eligible for awards
Lines of code
https://github.com/code-423n4/2022-12-gogopool/blob/aec9928d8bdce8a5a4efe45f54c39d4fc7313731/contracts/contract/MinipoolManager.sol#L257
Vulnerability details
Impact
Node validators can manipulate the slashing mechanism to slash only 0.000003170979198376 AVAX (0.00003691 USD) from GGP stake.
A hacker can create multiple nodes and use all the
ggAVAX
liquidity without actually finishing the validation period.Liquid stakers will not be compensated for the loss.
Hacker will pay less then 1 dollar of GGP.
Proof of Concept
When minipools are created/updated through
createMinipool
there is no check that the duration specified by the node operator is less then the minimum required validation period (14 days).https://github.com/code-423n4/2022-12-gogopool/blob/aec9928d8bdce8a5a4efe45f54c39d4fc7313731/contracts/contract/MinipoolManager.sol#L196
When no rewards are received after the validation period,
slash
is called to slash staked GGP for compensation of the ggAVAX liquid stakers.slash
:https://github.com/code-423n4/2022-12-gogopool/blob/aec9928d8bdce8a5a4efe45f54c39d4fc7313731/contracts/contract/MinipoolManager.sol#L670
As can be seen above, the
duration
set by the node operator is used together with theavaxLiquidStakerAmt
(1000 AVAX) to calculate the expected amount of rewards in order to slash proportionately.The rewards amount is calculated in
getExpectedAVAXRewardsAmt(duration, avaxLiquidStakerAmt)
:https://github.com/code-423n4/2022-12-gogopool/blob/aec9928d8bdce8a5a4efe45f54c39d4fc7313731/contracts/contract/MinipoolManager.sol#L557
The
rate
is set to 0.1 AVAX in the initialization of the dao: https://github.com/code-423n4/2022-12-gogopool/blob/aec9928d8bdce8a5a4efe45f54c39d4fc7313731/contracts/contract/ProtocolDAO.sol#L51Therefore, if the node operator sets
1
asduration
the functiongetExpectedAVAXRewardsAmt
will return3170979198376
WEI of AVAX.Consider the following scenario:
rialto
callsclaimAndInitiateStaking
to launch the minipool (Node-2222)claimAndInitiateStaking
and:4.1 NodeOp calls
cancelMinipool
- This is possible without waiting 5 days because of step Agreements & Disclosures #1 (See other submitted bug Anti griefing mechanism can be bypassed #211: "Anti griefing mechanism can be bypassed"). It is also possible to execute this step without the bug by waiting 5 days.4.2 NodeOp calls
createMinipool
with duration set to1
claimAndInitiateStaking
gets executed and staked.recordStakingEnd
will be called which will call theslash
function as no rewards are set.Foundry POC
The POC will demonstrate the above scenario
Add the following test to
MinipoolManager.t.sol
https://github.com/code-423n4/2022-12-gogopool/blob/aec9928d8bdce8a5a4efe45f54c39d4fc7313731/test/unit/MinipoolManager.t.sol#L175
To run the POC, execute:
Expected output:
Tools Used
VS Code, Foundry
Recommended Mitigation Steps
In
createMinipool
set a minimum requirement ofduration
to 14 days.Additionally, if a NodeID already exists in
createMinipool
, make sure the duration is not changed. If a node operator wishes to change the duration of his NodeID, he should generate a new NodeID.The text was updated successfully, but these errors were encountered: