If maturityRate is still 0 after maturity deadline (because no transactions setting maturityRate have been executed yet), then previewWithdraw calculated amount (used by ZcToken.withdraw function) is 0 and thus withdraw function will send 0 underlying tokens to user, which might be very confusing to user. Subsequent call to the same function will send him correct amount.
The same problem applies to all view functions in ZcToken contract - they use saved market maturityRate, which can be 0 even past deadline time and functions revert or return 0 in this case.
Incorrect withdrawal behaviour:
Bob has some ZcTokens.
Right at the time of maturity Bob tries to withdraw his underlying tokens by calling ZcToken.withdraw with some underlying amount.
Instead of receiving corresponding amount, Bob receives nothing (but transaction still succeeds and he uses gas for it).
Proof of Concept
withdraw: calculates previewAmount from previewWithdraw
Add getMaturityRate function to ZcToken, which will return either market's maturityRate or (if it's 0) current market's exchangeRate. Use this function instead of maturityRate everywhere across ZcToken.
Lines of code
https://github.com/code-423n4/2022-07-swivel/blob/fd36ce96b46943026cb2dfcb76dfa3f884f51c18/Tokens/ZcToken.sol#L99 https://github.com/code-423n4/2022-07-swivel/blob/fd36ce96b46943026cb2dfcb76dfa3f884f51c18/Tokens/ZcToken.sol#L92
Vulnerability details
Impact
If
maturityRate
is still0
after maturity deadline (because no transactions settingmaturityRate
have been executed yet), thenpreviewWithdraw
calculated amount (used byZcToken.withdraw
function) is0
and thuswithdraw
function will send0
underlying tokens to user, which might be very confusing to user. Subsequent call to the same function will send him correct amount.The same problem applies to all view functions in
ZcToken
contract - they use saved marketmaturityRate
, which can be0
even past deadline time and functions revert or return0
in this case.Incorrect withdrawal behaviour:
ZcToken
s.ZcToken.withdraw
with some underlying amount.Proof of Concept
withdraw
: calculatespreviewAmount
frompreviewWithdraw
https://github.com/code-423n4/2022-07-swivel/blob/fd36ce96b46943026cb2dfcb76dfa3f884f51c18/Tokens/ZcToken.sol#L99
previewWithdraw
: multiplication bymaturityRate
returns 0https://github.com/code-423n4/2022-07-swivel/blob/fd36ce96b46943026cb2dfcb76dfa3f884f51c18/Tokens/ZcToken.sol#L92
Recommended Mitigation Steps
Add
getMaturityRate
function toZcToken
, which will return either market'smaturityRate
or (if it's0
) current market'sexchangeRate
. Use this function instead ofmaturityRate
everywhere acrossZcToken
.