Two address tokens can be withdrawn by the admin even if they are vested #429
Labels
2 (Med Risk)
Assets not at direct risk, but function/availability of the protocol could be impacted or leak value
bug
Something isn't working
sponsor acknowledged
Technically the issue is correct, but we're not going to resolve it for XYZ reasons
Lines of code
https://github.com/code-423n4/2022-09-vtvl/blob/f68b7f3e61dad0d873b5b5a1e8126b839afeab5f/contracts/VTVLVesting.sol#L446-L451
Vulnerability details
Impact
Two address tokens exists in the blockchain. For example, Synthetix's
ProxyERC20
contract is such a token which exists in many forms (sUSD, sBTC...). Tokens as such can be vested, but the admin can withdraw them even if they are vested by providing the other address to thewithdrawOtherToken
function. The only check in this function is that_otherTokenAddress != tokenAddress
, which is irrelevant in the case of two address tokens.This can make the admin be able to withdraw the vested funds and break the system, because the balance of the contract can be less than the vested amount.
Proof of Concept
VTVLVesting
is deployed with thesUSD
contract, using its main (proxy) address -0x57Ab1ec28D129707052df4dF418D58a2D46d5f51
.numTokensReservedForVesting
is1000e18
.withdrawOtherToken
for 1000e18 sUSD, providing its second address -0x57Ab1ec28D129707052df4dF418D58a2D46d5f51
. The value ofnumTokensReservedForVesting
is still1000e18
, but the balance of the contract is now 0 sUSD.safeTransfer()
because there is insufficient balance of sUSD. Alice can't receive her funds.Tools Used
Manual audit
Recommended Mitigation Steps
Replace the address check with a balance check - record the vesting token balance of the contract before and after the transfer and assert that they are equal.
The text was updated successfully, but these errors were encountered: