Sparkn

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

Difficulty in getting Proxy address before deployment lead to wrong address funding

Summary

The ProxyFactory::getProxyAddress() intakes salt and implementation parameter. However, the salt value is unknown to the user before deployment. This may cause the user to send the funds to the wrong proxy address.

Vulnerability Details

  1. The salt value is calculated when setting up the contest through ProxyFactory::setContest(). However setContest()
    function doesn't return or emit a salt value. It's difficult for organizers.

  2. Also the ProxyFactory::_calculateSalt() is an internal function. It's not callable to calculate salt for organizers.

  3. The getProxyAddress() also intakes salt before deployment, the salt value is unknown to organizers.

Impact

  • It gives much more difficult for non-technical knowledge-based organizers to calculate proxy address without correct salt.

  • It may lead to a potential temporary loss of funds if the organizer calculates the proxy address incorrectly with incorrect salt

Tools Used

Manual Review

Recommendations

The getProxyAddress() function should be refactored to a more detailed parameter intake:

//Added _organizer param
function getProxyAddress(address _organizer, bytes32 contestId, address implementation) public view returns (address proxy) {
bytes32 salt = _calculateSalt(_organizer, contestId, implementation);
bytes memory code = abi.encodePacked(type(Proxy).creationCode, uint256(uint160(implementation)));
bytes32 hash = keccak256(abi.encodePacked(bytes1(0xff), address(this), salt, keccak256(code)));
proxy = address(uint160(uint256(hash)));
}

OR

  • _calculateSalt() should be a public function.

OR

  • setContest() should emit or return the salt value.

event SetContest(
address indexed organizer, bytes32 indexed contestId, uint256 closeTime, address indexed implementation, bytes32 indexed salt
);
function setContest(address organizer, bytes32 contestId, uint256 closeTime, address implementation)
public
onlyOwner
returns(bytes32 salt)
{
if (organizer == address(0) || implementation == address(0)) revert ProxyFactory__NoZeroAddress();
if (closeTime > block.timestamp + MAX_CONTEST_PERIOD || closeTime < block.timestamp) {
revert ProxyFactory__CloseTimeNotInRange();
}
bytes32 salt = _calculateSalt(organizer, contestId, implementation);
if (saltToCloseTime[salt] != 0) revert ProxyFactory__ContestIsAlreadyRegistered();
saltToCloseTime[salt] = closeTime;
emit SetContest(organizer, contestId, closeTime, implementation, salt);
}

Support

FAQs

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