The withdrawEmergency
function does not clear the value of ownerToId
Description
The VotingEscrow contract provides the locking mechanism where users can lock their assets to obtain the voting weight. VotingEscrowV2Rev2, the upgraded contract of the VotingEscrow, allows the agency, the privileged account at the VotingEscrow contract, to process the withdrawal of the lock before the lock expires.
The withdrawEmergency
function removes the lock and clears the information of the owner of the lock. However, it does not clear ownerToId
, which contains the lock of the owner:
function _withdrawEmergency(
uint256 _targetLockerId,
uint256 _currentLockerId,
address _for,
bool _isToMsgSender
) internal onlyAgency {
// ...
// from VotingEscrow._removeLockerIdFrom (from VotingEscrow._removeLockerId)
idToOwner[_targetLockerId] = address(0);
// ...
}
Meanwhile, in the VotingEscrowV2 contract, which is inherited by VotingEscrowV2Rev2, creating a new lock requires the ownerToId
of the address to be zero:
function _addLockerIdTo(address _to, uint256 _lockerId)
internal
virtual
override
{
// ...
require(ownerToId[_to] == 0, "_to already has locker id");
// ...
}
Impact
This prevents the user whose assets were withdrawn by the emergency withdrawal mechanism from creating a new lock, assuming the upgrade to the VotingEscrowV2.
Recommendations
Consider setting the ownerToId
of the address to zero in the emergency withdrawal mechanism.
Remediation
This issue has been acknowledged by Familia Labs Ltd., and a fix was implemented in commit ed20df78↗.