Beatland Festival

First Flight #44
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Impact: high
Likelihood: medium
Invalid

Owner can't withdraw funds

Description:

Owner can't withdraw funds with the ::withdraw:: function because this function is actually using "transfer" for sending eth that's is limited to 2300 gas. And the function is actually more than 2300 gas so eth can't be send. That lead to fund that are stuck in the protocol.

payable(target).transfer(address(this).balance);

Risk

Likelihood:

  • Everytime owner try to withdraw.

Impact:

  • Funds can't be withdrawn by owner

  • No other way to withdraw so funds are basically stuck in the protocol (side effect)

Proof of Concept:

As we know ::transfer:: function is limited by a max of 2300 gas, so we are going to use test to see if simulate a withdraw actually break thats maximum of gas. Please copy paste this test to "FestivalPass.t.sol"

function test_GasOnWithdrawFunction() public {
vm.deal(address(festivalPass), 20 ether);
vm.startPrank(owner);
uint256 gasBefore = gasleft();
festivalPass.withdraw(address(this));
uint256 gasUsed = gasBefore - gasleft();
vm.stopPrank();
uint256 maxGasForTransferFunction = 2300;
assertLe(gasUsed, maxGasForTransferFunction);
}
//don't forget to add this to simulate correctly
receive() external payable {}

After that we can see that the assertion is broke : └─ ← [Revert] assertion failed: 10460 > 2300

Recommended Mitigation:

I would recommend you to avoid ::transfer:: function for native eth and use instead this method :

- payable(target).transfer(address(this).balance);
+ (bool success, ) = payable(target).call{value: amount}("");
+ require(success, "Transfer failed");
Updates

Lead Judging Commences

inallhonesty Lead Judge 28 days ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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