Tracer contest - 0xRajeev's results

Build and trade with Tracer’s Perpetual Swaps and gain leveraged exposure to any market in the world.

General Information

Platform: Code4rena

Start Date: 24/06/2021

Pot Size: $80,000 USDC

Total HM: 18

Participants: 12

Period: 7 days

Judge: cemozer

Total Solo HM: 11

Id: 16

League: ETH

Tracer

Findings Distribution

Researcher Performance

Rank: 1/12

Findings: 9

Award: $20,073.60

🌟 Selected for report: 14

🚀 Solo Findings: 4

Findings Information

🌟 Selected for report: 0xRajeev

Labels

bug
3 (High Risk)
sponsor confirmed

Awards

6710.1761 USDC - $6,710.18

External Links

Handle

0xRajeev

Vulnerability details

Impact

The updateFundingRate() function updates the funding rate and insurance funding rate. While the instant/new funding rates are calculated correctly, the cumulative funding rate calculation is incorrect because it is always adding the instant to 0, not the previous value. This is due to the use of [currentFundingIndex] which has been updated since the previous call to this function while it should really be using [currentFundingIndex-1] to reference the previous funding rate.

Impact: The cumulative funding rate and insurance funding rates are calculated incorrectly without considering the correct previous values. This affects the settling of accounts across the entire protocol. The protocol logic is significantly impacted, accounts will not be settled as expected, protocol shutdown and contracts will need to be redeployed. Users may lose funds and protocol takes a reputation hit.

Proof of Concept

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/Pricing.sol#L155-L160

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/Pricing.sol#L168

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/Pricing.sol#L77

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/Pricing.sol#L196-L215

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/Pricing.sol#L221-L230

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/TracerPerpetualSwaps.sol#L445-L446

Tools Used

Manual Analysis

Use [currentFundingIndex-1] for non-zero values of currentFundingIndex to get the value updated in the previous call on lines L155 and L159 of Pricing.sol.

#0 - raymogg

2021-07-05T03:14:20Z

Confirmed as an index issue with funding rate 👍

Findings Information

🌟 Selected for report: 0xRajeev

Also found by: gpersoon, pauliax

Labels

bug
3 (High Risk)
sponsor confirmed
disagree with severity

Awards

1811.7475 USDC - $1,811.75

External Links

Handle

0xRajeev

Vulnerability details

Impact

The withdrawERC20Token() in SafetyWithdraw inherited in TracerPerpetualSwaps is presumably a guarded launch emergency withdrawal mechanism. However, given the trust model where the market creator/owner is potentially untrusted/malicious, this is a dangerous approach to emergency withdrawal in the context of guarded launch.

Alternatively, if this is meant for the owner to withdraw “external” ERC20 tokens mistakenly deposited to the Tracer market then the function should exclude tracerQuoteToken from being the tokenAddress that can be used as a parameter to withdrawERC20Token().

Impact: Malicious owner of a market withdraws/rugs all tracerQuoteTokens deposited at any time after market launch. All users lose deposits. Protocol takes a reputational hit and has to refund the users from treasury.

Proof of Concept

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/lib/SafetyWithdraw.sol#L8-L14

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/TracerPerpetualSwaps.sol#L20

Tools Used

Manual Analysis

For a guarded launch circuit breaker, design a pause/unpause feature where deposits are paused (in emergency situations) but withdrawals are allowed by the depositors themselves instead of the owner. Alternatively, if this is meant to be for removing external ERC20 tokens accidentally deposited to market, exclude the tracerQuoteToken from being given as the tokenAddress.

#0 - raymogg

2021-07-05T03:13:21Z

The only reason for the dispute on severity is that as part of the security model, the owner can manipulate the market in other ways (such as changing the oracle being used), so this trust assumption over the owner already exists. For this reason the team thinks this issue is closer to a medium

This however is a good issue as it is not the greatest circuit breaking mechanism, and as noted in #7 can reflect badly on the project without the exploit being used. The mechanism is being removed and replaced with more structured circuit breaker.

#1 - cemozerr

2021-07-18T20:04:51Z

Marking this as high risk, as regardless of the owner manipulating in other ways, the threat persists.

Findings Information

🌟 Selected for report: 0xRajeev

Also found by: a_delamo, cmichel, shw

Labels

bug
2 (Med Risk)

Awards

366.8789 USDC - $366.88

External Links

Handle

0xRajeev

Vulnerability details

Impact

The contracts use Chainlink’s deprecated API latestAnswer(). Such functions might suddenly stop working if Chainlink stopped supporting deprecated APIs.

Impact: Deprecated API stops working. Prices cannot be obtained. Protocol stops and contracts have to be redeployed.

Proof of Concept

See similar Low-severity finding L11 from OpenZeppelin's Audit of Opyn Gamma Protocol: https://blog.openzeppelin.com/opyn-gamma-protocol-audit/

See https://docs.chain.link/docs/deprecated-aggregatorinterface-api-reference/#latestanswer.

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/TracerPerpetualSwaps.sol#L372

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/TracerPerpetualSwaps.sol#L437

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/TracerPerpetualSwaps.sol#L462

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/Pricing.sol#L70

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/Pricing.sol#L175

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/Liquidation.sol#L156

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/oracle/GasOracle.sol#L32-L33

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/oracle/ChainlinkOracleAdapter.sol#L30

Tools Used

Manual Analysis

Use V3 interface functions: https://docs.chain.link/docs/price-feeds-api-reference/

#0 - raymogg

2021-07-05T09:15:27Z

Duplicate of #145

#1 - cemozerr

2021-07-18T17:47:45Z

Marking this as a medium as it can lead to having the whole protocol being redeployed.

Findings Information

🌟 Selected for report: s1m0

Also found by: 0xRajeev, JMukesh, Lucius, cmichel, pauliax, shw

Labels

bug
duplicate
2 (Med Risk)

Awards

152.8313 USDC - $152.83

External Links

Handle

0xRajeev

Vulnerability details

Impact

ERC20 tokens are specified to return a boolean value on token transfer() and transferFrom(). However, tokens may not adhere to the spec and return no value for success/failure. Checking the return values of ERC20 token transfers is therefore important to anticipate all possibilities: 1) return boolean 2) return nothing 3) revert. The SafeERC20 wrappers from OpenZeppelin cover all these scenarios and throw on failure (when the token contract returns false.

Tracer markets allow the market creator to specify any arbitrary ERC20 tracerQuoteToken which may or may not adhere to the ERC20 spec, and may even be malicious. To minimize risk, it will help to use the SafeERC20 wrappers and give better protection to the market users.

Impact: Market creator uses a tracerQuoteToken which returns true/false on success/failure. The code does not check return values of transfers and assumes correct amounts are deposited/withdrawn. This leads to bad accounting and the entire protocol is at risk of insolvency or exploitation.

Proof of Concept

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/eea376911b32d2c6392496d966e38601c1e762d5/contracts/token/ERC20/utils/SafeERC20.sol#L8-L16

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/TracerPerpetualSwaps.sol#L151

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/TracerPerpetualSwaps.sol#L203

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/TracerPerpetualSwaps.sol#L514

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/Insurance.sol#L51

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/Insurance.sol#L97

Tools Used

Manual Analysis

Use SafeERC20 wrapper functions to handle token transfers

#0 - raymogg

2021-07-05T03:25:08Z

Duplicate of #115

Findings Information

🌟 Selected for report: shw

Also found by: 0xRajeev

Labels

bug
duplicate
2 (Med Risk)
sponsor dispute

Awards

905.8738 USDC - $905.87

External Links

Handle

0xRajeev

Vulnerability details

Impact

The Trader contract makes an external call to the market contract TracerPerpetualSwaps as part of executeTrade(). The comments in code "// todo this could be succeptible to re-entrancy as // market is never verified” indicate that there could be a residual concern for reentrancy. However, it is not clear that this is the case because the factory only deploys TracerPerpetualSwaps market contract which is “trusted” and not expected to make a reentrant call to Trader::executeTrade().

Noting this here as a finding to indicate the concern expressed in the comment for reevaluation. executeTrade() neither has a reentrancy guard nor follows the Checks-Effects-Interactions pattern because order state is updated after the market call to matchOrders().

Proof of Concept

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/Trader.sol#L119-L120

Tools Used

Manual Analysis

Reevaluate the concern expressed in the comment a a “todo.” Clarify the concern or consider using the OpenZeppelin ReentrancyGuard and/or Checks-Effects-Interactions pattern.

#0 - raymogg

2021-07-08T00:28:50Z

Disputing as the issue is clearly marked in the code. Appreciate it being raised as a concern.

Ideally there will be a check with the factory to ensure that the market address is in fact a deployed tracer market (this fix is already implemented and to be pushed soon).

#1 - cemozerr

2021-07-18T20:58:14Z

Marking this as a valid issue as it still poses a security threat.

#2 - loudoguno

2021-08-24T16:38:18Z

changing risk from 1 to 2 and closing as duplicate of #143 as per judges sheet

Findings Information

🌟 Selected for report: 0xRajeev

Labels

bug
2 (Med Risk)
sponsor acknowledged

Awards

2013.0528 USDC - $2,013.05

External Links

Handle

0xRajeev

Vulnerability details

Impact

The Tracer Perpetuals Factory contract is arguably the most critical contract in the project given that it deploys all the markets. The ownership of this contract is transferred to _governance address, i.e. TracerDAO, in the constructor. This critical address transfer in one-step is very risky because it is irrecoverable from any mistakes.

Impact: If an incorrect address, e.g. for which the private key is not known, is used accidentally then it prevents the use of all the onlyOwner() functions forever, which includes the changing of various deployer contract addresses and market approvals. This use of incorrect address may not even be immediately apparent given that these functions are probably not used immediately. When noticed, due to a failing onlyOwner() function call, it will force the redeployment of the factory contract and require appropriate changes and notifications for switching from the old to new address. This will diminish trust in markets and incur a significant reputational damage.

Proof of Concept

See similar High Risk severity finding from Trail-of-Bits Audit of Hermez: https://github.com/trailofbits/publications/blob/master/reviews/hermez.pdf

See similar Medium Risk severity finding from Trail-of-Bits Audit of Uniswap V3: https://github.com/Uniswap/uniswap-v3-core/blob/main/audits/tob/audit.pdf

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/TracerPerpetualsFactory.sol#L43

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/TracerPerpetualsFactory.sol#L68

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/TracerPerpetualsFactory.sol#L119

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/TracerPerpetualsFactory.sol#L124

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/TracerPerpetualsFactory.sol#L129

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/TracerPerpetualsFactory.sol#L134

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/TracerPerpetualsFactory.sol#L144

Tools Used

Manual Analysis

Retain the deployer ownership in the constructor and then use a two-step address change to _governance address separately using setter functions: 1) Approve a new address as a pendingOwner 2) A transaction from the pendingOwner (TracerDAO) address claims the pending ownership change. This mitigates risk because if an incorrect address is used in step (1) then it can be fixed by re-approving the correct address. Only after a correct address is used in step (1) can step (2) happen and complete the address/ownership change.

#0 - raymogg

2021-07-05T03:49:12Z

Correct that having the owner be set to a wrong address could be detrimental, however for the first deploy of the factory, this will be owned by the DAO and will be easy to validate on deployment.

Subsequent ownership transfers will be done via DAO proposal, and will have many eyes across them (due to them being a public Tracer DAO proposal) before function execution happens.

For this reason it seems like a lot of overhead to have a two step process for this. Not withstanding that the issue you mention could still be possible

Findings Information

🌟 Selected for report: 0xRajeev

Labels

bug
2 (Med Risk)
sponsor confirmed

Awards

2013.0528 USDC - $2,013.05

External Links

Handle

0xRajeev

Vulnerability details

Impact

Tracer protocol like any other allows market creators to charge fees for trades. However, a malicious/greedy owner can arbitrarily change fee to any % value and without an event to observe this change or a timelock to react, there is no easy way for users to monitor this via front-end or off-chain monitoring tools.

Impact: Users trade on a market with 0.1% fees. The owner suddenly changes this to 100%. Users realise this only after their trades are executed. Market loses confidence. Protocol takes a reputational hit.

Proof of Concept

See similar Medium-severity finding in ConsenSys's Audit of 1inch Liquidity Protocol (https://consensys.net/diligence/audits/2020/12/1inch-liquidity-protocol/#unpredictable-behavior-for-users-due-to-admin-front-running-or-general-bad-timing

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/TracerPerpetualSwaps.sol#L548-L550

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/lib/LibBalances.sol#L198-L214

Tools Used

Manual Analysis

Emit event, provide time lock for users to react and establish an upper threshold for fees that is decided across markets by governance.

#0 - raymogg

2021-07-05T03:42:40Z

Like the idea of having a timelock for any update parameter update that immediately affects traders

Findings Information

🌟 Selected for report: 0xRajeev

Labels

bug
2 (Med Risk)

Awards

2013.0528 USDC - $2,013.05

External Links

Handle

0xRajeev

Vulnerability details

Impact

The owner of TracerPerpetualSwaps contract, who is potentially untrusted as per specification, can change the market critical parameters such as the addresses of the Liquidation/Pricing/Insurance/GasOracle/FeeReceiver and also critical values such as feeRate, maxLeverage, fundingRateSensitivity, deleveragingCliff, lowestMaxLeverage, insurancePoolSwitchStage and whitelisting.

None of these setter functions emit events to record these changes on-chain for off-chain monitors/tools/interfaces to register the updates and react if necessary.

Impact: Malicious owner changes the critical addresses or values that significantly change the security posture/perception of the protocol. No events are emitted and users lose funds/confidence. The protocol takes a reputation hit.

Proof of Concept

See similar High-severity finding OpenZeppelin’s Audit of Audius (https://blog.openzeppelin.com/audius-contracts-audit/#high) and Medium-severity finding OpenZeppelin’s Audit of UMA Phase 4 (https://blog.openzeppelin.com/uma-audit-phase-4/)

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/TracerPerpetualSwaps.sol#L522-L570

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/TracerPerpetualSwaps.sol#L577-L585

Tools Used

Manual Analysis

Consider emitting events when these addresses/values are updated. This will be more transparent and it will make it easier to keep track of the status of the system.

#0 - raymogg

2021-07-05T03:42:06Z

Duplicate of #66

#1 - cemozerr

2021-07-18T19:36:22Z

Opening this issue as the event emission seems to be separate from the arbitrarily changing of the values.

Findings Information

🌟 Selected for report: 0xRajeev

Also found by: JMukesh, cmichel, gpersoon, pauliax, shw

Labels

bug
1 (Low Risk)

Awards

66.0382 USDC - $66.04

External Links

#0 - raymogg

2021-07-05T23:05:24Z

Duplicate of #136

More issues brought up in this one, but falls under the general category of missing zero address checks

#1 - loudoguno

2021-08-17T23:25:56Z

reopening as primary issue to reflect judges findings sheet

Findings Information

🌟 Selected for report: 0xRajeev

Also found by: cmichel, gpersoon

Labels

bug
1 (Low Risk)
sponsor confirmed

Awards

181.1748 USDC - $181.17

External Links

Handle

0xRajeev

Vulnerability details

Impact

The gas cost for liquidation may change if code is updated/optimized, compiler changed or profiling improved. The developers may forget to update this constant in code.

Impact: The margin validity calculation which uses this value may be affected if this changes and hence is not as declared in the constant. This may adversely impact validation.

Proof of Concept

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/TracerPerpetualSwaps.sol#L26

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/TracerPerpetualSwaps.sol#L244

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/TracerPerpetualSwaps.sol#L250

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/TracerPerpetualSwaps.sol#L494

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/Liquidation.sol#L159

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/Liquidation.sol#L193

Tools Used

Manual Analysis

It is safer to make this a constructor-set immutable value that will force usage of an updated accurate value at deployment time. Evaluate if the sensitivity to this value is great enough to justify a setter to change it if incorrectly initialized at deployment.

#0 - raymogg

2021-07-05T23:06:11Z

Duplicate of #101

#1 - loudoguno

2021-08-17T23:35:46Z

reopened as primary issue to reflect judges findings sheet

Findings Information

🌟 Selected for report: 0xRajeev

Labels

bug
1 (Low Risk)
sponsor confirmed

Awards

671.0176 USDC - $671.02

External Links

Handle

0xRajeev

Vulnerability details

Impact

The Deposit event uses the function parameter amount instead of the convertedWadAmount which is what is used to update the user’s position and tvl because it prevents any dust deposited in amount. This will also make it consistent with the emit event in withdraw function.

Impact: Deposit event amount reflects the value with dust while the user position does not. This may lead to confusion.

Proof of Concept

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/TracerPerpetualSwaps.sol#L163

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/TracerPerpetualSwaps.sol#L153-L162

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/TracerPerpetualSwaps.sol#L204

Tools Used

Manual Analysis

Use uint256(convertedWadAmount) instead of amount in Deposit event.

Findings Information

🌟 Selected for report: 0xRajeev

Labels

bug
1 (Low Risk)
sponsor confirmed

Awards

671.0176 USDC - $671.02

External Links

Handle

0xRajeev

Vulnerability details

Impact

The tvl calculation in deposit() uses convertedWadAmount but the one in withdraw() uses the parameter amount. While amount is still in WAD format, it may contain dust which is what the conversion to rawTokenAmount and then back to convertedWadAmount removes.

Impact: Use of amount in tvl during withdraw() will consider dust while the one in deposit() will not, which is inconsistent.

Proof of Concept

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/TracerPerpetualSwaps.sol#L200

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/TracerPerpetualSwaps.sol#L176-L177

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/TracerPerpetualSwaps.sol#L162

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/TracerPerpetualSwaps.sol#L153-L155

Tools Used

Manual Analysis

Use convertedWadAmount instead of amount to be consistent with the increment during withdraw() tvl calculation.

Findings Information

🌟 Selected for report: 0xRajeev

Also found by: a_delamo, pauliax

Labels

bug
1 (Low Risk)

Awards

181.1748 USDC - $181.17

External Links

Handle

0xRajeev

Vulnerability details

Impact

Low-level calls call/delegatecall/staticcall return true even if the account called is non-existent (per EVM design). Solidity documentation warns: "The low-level functions call, delegatecall and staticcall return true as their first return value if the account called is non-existent, as part of the design of the EVM. Account existence must be checked prior to calling if needed.”

Market address may not exist as a contract (e.g. incorrect EOA address used in orders) in which case low-level call still returns true/success. But the trade is assumed to have been successfully executed.

Impact: executeTrade() executes batch orders against a non-existing market contract due to a mistake in the trading interface. The transaction executes successfully without any side-effects because the market doesn’t exist. Internal accounting is updated incorrectly.

Proof of Concept

See related High-severity finding in ToB’s Audit of Hermez: https://github.com/trailofbits/publications/blob/master/reviews/hermez.pdf and ToB’s Audit of Uniswap V3: https://github.com/Uniswap/uniswap-v3-core/blob/main/audits/tob/audit.pdf

See Warning in: https://docs.soliditylang.org/en/v0.8.0/control-structures.html#error-handling-assert-require-revert-and-exceptions

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/Trader.sol#L121-L129

Tools Used

Manual Analysis

makeOrder.market should be checked for contract existence before the low-level call and verified to be actual market contract (but it is not verified as noted in the comment). Evaluate if this is a greater concern than undefined behavior.

#0 - raymogg

2021-07-05T09:22:27Z

Duplicate of #126

#1 - loudoguno

2021-08-24T16:54:28Z

removed duplicate label and reopened as per judges sheet (swapped with #126 )

Findings Information

🌟 Selected for report: 0xRajeev

Labels

bug
1 (Low Risk)
sponsor acknowledged

Awards

671.0176 USDC - $671.02

External Links

Handle

0xRajeev

Vulnerability details

Impact

In verifyAndSubmitLiquidation(), the tx.gasprice is checked against the fastGasOracle’s current gas price presumably to prevent liquidators front-running others for the same market/account by using a gas price exceeding the current prevailing price as indicated by the fastGasOracle.

Impact: If the gas prices are increasing rapidly due to volatility or network congestion, or if the liquidation engines and fastGasOracle are out of sync on gas prices because of consulting different sources, then these liquidations will keep failing. Front-running risk on liquidations is not adequately protected by tx.gasprice check.

This logic may also be impacted by the upcoming inclusion of EIP-1559 in London fork which affect gas semantics significantly.

Proof of Concept

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/Liquidation.sol#L156

Tools Used

Manual Analysis

Liquidation bots front-running by monitoring mempool or the use of FlashBots for liquidation MEV is a systemic challenge and not solved by using gasprice logic in contracts. Evaluate if the benefits match the failure modes.

#0 - raymogg

2021-07-08T00:27:26Z

Good point on the strict check of fast gas price. As you pointed out this is to prevent gas auctions from occuring and causing liquidations to be extremely expensive, however this could become a bottleneck in times of rapidly changing gas prices.

Have acknowledged that this could cause problems in certain scenarios. The team will be thinking about a safer implementation of this mechanism.

Findings Information

🌟 Selected for report: 0xRajeev

Labels

bug
1 (Low Risk)
sponsor confirmed

Awards

671.0176 USDC - $671.02

External Links

Findings Information

🌟 Selected for report: pauliax

Also found by: 0xRajeev, s1m0, shw

Labels

bug
duplicate
1 (Low Risk)
sponsor dispute
disagree with severity

Awards

122.293 USDC - $122.29

External Links

Handle

0xRajeev

Vulnerability details

Impact

ChainID is hardcoded to 1337 whereas it should be using the deployed chain’s chainID to function correctly. ChainID is used in signatures and verification to prevent replay attacks across hard forks or different chains e.g. L2s. While Trader contract uses ChainID in EIP712_DOMAIN, it is hardcoded to a constant 1337. This is likely a test configuration (not even listed on chainid.network) being carried over to production.

Impact: The current contracts get deployed in production on Ethereum Mainnet whose chainID is 1. Signature verification uses EIP712_DOMAIN which has a chainID of 1337 and signatures fail verification. Execution of trades fail across all markets. Contracts need to be redeployed. Protocol takes a reputation hit.

Proof of Concept

See related High-severity finding from ToB’s Audit of Yield Protocol: https://github.com/trailofbits/publications/blob/master/reviews/YieldProtocol.pdf

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/Trader.sol#L28

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/Trader.sol#L42-L50

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/Trader.sol#L175

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/Trader.sol#L238

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/Trader.sol#L207

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/Trader.sol#L81-L82

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/Trader.sol#L67

https://docs.soliditylang.org/en/v0.8.0/units-and-global-variables.html#block-and-transaction-properties

Tools Used

Manual Analysis

Instead of a hardcoded constant, use Solidity’s block.chainID to get currently executing chain’s chainID. Do not use test configuration in production contracts.

#0 - raymogg

2021-07-05T03:17:02Z

Disputing as an issue as while the suggested approach is a better solution (dynamically setting ChainID), deploying a Trader contract with the wrong ID does not affect the system. A new Trader can be deployed using the appropriate ChainID if one is accidentally deployed with the wrong ChainID.

Currently this ChainID is just updated before deployment. The team will implement the dynamic approach moving forward.

#1 - raymogg

2021-07-07T00:02:30Z

If we are considering this an issue, it would probably also be much lower severity, as the ramifications of this are pretty low considering the option to redeploy. Would be a 0 or 1 in my mind.

#2 - cemozerr

2021-07-18T19:08:24Z

Marking this as low risk as there is an option to redeploy.

#3 - loudoguno

2021-08-24T04:32:52Z

closing and labeling as duplicate of #85 as per judge

Findings Information

🌟 Selected for report: 0xRajeev

Labels

bug
1 (Low Risk)
sponsor confirmed

Awards

671.0176 USDC - $671.02

External Links

Handle

0xRajeev

Vulnerability details

Impact

Trading function executeTrade() batch executes maker/taker orders against a market. The trader/interface provides arrays of makers/takers which is unbounded. As a result, if the number of orders is too many, there is a risk of this transaction exceeding the block gas limit (which is 15 million currently).

Impact: executeTrade() is called with too many orders in the batch. Tx exceeds block gas limit and reverts. None of the orders are executed.

Proof of Concept

See similar Medium-severity finding from ConsenSys's Audit of Growth DeFi: https://consensys.net/diligence/audits/2020/12/growth-defi-v1/#potential-resource-exhaustion-by-external-calls-performed-within-an-unbounded-loop

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/Trader.sol#L67

https://github.com/code-423n4/2021-06-tracer/blob/74e720ee100fd027c592ea44f272231ad4dfa2ab/src/contracts/Trader.sol#L78

Tools Used

Manual Analysis

Limit the number or orders executed based on gasleft() after every iteration or estimate the gas cost and enforce an upper bound on the number of orders allowed in maker/taker arrays.

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