Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Users should still be slashed the total amount of their GGP staked even if they do not meet the calculated amount #561

Closed
code423n4 opened this issue Jan 3, 2023 · 7 comments
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-494 satisfactory satisfies C4 submission criteria; eligible for awards

Comments

@code423n4
Copy link
Contributor

Lines of code

https://github.com/code-423n4/2022-12-gogopool/blob/aec9928d8bdce8a5a4efe45f54c39d4fc7313731/contracts/contract/MinipoolManager.sol#L670-L683

Vulnerability details

Impact

Currently, slash() will revert if the calculated amount of staked GGP is more than node operator's staked amount as they do not have enough to pay for it. This is problematic as in such situations, the function will revert instead of simply slashing all of their staked amount.

Proof of Concept

Currently, there is a 10% requirement of GGP staked in order for a node operator to create a minipool. This is used as a precaution to compensate liquid stakers if node operator does not fufill its obligations. However, there is no guarantee that this amount is sufficient.

Slash amount is calculated based on the expected AVAX reward amount. It might be possible for this amount to be higher than the minimum GGP staked amount.

MinipoolManager.sol#L670-L683

function slash(int256 index) private {
	address nodeID = getAddress(keccak256(abi.encodePacked("minipool.item", index, ".nodeID")));
	address owner = getAddress(keccak256(abi.encodePacked("minipool.item", index, ".owner")));
	uint256 duration = getUint(keccak256(abi.encodePacked("minipool.item", index, ".duration")));
	uint256 avaxLiquidStakerAmt = getUint(keccak256(abi.encodePacked("minipool.item", index, ".avaxLiquidStakerAmt")));
	uint256 expectedAVAXRewardsAmt = getExpectedAVAXRewardsAmt(duration, avaxLiquidStakerAmt);
	uint256 slashGGPAmt = calculateGGPSlashAmt(expectedAVAXRewardsAmt);
	setUint(keccak256(abi.encodePacked("minipool.item", index, ".ggpSlashAmt")), slashGGPAmt);

	emit GGPSlashed(nodeID, slashGGPAmt);

	Staking staking = Staking(getContractAddress("Staking"));
	staking.slashGGP(owner, slashGGPAmt);
}

When we slash a user, we are subtracting their current staked GGP with slashGGPAmt. This can underflow and revert the slash function if they do not have enough.

Tools Used

Manual Review

Recommended Mitigation Steps

We have a simple and effective fix for this.

We can slash the minimum of slashGGPAmt and staker's GGP stake instead.

- staking.slashGGP(owner, slashGGPAmt);
+ staking.slashGGP(owner, min(slashGGPAmt, getGGPStake(stakerAddr))); 
@code423n4 code423n4 added 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 labels Jan 3, 2023
code423n4 added a commit that referenced this issue Jan 3, 2023
C4-Staff added a commit that referenced this issue Jan 6, 2023
@GalloDaSballo
Copy link

Despite the nuance I think this ultimately is a dup of the reports using a longer duration to cause an overflow and prevent slashing

@c4-judge
Copy link
Contributor

GalloDaSballo marked the issue as duplicate of #136

@c4-judge
Copy link
Contributor

c4-judge commented Feb 3, 2023

GalloDaSballo marked the issue as not a duplicate

@c4-judge c4-judge reopened this Feb 3, 2023
@c4-judge
Copy link
Contributor

c4-judge commented Feb 3, 2023

GalloDaSballo changed the severity to 3 (High Risk)

@c4-judge c4-judge added 3 (High Risk) Assets can be stolen/lost/compromised directly upgraded by judge Original issue severity upgraded from QA/Gas by judge 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value downgraded by judge Judge downgraded the risk level of this issue and removed 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value 3 (High Risk) Assets can be stolen/lost/compromised directly upgraded by judge Original issue severity upgraded from QA/Gas by judge labels Feb 3, 2023
@c4-judge
Copy link
Contributor

c4-judge commented Feb 3, 2023

GalloDaSballo changed the severity to 2 (Med Risk)

@c4-judge
Copy link
Contributor

c4-judge commented Feb 3, 2023

GalloDaSballo marked the issue as duplicate of #494

@c4-judge c4-judge closed this as completed Feb 3, 2023
@c4-judge c4-judge added duplicate-494 satisfactory satisfies C4 submission criteria; eligible for awards labels Feb 3, 2023
@c4-judge
Copy link
Contributor

c4-judge commented Feb 8, 2023

GalloDaSballo marked the issue as satisfactory

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
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-494 satisfactory satisfies C4 submission criteria; eligible for awards
Projects
None yet
Development

No branches or pull requests

3 participants