Swivel contest - 0xsanson's results

The Decentralized Protocol For Fixed-Rate Lending & Tokenized Cash-Flows.

General Information

Platform: Code4rena

Start Date: 30/09/2021

Pot Size: $75,000 ETH

Total HM: 9

Participants: 15

Period: 7 days

Judge: 0xean

Total Solo HM: 2

Id: 39

League: ETH

Swivel

Findings Distribution

Researcher Performance

Rank: 5/15

Findings: 6

Award: $4,970.93

🌟 Selected for report: 4

🚀 Solo Findings: 1

Findings Information

🌟 Selected for report: 0xsanson

Also found by: 0xRajeev, GalloDaSballo, JMukesh, cmichel, defsec, leastwood, loop, nikitastupin, pants, pauliax

Labels

bug
duplicate
3 (High Risk)

Awards

0.1048 ETH - $310.65

External Links

Handle

0xsanson

Vulnerability details

Impact

Not every ERC20 token follows OpenZeppelin's recommendation. It's possible (inside ERC20 standard) that a transferFrom doesn't revert upon failure but returns false.

The code doesn't check these return values. For example uToken.transferFrom(msg.sender, o.maker, a); in initiateVaultFillingZcTokenInitiate can be exploited by the msg.sender to initiate a trade without sending any underlying.

Proof of Concept

grep 'transfer' Swivel.sol

Tools Used

editor

Consider using OpenZeppelin's library with safe versions of transfer functions.

#0 - JTraversa

2021-10-24T21:35:31Z

How does one chose a specific issue out of all the dupes?

I had chosen the one that was the most verbose and accurate (of a few very verbose responses). Just curious how we've ended up with this one hah.

Findings Information

🌟 Selected for report: 0xRajeev

Also found by: 0xsanson, leastwood

Labels

bug
duplicate
2 (Med Risk)
disagree with severity

Awards

0.2678 ETH - $793.82

External Links

Handle

0xsanson

Vulnerability details

Impact

In MarketPlace.sol, admin can change the swivel address at any time.

A malicious admin can abuse this by setting swivel to his personal address. Then they can call some functions (like p2pZcTokenExchange and p2pVaultExchange) to steal zc-tokens and n-tokens from users. By redeeming these, they can steal all funds from the protocol.

Proof of Concept

https://github.com/Swivel-Finance/gost/blob/v2/test/marketplace/MarketPlace.sol#L42

Tools Used

editor

Consider adding a timelock on setSwivelAddress or directly on admin. Alternatively add a require(swivel == address(0)) so it can be called only the first time.

#0 - JTraversa

2021-10-08T05:42:12Z

I need to check whether this is a duplicate. Will remove once reviewing tomorrow.

I'd also lower this to low severity as one of a number of admin functionality restrictions.

#1 - 0xean

2021-10-16T22:39:18Z

Downgraded to Risk 2 along with its duplicates based on assets not at direct risk

Findings Information

🌟 Selected for report: 0xRajeev

Also found by: 0xsanson, cmichel, gpersoon, itsmeSTYJ, pauliax

Labels

bug
duplicate
2 (Med Risk)

Awards

0.0976 ETH - $289.35

External Links

Handle

0xsanson

Vulnerability details

Impact

Only an admin can create a market by calling MarketPlace.createMarket. With the current implementation, it's possible to create another market with the same underlying u and maturity m. Doing so would rewrite markets[u][m] with a new ZcToken and VaultTracker. This makes the previous market inaccessible, effectively causing the loss of users' balances of n-tokens and zc-tokens.

Proof of Concept

https://github.com/Swivel-Finance/gost/blob/v2/test/marketplace/MarketPlace.sol#L53-L70

Tools Used

editor

In createMarket consider checking if the market is already present, for example adding a require(markets[u][m].cTokenAddr == address(0)). If multiple markets with the same u and m are needed, it's possible to add an identifier index to separate them, but the code needs more restructuring.

#0 - 0xean

2021-10-16T23:09:25Z

dupe of #97

Findings Information

🌟 Selected for report: 0xsanson

Labels

bug
2 (Med Risk)
sponsor acknowledged
disagree with severity

Awards

0.9917 ETH - $2,940.08

External Links

Handle

0xsanson

Vulnerability details

Impact

The current implementation doesn't work with fee-on-transfer underlying tokens. Considering that Compound can have these kind of tokens (ex. USDT can activate fees), this issue can affect the protocol.

The problem arise when transferring tokens, basically blocking all functions in Swivel.sol for that particular token, since the contract wrongly assumes balances values. This becomes particularly problematic in the following scenario: a market for USDT is running without problems, then they activate the fee: this effectively blocks users from redeeming the underlying.

Proof of Concept

grep 'transfer' Swivel.sol for a complete list of affected lines (basically every tranfer or transferFrom of underlying tokens). Also grep 'redeemUnderlying' Swivel.sol.

For example:

require(CErc20(mPlace.cTokenAddress(u, m)).redeemUnderlying(redeemed) == 0, 'compound redemption failed');
// transfer underlying back to msg.sender
Erc20(u).transfer(msg.sender, redeemed);

This would fail (revert) since the contract would have received less than redeemed tokens.

Tools Used

editor

If the protocol wants to use all possible Compund's tokens, a way to handle these tokens must be implemented. A possible way to do it is to check the balance of the contract before and after every time a token is transferred to see the effective quantity. To help keeping the code clear, a function like Compund's doTransferIn can be implemented.

#0 - JTraversa

2021-10-08T05:38:37Z

Will review further. I dont believe that any tokens on compound currently have fees. Although it is news to me that USDT has toggle-able fee's woops.

That said, given we have admin control over added assets, I'd probably also lower this to a low-risk if accepted.

#1 - 0xean

2021-10-15T01:17:38Z

2 — Med: Assets not at direct risk, but the function of the protocol or its availability could be impacted, or leak value with a hypothetical attack path with stated assumptions, but external requirements.

based on this "leaking value" I would say it qualifies as a med-severity.

#2 - JTraversa

2021-10-24T22:08:28Z

We can account for the transfers in with a similar balance before transferFrom, and balance after check, in order to prevent additional deposits after a fee has been turned on.

That said, Im not sure we can account for redeemUnderlying easily because should a fee be turned on, all funds would just be stuck in our contract if we added a similar check? (a != balance2-balance1)

If a fee is turned on for USDT markets, there would be lost fee value, so if adding a check wouldn't work, the most reasonable response is just to make sure the market is pausable.

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