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: 60/111
Findings: 1
Award: $118.88
🌟 Selected for report: 0
🚀 Solo Findings: 0
118.8832 USDC - $118.88
https://github.com/code-423n4/2022-12-gogopool/blob/aec9928d8bdce8a5a4efe45f54c39d4fc7313731/contracts/contract/MinipoolManager.sol#L380-L440 https://github.com/code-423n4/2022-12-gogopool/blob/aec9928d8bdce8a5a4efe45f54c39d4fc7313731/contracts/contract/MinipoolManager.sol#L667-L683
GoGoPool uses staked GGP to compensate users for not receiving the avax rewards in the case where Node operators fails to validate sufficiently and earn validation rewards.
A minimum staked GGP collateral of 10% is required before a minipool can be created which can potentially compensate up to 12 months of a failed validation period as the avax reward rate is estimate at 10%. In which case the 10% GGP can be converted to avax and sent to the users.
The protocol uses the price of GGP in AVAX in order to calculate the amount of GGP required to stake as collateral and at a later phase also the amount of GGP required to slashed to compensate the users.
The problem lies in that price of GGP can vary in such a way where the 10% collateral can become less than 10% by the time the slashing is happening, the minipool would have been created and running for a year afterwhich ending the minipool(Minipool.recordStakingEnd()) would revert because the node operator would not have staked sufficient GGP to cover the slashing due to a price drop of GGP when compared to the price of GGP during the creation of the minipool.
While the users can potentially still receive their rewards and their staked AVAX through manual efforts with the protocol team (also kinda going against the essence of decentralized protocol), there could be a slightly better solution to at least enforcing the slashing.
This is how collateral ratio is calculated Link to full code
uint256 ggpStakedInAvax = getGGPStake(stakerAddr).mulWadDown(ggpPriceInAvax); return ggpStakedInAvax.divWadDown(avaxAssigned);
This is how the ggp slashing amount is calculated Link to full code
return avaxRewardAmt.divWadDown(ggpPriceInAvax);
When creating a minipool the 10% minimum collateral ratio is enforced here
So assuming the below at the time a minipool is being created: minipool duration = 1 year avaxAssigned = 1000 ggpPriceInAvax = 2 Therefore min collateral value required = 100 avax required ggpCollateralAmount = 50 ggp
1 year later at validation end with failed validation, slashing should occur although assuming ggpPrice decreased: EstimatedRewardAmount (to users)= 100 avax ggpPriceInAvax = 1 Therfore ggp reqruired = 100 ggp
User's staked amount was only 50 ggp as that was sufficient during the time of minipool creation and due to this slashing will revert because the Node operation would not have enough ggp staked so the Staking.decreaseGGP() function will fail this would lead the Node operator not getting penalilzed
VSCode
Staking.slashGGP() can check if the ggpAmt is greater than the total amount of ggp staked by the staker and if so use the total amount of ggp staked, at least that way slashing can be enforced to still penalize the failed validation. These can used for either additional rewards to the users or possibly just burned
function slashGGP(address stakerAddr, uint256 ggpAmt) public onlySpecificRegisteredContract("MinipoolManager", msg.sender) { Vault vault = Vault(getContractAddress("Vault")); stakedggpAmt = getGGPStake(stakerAddr); ggpAmt = if(ggpAmt>stakedggpAmt)?stakedggpAmt:ggpAmt; decreaseGGPStake(stakerAddr, ggpAmt); vault.transferToken("ProtocolDAO", ggp, ggpAmt); }
#0 - c4-judge
2023-01-09T09:47:04Z
GalloDaSballo marked the issue as duplicate of #136
#1 - c4-judge
2023-02-03T19:37:10Z
GalloDaSballo marked the issue as not a duplicate
#2 - c4-judge
2023-02-03T19:40:43Z
GalloDaSballo changed the severity to 3 (High Risk)
#3 - c4-judge
2023-02-03T19:56:23Z
GalloDaSballo marked the issue as duplicate of #494
#4 - c4-judge
2023-02-03T19:58:50Z
GalloDaSballo changed the severity to 2 (Med Risk)
#5 - c4-judge
2023-02-08T20:16:53Z
GalloDaSballo marked the issue as satisfactory