To merge 2 tokens into 1, a user must be either be approved or the owner of both tokens. This is obvious in the checks in merge(...) function
Vulnerability Detail
The merge function has a check to ensure that a third party user has approval to merge any two tokens. And then it cals the _burn(..) function to burn the _from token.
However, the _burn(...) function clears the approval of the _from token. It does this by calling approve(address(0), _tokenId) on the _from token which checks if the caller is the owner or approved for all, but it doesn't allow "regular" approved users to perform this task and hence the call reverts.
CODED POC
Add the test case below to the VotingEscrow.t.sol file and run forge test --mt testApprovedMergeReverts -vvv
address dan = address(0x01);
function testApprovedMergeReverts() public {
flowDaiPair.approve(address(escrow), TOKEN_1);
uint256 lockDuration = 7 * 24 * 3600; // 1 week
// Balance should be zero before and 1 after creating the lock
assertEq(escrow.balanceOf(address(owner)), 0);
uint token1 = escrow.create_lock(TOKEN_1/2, lockDuration);
uint token2 = escrow.create_lock(TOKEN_1/2, lockDuration);
vm.prank(address(owner));
escrow.approve(dan, token1);
vm.prank(dan);
vm.expectRevert();
escrow.merge(token1, token2);
}
Impact
Approved users cannot merger tokens if they are not approved for all and this breaks core protocol functionality and also leads to a DOS.
Audinarey
High
Approved users cannot merge tokens for owners
Summary
To merge 2 tokens into 1, a user must be either be approved or the owner of both tokens. This is obvious in the checks in
merge(...)
functionVulnerability Detail
The merge function has a check to ensure that a third party user has approval to merge any two tokens. And then it cals the
_burn(..)
function to burn the_from
token.However, the
_burn(...)
function clears the approval of the_from
token. It does this by callingapprove(address(0), _tokenId)
on the_from
token which checks if the caller is the owner or approved for all, but it doesn't allow "regular" approved users to perform this task and hence the call reverts.CODED POC
VotingEscrow.t.sol
file and runforge test --mt testApprovedMergeReverts -vvv
Impact
Approved users cannot merger tokens if they are not approved for all and this breaks core protocol functionality and also leads to a DOS.
Code Snippet
https://github.com/sherlock-audit/2024-06-velocimeter/blob/main/v4-contracts/contracts/VotingEscrow.sol#L1195-L1210 https://github.com/sherlock-audit/2024-06-velocimeter/blob/main/v4-contracts/contracts/VotingEscrow.sol#L537-L543
Tool used
Foundry test
Recommendation
In the
_burn(...)
function replaceapprove(address(0), _tokenId)
with_clearApproval(owner, _tokenId)
as shown belowDuplicate of #42