Sparkn

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

Signature schemes of `deployProxyAndDistributeBySignature()` are potentially dangerous for replay attacks.

Summary

First, the digest variable used in deployProxyAndDistributeBySignature() function has not include the address(this) parameter and block.chainid parameter to limit the using scope of the signature only in this contract.

Second, attacker can call deployProxyAndDistributeBySignature() function multiple times with one signature. The signature can replay in this contract.

Vulnerability Details

The digest variable is related with contestId and data, but not address(this) and block.chainid. It has not mark down these signature which have been used.

bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(contestId, data)));

Impact

If there has orther project which using the same implementation scheme for signature, this signature can be replalyed from Sparkn
to other projects or from other projects to Sparkn
.
One signature can replay in this contract to call _distribute() multiple times.

Tools Used

Manual

Recommendations

Recommend to fix the ProxyFactory.deployProxyAndDistributeBySignature() function as follow.

mapping(bytes32 => bool) public signatureIsUsed;
function deployProxyAndDistributeBySignature(
address organizer,
bytes32 contestId,
address implementation,
bytes calldata signature,
bytes calldata data
) public returns (address) {
bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(contestId, data, address(this), block.chainid)));
if (ECDSA.recover(digest, signature) != organizer) revert ProxyFactory__InvalidSignature();
if (signatureIsUsed[signature] == true){
revert();
}else{
signatureIsUsed[signature] = true;
}
bytes32 salt = _calculateSalt(organizer, contestId, implementation);
if (saltToCloseTime[salt] == 0) revert ProxyFactory__ContestIsNotRegistered();
if (saltToCloseTime[salt] > block.timestamp) revert ProxyFactory__ContestIsNotClosed();
address proxy = _deployProxy(organizer, contestId, implementation);
_distribute(proxy, data);
return proxy;
}

Support

FAQs

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

Give us feedback!