- High: 1
- Medium: 0
- Low: 2
Unexpected behavior regarding setContest
and deployProxyAndDistribute
There are 3 scenarios:
- The sponsors can sent tokens to a expired contest since there is no reset/check. This will result in locking of funds or the next scenario.
- It is possible to run
deployProxyAndDistribute
more than once. It will pass all checks and since there is funds in the contract, it will double spend and send tokens to winner addresses. - New contests with same
salt
will not be initialized even though the old contest has expired.
Possible double spending and locking of funds in contract
Manual review
The best solution I can think of is setting:
saltToCloseTime[salt]=0
after each of the deployProxyAndDistribute
functions.
- Vulnerability #1 is solved. Use a check for sponsors while sending tokens to the contract that the
saltToCloseTime[salt]>0
. - Vulnerability #2 is solved.
deployProxyAndDistribute
cannot be run more than once since there is check for!saltToCloseTime[salt]>0
- Vulnerability #3 is solved. New contests with same
salt
can be set
No Address(0) check for Winners in the array
winners
array length is checked. However, the individual addresses are not checked for 0x00 address. This may cause loss of funds by sending tokens to Address(0)
Loss of Funds. Irrecoverable
Manual Review
Put a address(0) check inside the loop which is used to send tokens to the winner addresses. In Distributor.sol
for (uint256 i; i < winnersLength; ) {
if(winners[i]==address(0)){
revert Distributor__NoZeroAddress()();
}
//remaining logic
}
In ProxyFactory.sol
, the implementation address is required to be passed in every function as a parameter. This may not be best practice as this is prone to mistakes/typos.
Moreover, there is no upgradability function in the ProxyFactory.sol
. In case there is any changes required to the implementation contract, the new address will have to be passed which again may result in mistakes.
The variable implementation
which holds the address of the logic contract is required to be passed in as a parameter in each function. This is not required as the the address will be the same unless upgraded.
If a contest is set with a wrong implementation address, there is no way to recover from that other than redeploying with the correct address again. Instead of manually passing the variable each time, it can be read from a state variable directly.
Manual review
Two steps:
- Create a state variable called
s_implementation
and initialize it later using the next step
address public s_implementation;
- Create an
upgrade
function which allows the OWNER ONLY to change the implementaion address
function upgradeImplementation(address _newImplementation) public onlyOwner{
if(_newImplementation==address(0)){
revert ProxyFactory__NoZeroAddress();
}
s_implementation=_newImplementation;
}