pragma solidity 0.8.29;
import {Test, console} from "forge-std/Test.sol";
import {WeatherNft} from "src/WeatherNft.sol";
import {LinkTokenInterface} from "@chainlink/contracts/src/v0.8/shared/interfaces/LinkTokenInterface.sol";
contract WeatherNftWithdrawalTest is Test {
WeatherNft weatherNft;
LinkTokenInterface linkToken;
address owner = makeAddr("owner");
address user = makeAddr("user");
function setUp() external {
weatherNft = WeatherNft(0x4fF356bB2125886d048038386845eCbde022E15e);
linkToken = LinkTokenInterface(0x0b9d5D9136855f6FEc3c0993feE6E9CE8a297846);
vm.deal(user, 10 ether);
deal(address(linkToken), user, 100e18);
}
function test_stuckFunds() public {
uint256 initialContractETH = address(weatherNft).balance;
uint256 initialContractLINK = linkToken.balanceOf(address(weatherNft));
vm.startPrank(user);
uint256 mintPrice = weatherNft.s_currentMintPrice();
weatherNft.requestMintWeatherNFT{value: mintPrice}(
"125001",
"IN",
false,
12 hours,
0
);
vm.stopPrank();
vm.prank(user);
linkToken.transfer(address(weatherNft), 5e18);
uint256 finalContractETH = address(weatherNft).balance;
uint256 finalContractLINK = linkToken.balanceOf(address(weatherNft));
console.log("ETH in contract:", finalContractETH);
console.log("LINK in contract:", finalContractLINK);
bytes4[] memory selectors = new bytes4[](0);
bool hasWithdrawFunction = false;
bytes4[] memory commonWithdrawFunctions = new bytes4[](5);
commonWithdrawFunctions[0] = bytes4(keccak256("withdraw()"));
commonWithdrawFunctions[1] = bytes4(keccak256("withdrawETH()"));
commonWithdrawFunctions[2] = bytes4(keccak256("withdrawLink()"));
commonWithdrawFunctions[3] = bytes4(keccak256("withdrawTokens(address)"));
commonWithdrawFunctions[4] = bytes4(keccak256("emergencyWithdraw()"));
for (uint i = 0; i < commonWithdrawFunctions.length; i++) {
(bool success, ) = address(weatherNft).staticcall(abi.encodeWithSelector(commonWithdrawFunctions[i]));
if (success) {
hasWithdrawFunction = true;
break;
}
}
console.log("Contract has withdrawal function:", hasWithdrawFunction);
assertFalse(hasWithdrawFunction, "Withdraw function exists, vulnerability not confirmed");
assertGt(finalContractETH, initialContractETH, "No ETH added to contract");
assertGt(finalContractLINK, initialContractLINK, "No LINK added to contract");
console.log("VULNERABILITY CONFIRMED: Funds are stuck in the contract");
}
}