A contract/EOA which has been approved some ZcToken cannot redeem() or withdraw() the approved tokens since these functions always revert if msg.sender != holder.
Proof of Concept
In the withdraw() function (ZcToken.sol#L112) the check on allowance
if (allowed >= previewAmount) {
revert Approvals(allowed, previewAmount);
}
is incorrect.
So the withdraw() always reverts if msg.sender != holder, since if allowed >= previewAmount, then it reverts and otherwise allowance[holder][msg.sender] -= previewAmount; it reverts for underflow.
In the redeem() function the issue is similiar (ZcToken.sol#L133) but concerns the check allowed >= principalAmount which is incorrect.
Tools Used
Manual analysis
Recommended Mitigation Steps
Use allowed < previewAmount (in withdraw()) and allowed < principalAmount (in redeem()) to check amount exceding allowance.
Lines of code
https://github.com/code-423n4/2022-07-swivel/blob/fd36ce96b46943026cb2dfcb76dfa3f884f51c18/Creator/ZcToken.sol#L112 https://github.com/code-423n4/2022-07-swivel/blob/fd36ce96b46943026cb2dfcb76dfa3f884f51c18/Creator/ZcToken.sol#L133
Vulnerability details
Title
Cannot
withdraw
orredeem
approved tokensImpact
A contract/EOA which has been approved some
ZcToken
cannotredeem()
orwithdraw()
the approved tokens since these functions always revert ifmsg.sender
!=holder
.Proof of Concept
In the
withdraw()
function (ZcToken.sol#L112) the check on allowanceis incorrect. So the
withdraw()
always reverts ifmsg.sender
!=holder
, since ifallowed
>=previewAmount
, then it reverts and otherwiseallowance[holder][msg.sender] -= previewAmount;
it reverts for underflow.In the
redeem()
function the issue is similiar (ZcToken.sol#L133) but concerns the checkallowed >= principalAmount
which is incorrect.Tools Used
Manual analysis
Recommended Mitigation Steps
Use
allowed < previewAmount
(inwithdraw()
) andallowed < principalAmount
(inredeem()
) to check amount exceding allowance.