Closed sherlock-admin2 closed 3 months ago
Escalate
Admin function Lack of Access Control
Escalate
Admin function Lack of Access Control
The escalation could not be created because you are not exceeding the escalation threshold.
You can view the required number of additional valid issues/judging contest payouts in your Profile page, in the Sherlock webapp.
Escalate
Admin function Lack of Access Control
There is no clear impact, provide more information if you think it's valid
@MxAxM
The function predictDistributorAddress
is public, allowing us to predict the Distributor Address.
The deployDistributor
function uses the cloneDeterministic
function. The actual problem arises from this. This function uses the create2
opcode and a salt
to deterministically deploy the clone. Using the same implementation
and salt
multiple time will cause a revert.
Malicious actors can precompute the addresses of new distributors before they are deployed. This predictability can be exploited in several ways:
As a result, the admin cannot deploy the distributor because it will revert. An attacker can precompute the address of a new distributor and deploy a malicious contract at that address before the legitimate user.
distributor = PerAddressContinuousVestingMerkleDistributor(Clones.cloneDeterministic(i_implementation, salt));
distributors.push(address(distributor));
Clones.cloneDeterministic
/**
* @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
*
* This function uses the create2 opcode and a `salt` to deterministically deploy
* the clone. Using the same `implementation` and `salt` multiple times will revert, since
* the clones cannot be deployed twice at the same address.
*/
function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {
/// @solidity memory-safe-assembly
assembly {
// Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes
// of the `implementation` address with the bytecode before the address.
mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))
// Packs the remaining 17 bytes of `implementation` with the bytecode after the address.
mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))
instance := create2(0, 0x09, 0x37, salt)
}
require(instance != address(0), "ERC1167: create2 failed");
}
There is no benefit for attacker, also it doesn't block deploying new distributors, owner can simply use a different nonce for deployment
@MxAxM
If an attacker successfully deploys a malicious or dummy contract at the predicted address, the legitimate owner would need to use a different nonce for deployment. This process can lead to increased gas costs for the owner, as they may need to iterate through multiple nonce values until they find an available address.
The attacker can precompute the address and deploy a malicious contract before the owner, preventing the owner from deploying the distributor at the intended address.
That's not an attack. That's actually saving gas costs for the owner. There is no way to deploy to the owner's predicted address without also transferring control to said owner.
hunter_w3b
medium
Lack of Access Control in deployDistributor Function
Summary
The deployDistributor function in the
PerAddressContinuousVestingMerkleDistributorFactory
andPerAddressContinuousVestingMerkleDistributorFactory
contract lacks access control, allowing anyone to deploy a new distributor. This function should be restricted to authorized entities to prevent unauthorized deployments.Vulnerability Detail
The deployDistributor function is publicly accessible, meaning any user can call this function and deploy a new PerAddressContinuousVestingMerkleDistributor contract. This function should ideally be restricted to the contract owner or an authorized entity to prevent unauthorized deployments.
Impact
Unintended Deployments:
Predictable Addresses:
Code Snippet
https://github.com/sherlock-audit/2024-05-tokensoft-distributor-contracts-update/blob/main/contracts/packages/hardhat/contracts/claim/factory/PerAddressContinuousVestingMerkleDistributorFactory.sol#L39-L68
https://github.com/sherlock-audit/2024-05-tokensoft-distributor-contracts-update/blob/main/contracts/packages/hardhat/contracts/claim/factory/PerAddressContinuousVestingMerkleDistributorFactory.sol#L39-L68
Tool used
Manual Review
Recommendation
Implement access control using OpenZeppelin's Ownable contract to restrict the deployDistributor function to the contract owner. This will prevent unauthorized entities from deploying new distributors.