Platform: Code4rena
Start Date: 12/07/2022
Pot Size: $35,000 USDC
Total HM: 13
Participants: 78
Period: 3 days
Judge: 0xean
Total Solo HM: 6
Id: 135
League: ETH
Rank: 16/78
Findings: 4
Award: $225.50
🌟 Selected for report: 1
🚀 Solo Findings: 0
🌟 Selected for report: 0xDjango
Also found by: 0x1f8b, 8olidity, Bahurum, Lambda, arcoun, caventa, csanuragjain, hansfriese, joestakey, jonatascm, oyc_109, ronnyx2017
https://github.com/code-423n4/2022-07-swivel/blob/daf72892d8a8d6eaa43b9e7d1924ccb0e612ee3c/Tokens/ZcToken.sol#L112-L114 https://github.com/code-423n4/2022-07-swivel/blob/daf72892d8a8d6eaa43b9e7d1924ccb0e612ee3c/Tokens/ZcToken.sol#L132-L133
There is an error in the allowance functionality to allow a non-owner to withdraw or redeem ZcTokens for the owner. Taking ZcToken.redeem()
as an example, behold the following if/else block:
if (holder == msg.sender) { return redeemer.authRedeem(protocol, underlying, maturity, msg.sender, receiver, principalAmount); } else { uint256 allowed = allowance[holder][msg.sender]; if (allowed >= principalAmount) { revert Approvals(allowed, principalAmount); } allowance[holder][msg.sender] -= principalAmount; return redeemer.authRedeem(protocol, underlying, maturity, holder, receiver, principalAmount);
If the msg.sender
is the holder, no check for allowance is needed. If the sender is not the holder, then their allowance is checked.
The error lies in the if statement if (allowed >= principalAmount) { revert Approvals(allowed, principalAmount); }
. This states that if the sender has equal to or more allowance than the principalAmount, revert.
Therefore, if the sender has the proper allowance or more allowance than necessary, the transaction will revert. If the sender has less allowance than necessary, the transaction will still revert because of the allowance[holder][msg.sender] -= principalAmount;
clause.
In conclusion, there is no way to withdraw()
or redeem()
on behalf of another user.
Manual review.
The fix is to simply change >=
to <
#0 - JTraversa
2022-07-20T07:27:31Z
Approval workflow doesnt leave funds at risk but is a nice to have, that plus scope and this might end up low risk but I think medium is appropriate as well.
#1 - bghughes
2022-07-31T18:59:26Z
This is a good issue and I agree with the severity. I decided against making this high severity due to the fact that funds are not necessarily at risk; it it just intended allowance functionality will not behave as expected.
#2 - robrobbins
2022-08-02T22:51:18Z
see #180
#3 - bghughes
2022-08-03T01:44:27Z
Making this the main issue for the allowance flipped sign
🌟 Selected for report: bin2chen
Also found by: 0x52, 0xDjango, 0xSky, Picodes, auditor0517, rokinot, ronnyx2017, scaraven
106.8838 USDC - $106.88
https://github.com/code-423n4/2022-07-swivel/blob/daf72892d8a8d6eaa43b9e7d1924ccb0e612ee3c/Marketplace/MarketPlace.sol#L156 https://github.com/code-423n4/2022-07-swivel/blob/daf72892d8a8d6eaa43b9e7d1924ccb0e612ee3c/Swivel/Swivel.sol#L620
A user redeems or withdraws from their ZcToken by calling ZcToken.withdraw()
or ZcToken.redeem()
. Both of these functions then call MarketPlace.authRedeem()
which in turn calls Swivel.authRedeem()
. The issue is that Swivel.sol
does not have an authRedeem()
function. Instead it only has the authRedeemZcToken()
function.
Therefore, all redeem/withdraw operations will fail and all users' funds will be stuck.
ZcToken.redeem()
MarketPlace.authRedeem()
MarketPlace.authRedeem()
calls ISwivel(swivel).authRedeem(p, u, market.cTokenAddr, t, a);
Swivel.sol
does not contain this function, the call will revert and the user's ZcToken will not be redeemed. Their underlying will sit in the contract.Manual review.
Change the function name in Swivel.sol from authRedeemZcToken()
to authRedeem()
.
#0 - JTraversa
2022-07-20T07:47:41Z
Duplicate of #39
#1 - robrobbins
2022-07-28T15:00:39Z
This had been a regression. Current branch has both the interface:
https://github.com/Swivel-Finance/gost/blob/v3/test/marketplace/Interfaces.sol#L40
and the Swivel.sol:
https://github.com/Swivel-Finance/gost/blob/v3/test/swivel/Swivel.sol#L592
with the correct authRedeem
No PR link as this was fixed whilst correcting for said regression
#2 - bghughes
2022-08-03T14:24:11Z
Duplicate of #39
🌟 Selected for report: joestakey
Also found by: 0x1f8b, 0x52, 0xDjango, 0xNazgul, 0xNineDec, 8olidity, Avci, Bahurum, Bnke0x0, Chom, ElKu, Funen, GimelSec, JC, Junnon, Kaiziron, Meera, PaludoX0, Picodes, ReyAdmirado, Sm4rty, Soosh, Waze, _Adam, __141345__, ak1, aysha, benbaessler, bin2chen, c3phas, cccz, cryptphi, csanuragjain, defsec, exd0tpy, fatherOfBlocks, gogo, hake, hansfriese, itsmeSTYJ, jonatascm, kyteg, mektigboy, oyc_109, pashov, rbserver, rishabh, robee, rokinot, sach1r0, sashik_eth, scaraven, simon135, slywaters
44.3637 USDC - $44.36
It is recommended that ownership transfer be completed in two steps, firstly by setting a pending admin and finally by accepting the change from the pending admin account.
https://github.com/code-423n4/2022-07-swivel/blob/daf72892d8a8d6eaa43b9e7d1924ccb0e612ee3c/Swivel/Swivel.sol#L428-L432 https://github.com/code-423n4/2022-07-swivel/blob/daf72892d8a8d6eaa43b9e7d1924ccb0e612ee3c/Marketplace/MarketPlace.sol#L53-L56
Certain contracts contain a floating pragma. It is encouraged to deploy with the same specific compiler version for all contracts.
E.g. https://github.com/code-423n4/2022-07-swivel/blob/daf72892d8a8d6eaa43b9e7d1924ccb0e612ee3c/Tokens/ZcToken.sol#L2 https://github.com/code-423n4/2022-07-swivel/blob/daf72892d8a8d6eaa43b9e7d1924ccb0e612ee3c/Tokens/Erc20.sol#L4
The comment refers to "owner" but the param is named "holder".
https://github.com/code-423n4/2022-07-swivel/blob/daf72892d8a8d6eaa43b9e7d1924ccb0e612ee3c/Tokens/ZcToken.sol#L94 https://github.com/code-423n4/2022-07-swivel/blob/daf72892d8a8d6eaa43b9e7d1924ccb0e612ee3c/Tokens/ZcToken.sol#L120
#0 - robrobbins
2022-08-26T20:47:50Z
1 is a wontfix 2 is fixed elsewhere N01 the zctoken is in flux and will go thru further scrutiny in its own process away from swivel
🌟 Selected for report: joestakey
Also found by: 0x040, 0x1f8b, 0xDjango, 0xNazgul, 0xsam, Avci, Aymen0909, Bnke0x0, CRYP70, ElKu, Fitraldys, Funen, JC, Kaiziron, MadWookie, Meera, ReyAdmirado, Sm4rty, Soosh, TomJ, Waze, _Adam, __141345__, ajtra, benbaessler, c3phas, csanuragjain, durianSausage, exd0tpy, fatherOfBlocks, hake, ignacio, karanctf, kyteg, m_Rassska, oyc_109, rbserver, robee, rokinot, samruna, sashik_eth, simon135, slywaters
25.7087 USDC - $25.71