Griefing Attack Possible Where Validator Will Lose Their Stake #369
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
🤖_03_group
AI based duplicate group recommendation
Lines of code
https://github.com/code-423n4/2024-05-arbitrum-foundation/blob/main/src/assertionStakingPool/AssertionStakingPool.sol#L40
https://github.com/code-423n4/2024-05-arbitrum-foundation/blob/main/src/assertionStakingPool/EdgeStakingPool.sol#L44
Vulnerability details
Proof of Concept
Flow
Create a Pool
: Any validator can use thecreatePool
function to create a newAssertionStakingPool
.Deposit Tokens
: Validators deposit tokens into the staking pool using thedepositIntoPool
function.Create Assertions
: Using the deposited tokens, validators can create new assertions with thecreateAssertion
function.Important things to note about this function
No access control in
createAssertion
.The required stake tokens are directly approved and transferred without verifying the caller's authorization.
Griefing Attack Scenario
Alice creates a new
AssertionStakingPool
and depositsX
tokens.Attacker frontruns Alice by calling
createAssertion
with incorrectassertionInputs
.Alice unknowingly becomes a malicious validator due to the incorrect assertion and loses her stake.
Similar situation will happen with
EdgeStakingPool
contract as well while creating new edge throughcreateEdge
function.Alice creates a new
EdgeStakingPool
and depositsX
tokens.Attacker frontruns Alice by calling
createEdge
with incorrectCreateEdgeArgs
.Alice unknowingly becomes a malicious due to the incorrect edge and loses her stake.
Impact
Validators can lose their stake due to incorrect assertions being made on their behalf.
Tools Used
VS Code
Recommended Mitigation Steps
Implement access control to ensure that only the validator who deposited the tokens can create assertions or edges.
File: AssertionStakingPool.sol function createAssertion(AssertionInputs calldata assertionInputs) external { uint256 requiredStake = assertionInputs.beforeStateData.configData.requiredStake; + require(depositBalance[msg.sender] >= requiredStake); // approve spending from rollup for newStakeOnNewAssertion call IERC20(stakeToken).safeIncreaseAllowance(rollup, requiredStake); // reverts if pool doesn't have enough stake and if assertion has already been asserted IRollupUser(rollup).newStakeOnNewAssertion(requiredStake, assertionInputs, assertionHash, address(this)); }
File: EdgeStakingPool.sol function createEdge(CreateEdgeArgs calldata args) external { uint256 requiredStake = EdgeChallengeManager(challengeManager).stakeAmounts(args.level); + require(depositBalance[msg.sender] >= requiredStake); IERC20(stakeToken).safeIncreaseAllowance(address(challengeManager), requiredStake); bytes32 newEdgeId = EdgeChallengeManager(challengeManager).createLayerZeroEdge(args); if (newEdgeId != edgeId) { revert IncorrectEdgeId(newEdgeId, edgeId); } }
Assessed type
Invalid Validation
The text was updated successfully, but these errors were encountered: