Sparkn

CodeFox Inc.
DeFiFoundryProxy
15,000 USDC
View results
Submission Details
Severity: low
Valid

Low level call returns true if the address doesn’t exist

Summary

The proxy forwards all requests to the distributor using delegatecall, but it's never checked whether the distributor address actually exists or possesses code. If that's not the case, delegatecall still returns True, and it's assumed that everything is functioning correctly.

Vulnerability Details

Here's a PoC demonstrating that even if the distributor address doesn't exist, there is no revert, and it's assumed that everything has worked correctly. (Test can be added in test/integration/ProxyFactoryTest.t.sol)

function testNoRevertIfDistributorNotExist() public {
//Owner sets up contest and makes a mistake with the distributor address
address wrongDistributorAddress = 0x29D7d1dd5B6f9C864d9db560D72a247c178aE86B;
vm.startPrank(factoryAdmin);
bytes32 randomId = keccak256(abi.encode("Jason", "001"));
proxyFactory.setContest(organizer, randomId, block.timestamp + 8 days, wrongDistributorAddress);
vm.stopPrank();
bytes32 salt = keccak256(abi.encode(organizer, randomId, wrongDistributorAddress));
address proxyAddress = proxyFactory.getProxyAddress(salt, wrongDistributorAddress);
//Sponsors send tokens to proxy
vm.startPrank(sponsor);
MockERC20(jpycv2Address).transfer(proxyAddress, 10000 ether);
vm.stopPrank();
bytes memory data = createData();
//Check that the addresses have no tokens before distribution
assertEq(MockERC20(jpycv2Address).balanceOf(user1), 0);
assertEq(MockERC20(jpycv2Address).balanceOf(stadiumAddress), 0);
//The organizer is trying to distribute tokens and assumes that everything is working
vm.warp(9 days);
vm.startPrank(organizer);
proxyFactory.deployProxyAndDistribute(randomId, wrongDistributorAddress, data);
vm.stopPrank();
//Winner and StadiumAddress did not receive any tokens
assertEq(MockERC20(jpycv2Address).balanceOf(user1), 0);
assertEq(MockERC20(jpycv2Address).balanceOf(stadiumAddress), 0);
}

Impact

Events are being emitted stating that the tokens have been distributed, even though it hasn't actually worked. Systems tracking these events might potentially be 'confused'

Tools Used

Manual Review, VSCode

Recommendations

Add a function to ProxyFactory that checks for code presence or existence of the Distributor Address when setting up the Contest.

function isContract(address _addr) private returns (bool isContract){
uint32 size;
assembly {
size := extcodesize(_addr)
}
return (size > 0);
}

Add this line to the setContest function:

if(!isContract(implementation)) revert ProxyFactory__ImplementationNotExists();

If you run the PoC now, there should be a revert with the custom error.

Support

FAQs

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