The start time of the vesting contract can be set to any value.
Summary
While deploying vesting contract the vestingStart value can be set to any arbitrary value.
Vulnerability Detail
VestingEscrowFactory.sol
In function deployVestingContract() there is no check to ensure vestingStart value to be a valid value and as End time also depends on vestingStart value (endTime = vestingStart + vestingDuration) so endTime can be less than block.timestamp also possible.
Impact
It can cause many issues but 1 of the issue I am illustrating here. In below given code vesting escrow is deployed with end Time < block.timestamp.
function setUp() public {setUpProtocol(ProtocolConfig({owner: address(1), manager: address(2)}));deployVestingEscrow(VestingEscrowConfig({amount: 1 ether,recipient: address(this),vestingDuration: 1000,vestingStart: uint40(block.timestamp-1500),cliffLength: 500,isFullyRevokable: true,initialDelegateParams: new bytes(0)}));}
Claim can be made immediately after vestingEscrow deployment. Run below test.
function testClaimImmediatlyAfterdeployment() public {assertEq(token.balanceOf(recipient), 0);vm.prank(recipient);assertEq(deployedVesting.claim(recipient, type(uint256).max), amount);assertEq(token.balanceOf(recipient), amount);}
psb01
medium
The start time of the vesting contract can be set to any value.
Summary
While deploying vesting contract the vestingStart value can be set to any arbitrary value.
Vulnerability Detail
VestingEscrowFactory.sol In function deployVestingContract() there is no check to ensure vestingStart value to be a valid value and as End time also depends on vestingStart value (endTime = vestingStart + vestingDuration) so endTime can be less than block.timestamp also possible.
Impact
It can cause many issues but 1 of the issue I am illustrating here. In below given code vesting escrow is deployed with end Time < block.timestamp.
function setUp() public {
setUpProtocol(ProtocolConfig({owner: address(1), manager: address(2)}));
deployVestingEscrow(
VestingEscrowConfig({
amount: 1 ether,
recipient: address(this),
vestingDuration: 1000,
vestingStart: uint40(block.timestamp-1500),
cliffLength: 500,
isFullyRevokable: true,
initialDelegateParams: new bytes(0)
})
);
}
Claim can be made immediately after vestingEscrow deployment. Run below test.
function testClaimImmediatlyAfterdeployment() public {
assertEq(token.balanceOf(recipient), 0);
vm.prank(recipient);
assertEq(deployedVesting.claim(recipient, type(uint256).max), amount);
assertEq(token.balanceOf(recipient), amount);
}
Code Snippet
VestingEscrowFactory.sol
Tool used
Manual Review
Recommendation
check should be applied to ensure vestingStart >= block.timestamp.
Duplicate of #101