Swivel v3 contest - 0xDjango's results

The Capital-Efficient Protocol For Fixed-Rate Lending.

General Information

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

Swivel

Findings Distribution

Researcher Performance

Rank: 16/78

Findings: 4

Award: $225.50

🌟 Selected for report: 1

🚀 Solo Findings: 0

Findings Information

Labels

bug
2 (Med Risk)
resolved

Awards

48.5491 USDC - $48.55

External Links

Lines of code

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

Vulnerability details

Impact

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.

Tools Used

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

Findings Information

🌟 Selected for report: bin2chen

Also found by: 0x52, 0xDjango, 0xSky, Picodes, auditor0517, rokinot, ronnyx2017, scaraven

Labels

bug
duplicate
2 (Med Risk)
resolved

Awards

106.8838 USDC - $106.88

External Links

Lines of code

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

Vulnerability details

Impact

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.

Proof of Concept

  1. User attempts to redeem their ZcToken that has matured with ZcToken.redeem()
  • This function calls MarketPlace.authRedeem()
  1. MarketPlace.authRedeem() calls ISwivel(swivel).authRedeem(p, u, market.cTokenAddr, t, a);
  • Since 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.

Tools Used

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

QA Report

[L-01] Ownership transfer should be a two-step process

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

[L-02] Floating pragma

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

[N-01] Comment vs Code

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

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter