Weather Witness

First Flight #40
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Severity: high
Valid

Locked ETH inside the contract, because there is no withdraw function

Root + Impact

Description

  • The contract WeatherNft.sol can receive ETH through requestMintWeatherNFT(), which is a payable function

  • This happens via msg.value, which is the price to pay for a NFT

  • However, there is no way of withdrawing or sending ETH out of the contract, which makes the funds stuck inside the contract

function requestMintWeatherNFT(
string memory _pincode,
string memory _isoCode,
bool _registerKeeper,
uint256 _heartbeat,
uint256 _initLinkDeposit
) external payable returns (bytes32 _reqId) {
// @audit-issue Locked ETH, no withdraw function
require(
msg.value == s_currentMintPrice,
WeatherNft__InvalidAmountSent()
);
s_currentMintPrice += s_stepIncreasePerMint;
if (_registerKeeper) {
IERC20(s_link).safeTransferFrom(
msg.sender,
address(this),
_initLinkDeposit
);
}
_reqId = _sendFunctionsWeatherFetchRequest(_pincode, _isoCode);
emit WeatherNFTMintRequestSent(msg.sender, _pincode, _isoCode, _reqId);
s_funcReqIdToUserMintReq[_reqId] = UserMintRequest({
user: msg.sender,
pincode: _pincode,
isoCode: _isoCode,
registerKeeper: _registerKeeper,
heartbeat: _heartbeat,
initLinkDeposit: _initLinkDeposit
});
}

Risk

Likelihood:

  • Reason 1 This is a general issue of the contract, that will happen everytime

  • Reason 2 Every time an amount is sent to the contract this gets blocked inside

Impact:

  • Impact 1 Locked funds

  • Impact 2 Owner not able to use mint funds




Proof of Concept

Recommended Mitigation

Add a withdraw function, to allow the owner to withdraw ETH from the contract to a desired address.
The function also checks that the recipient address is valid and the amount to withdraw does not exceed the contract balance.

/**
* @notice Allows the contract owner to withdraw ETH from the contract
* @param to The address to send ETH to
* @param amount The amount of ETH to withdraw (in wei)
*/
function withdraw(address payable to, uint256 amount) external onlyOwner {
require(to != address(0), "Invalid recipient address");
require(address(this).balance >= amount, "Insufficient ETH balance");
(bool success, ) = to.call{value: amount}("");
require(success, "Transfer failed");
}
Updates

Appeal created

bube Lead Judge 4 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Lack of `withdraw` function

The contract collects funds for minting a WeatherNFT, but there is no function that allows the owner to withdraw these funds.

Support

FAQs

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