Beginner FriendlyFoundryDeFi
100 EXP
View results
Submission Details
Severity: high
Valid

An attacker can gain unfair advantage for $STEAK airdrop even without staking any ETH

Summary

A user can become eligible for $STEAK airdrop, if they have minted atleast 0.5 eth, in which case they are given 500 points on the off-chain server. According to the protocol, users with more points (i.e., those who staked more ETH) will have a greater opportunity to receive a larger share of the $STEAK token airdrop.

In the main.jsfile , the server only listens for the event when someone stakes ETH and gives them points accordingly in the database.

async function main() {
await connectToMongodb();
const { rpcUrl, steakingAddress } = getConfig();
const provider = new ethers.JsonRpcProvider(rpcUrl);
const steaking = new ethers.Contract(steakingAddress, steakingAbi, provider);
steaking.on(STAKED, async (_, amount, onBehalfOf) => {
let steakPoints;
steakPoints = await steakPointsModel.findOne({ walletAddress: onBehalfOf });
if (!steakPoints) {
steakPoints = new steakPointsModel({
walletAddress: onBehalfOf,
points: +ethers.formatEther(amount) * PRECISION,
});
} else {
steakPoints.points += +ethers.formatEther(amount) * PRECISION;
}
await steakPoints.save();
});
}

However, there is no function that listens for the event when someone unstakes ETH from the protocol, and then deduct the points accordingly.This leaves room for a malicious user to repeatedly stake the minimum stake amount, unstake it, and still gain points each time.

Vulnerability Details

The vulnerability arises because the current implementation of the main.js file only listens for the STAKED event to award points to users based on the amount of ETH they stake. However, there is no corresponding event listener for when users unstake their ETH, meaning the points are not deducted from their accounts when they withdraw their staked ETH.

Exploitation

  1. Attacker stakes 0.5 ether .

  2. Attacker unstakes 0.5 ether.

  3. We observe that they still have 500 points awarded in the server

cast send $STEAKING_CONTRACT_ADDRESS_LOCALHOST "stake(uint256, address)" 0.5ether <ATTACKER_PUBLIC_ADDRESS> --rpc-url <http://127.0.0.1:8545> --private-key <ATTACKER_PRIVATE_KEY>
cast send $STEAKING_CONTRACT_ADDRESS_LOCALHOST "unstake(uint256, address)" 0.5ether <ATTACKER_PUBLIC_ADDRESS> --rpc-url <http://127.0.0.1:8545> --private-key <ATTACKER_PRIVATE_KEY>

Now we observe that the server still has 500 points awarded to the <ATTACKER_PUBLIC_ADDRESS>. Which directly means that upon unstaking, the points are not being deducted from the server.

Impact

  • A malicious user can gain unfair advantages by minting a very large amount of points and get major share from the $STEAK airdrop, when it is released. All of this without even having staked any ETH, which will be unfair to all the legitimate users of the protocol.

  • This loophole could also affect the purpose of bootstrapping liquidity for the WETH vault. This is because if the points are avaliable even after unstaking, majority user may unstake their ETH after obtaining the points on the off-chain server.

  • Hence the severity of this vulnerability is decided to be a high.

Tools Used

manual code review

Recommendations

in the main.jsfile, under the main function, add a function which listens for the unstakedevent and deducts the points correposing to the amount of eth unstaked from the database.

Updates

Lead Judging Commences

inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Steaking server is not taking unstakes into account

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.