dHEDGE Differential Smart Contract Audit

# 1. Introduction
iosiro was commissioned by [dHEDGE](https://www.dhedge.org/) to conduct an audit of changes made to their smart contracts since the [last audit](https://iosiro.com/audits/dhedge-platform-smart-contract-audit) performed by iosiro. The audit was performed between 7 March and 12 March 2021, consuming a total of 5 person days.

This report is organized into the following sections.

* **[Section 2 - Executive summary:](#section-2)** A high-level description of the findings of the audit.
* **[Section 3 - Audit details:](#section-3)** A description of the scope and methodology of the audit.
* **[Section 4 - Design specification:](#section-4)** An outline of the intended functionality of the smart contracts.
* **[Section 5 - Detailed findings:](#section-5)** Detailed descriptions of the findings of the audit.

The information in this report should be used to better understand the risk exposure of the smart contracts, and as a guide to improving the security posture of the smart contracts by remediating issues identified. The results of this audit are only a reflection of the source code reviewed at the time of the audit and of the source code that was determined to be in-scope.

The purpose of this audit was to achieve the following:

* Identify potential security flaws.
* Ensure that the smart contracts functioned according to the documentation provided.

Assessing the economics, game theory, or underlying business model of the platform were strictly beyond the scope of this audit.

Due to the unregulated nature and ease of transfer of cryptocurrencies, operations that store or interact with these assets are considered very high risk with regards to cyber attacks. As such, the highest level of security should be observed when interacting with these assets. This requires a forward-thinking approach, which takes into account the new and experimental nature of blockchain technologies. Strategies that should be used to encourage secure code development include:

* Security should be integrated into the development lifecycle and the level of perceived security should not be limited to a single code audit.
* Defensive programming should be employed to account for unforeseen circumstances.
* Current best practices should be followed where possible.

<a name="section-2"></a>
# 2. Executive summary

This report presents the findings of an audit performed by iosiro on changes made to [dHEDGE](https://www.dhedge.org/) smart contracts since their last audit performed by iosiro. The changes included:

- The removal of exit fees.
- An implementation for managers to increase their performance fees.
- A `DHPTSwap` contract was created to facilitate buying and selling of various pool tokens.

Several low risk and informational issues were identified, including the usage of potentially invalid synth exchange rates and hard-coded constants used in the source code. Several design comments were also raised, including a remark on the proxy pattern used, potential gas optimisations, as well as code quality improvements. Overall, the code was found to be of a high standard and in accordance with the specification provided.

<a name="section-3"></a>
# 3. Audit details

## 3.1 Scope
The source code considered in-scope for the assessment is described below. Code from all other files is considered to be out-of-scope. Out-of-scope code that interacts with in-scope code is assumed to function as intended and introduce no functional or security vulnerabilities for the purposes of this audit.

### 3.1.1 dHEDGE smart contracts
**Project name:** dhedge-soldity <br/>
**Starting audit commit:** [5fbbc4b](https://github.com/dhedge/dhedge-solidity/tree/5fbbc4b011cc4dfcb195094849712da59cf64e0e) *<br/>
**Last audit commit:** [f22fc29](https://github.com/dhedge/dhedge-solidity/tree/f22fc29c0ce434ab45c7b77b339c8d611f41abe0) *<br/>
**Files:** DHedge.sol, DHedgeFactory.sol, DHPTSwap.sol<br/>

The scope of the audit was limited to changes between the starting commit and the last commit (the "differential", i.e. [5fbbc4b..f22fc29](https://github.com/dhedge/dhedge-solidity/compare/5fbbc4b..f22fc29)). Any code which was not modified between the two commits is considered to be out of scope.

_* Note: the audit was performed on contracts from a private repository._

## 3.2  Methodology

A variety of techniques were used while conducting the audit. These techniques are briefly described below.

### 3.2.1 Code review

The source code was manually inspected to identify potential security flaws. Code review is a useful approach for detecting security flaws, discrepancies between the specification and implementation, design improvements, and high risk areas of the system.

### 3.2.2 Dynamic analysis

The contracts were compiled, deployed, and tested in a Ganache test environment. Manual analysis was used to confirm that the code operated at a functional level, and to verify the exploitability of any potential security issues identified. The coverage report of the provided tests is given below.

| File                                   |  % Stmts | % Branch |  % Funcs |  % Lines |
| ---------------------------------------|----------|----------|----------|----------|
|   DHPTSwap.sol                         |    67.52 |     37.5 |    54.55 |    67.52 |
|   DHedge.sol                           |    83.89 |    80.77 |    85.37 |    84.13 |
|   DHedgeFactory.sol                    |    89.74 |       50 |    79.49 |     87.5 |
|   Managed.sol                          |    84.38 |       80 |    85.71 |    85.71 |
|   Address.sol                          |      100 |      100 |      100 |      100 |
|   BaseUpgradeabilityProxy.sol          |    77.78 |       75 |    66.67 |       80 |
|   HasLogic.sol                         |      100 |      100 |      100 |      100 |
|   InitializableUpgradeabilityProxy.sol |      100 |       50 |      100 |      100 |
|   Proxy.sol                            |      100 |      100 |      100 |       80 |
|   ProxyFactory.sol                     |      100 |      100 |      100 |      100 |
| **All files**                              |    **82.71** |    **58.88** |    **80.68** |     **82.6** |

In addition to the tests provided a number of custom tests were developed and run using a mainnet fork. This was primarily done to validate the integration with the Synthetix ecosystem and cover additional use cases that were not possible with the mocks provided.

### 3.2.3 Automated analysis

Tools were used to automatically detect the presence of several types of security vulnerabilities, including reentrancy, timestamp dependency bugs, and transaction-ordering dependency bugs. The static analysis results were manually analysed to remove false positive results. True positive results would be indicated in this report. Static analysis tools commonly used include Slither, MythX, as well as Securify. Furthermore, the Remix IDE, compilation output, and linters are also used to identify potential areas of concern.

## 3.3  Risk ratings

Each issue identified during the audit has been assigned a risk rating. The rating is determined based on the criteria outlined below.

* **High risk** - The issue could result in a loss of funds for the contract owner or system users.
* **Medium risk** - The issue resulted in the code specification being implemented incorrectly.
* **Low risk** - A best practice or design issue that could affect the security of the contract.
* **Informational** - A lapse in best practice or a suboptimal design pattern that has a minimal risk of affecting the security of the contract.
* **Closed** - The issue was identified during the audit and has since been addressed to a satisfactory level to remove the risk that it posed.

<a name="section-4"></a>
# 4. Design specification

The following section outlines the intended function of the system at a high level. The information is based on dHEDGE documentation as well as the code in the target commit hashes.

## 4.1 System Description

The dHEDGE system allowed anyone to mimic the trades of fund managers on the Synthetix platform. Users would enter funds with Synthetix USD (sUSD) and exit with a proportion of the underlying assets. Managers are allowed to exchange the underlying fund assets to any other supported assets, but not to withdraw other users funds'.

### 4.1.1 Fees

A manager fee based on the performance of the underlying assets, denominated in fund tokens, is issued whenever a deposit or withdrawal occurs. The value of this fee is determined by the increase in value (in sUSD) of the fund's total assets. Available manager fees can be withdrawn at any time by the manager. A portion of the manager fee is also distributed to the dHEDGE DAO, based on a fixed rate.

At the time of the initial audit, the dHEDGE system included an exit fee. This functionality has now been removed and the fee no longer applies. However, the cooldown period is still present and no withdrawals are permitted before the period elapses.

### 4.1.2 Pool and pool managers

The previous [audit report](https://iosiro.com/audits/dhedge-platform-smart-contract-audit#4.-design-specification) documents the intended behaviour for pools and pool managers. Some of the behaviour has changed, as noted below:
* Manager fee increases were introduced. Managers have to announce manager fee increases and only after a set waiting period can the change be applied. An announcement can be withdrawn by a manager.
* Supported assets can be removed from the whitelist by the DAO in addition to managers, where previously only managers were allowed.

### 4.1.3 Upgrades

All the contracts in the dHEDGE system are deployed using an upgradeable proxy pattern, which allows the implementation logic to be separate from the contract state. The system makes extensive use of the OpenZeppelin upgradeable contracts, but some custom modifications were identified.

## 4.2 Pool token swap contract

A new contract, `DHPTSwap`, was introduced to aid in the buying and selling of dHEDGE pool tokens (DHPT). The contract was introduced to reduce gas savings for users looking to get exposure to the top performing dHEDGE pools. Initial liquidity of sUSD and pool tokens is provided by the dHEDGE team to enable the buying and selling of various pool tokens.

Two sets of buying and selling functions were introduced, one of which derived the token price from examining the fund composition, with the other getting the token price from an off-chain oracle. Buying and selling tokens through the oracle further reduced gas costs by relying on a signature from the off-chain oracle, avoiding the need to fetch individual synth rates from the Synthetix `ExchangeRates` contract. The signature included a short window of validity to prevent users from using older rates in the future. Buying pool tokens through either function on the swap contract incurred a small saving as Synthetix exchange fees were avoided as no new sUSD needed to be exchanged. The code used by the oracle and the related infrastructure was out-of-scope for this audit, and assumed to operate as intended.

The contracts had a whitelist to specify which pool tokens were allowed to be traded on the contract. This whitelisted included a capped amount, which indicates the maximum balance of pool tokens the contract is allowed to hold at any time. If the cap is reached, an administrator can increase the cap to enable further sales.

<a name="section-5"></a>
# 5. Detailed findings
The following section includes in depth descriptions of the findings of the audit.

## 5.1 High risk

No high risk issues were present at the conclusion of the audit.

## 5.2 Medium risk

No medium risk issues were present at the conclusion of the audit.

## 5.3 Low risk

### 5.3.1 Synths can have invalid rates
*[DHedge.sol#L492](https://github.com/dhedge/dhedge-solidity/blob/f22fc29c0ce434ab45c7b77b339c8d611f41abe0/contracts/DHedge.sol#L492), [DHPTSwap.sol#L370](https://github.com/dhedge/dhedge-solidity/blob/f22fc29c0ce434ab45c7b77b339c8d611f41abe0/contracts/DHPTSwap.sol#L370)*

#### Description

Synthetix has implemented Chainlink oracles to provide pricing data for synths. These feeds can occasionally be flagged if there is an issue with the Aggregator. Certain functions, such as the `DHedge.getFundComposition()` and `DHPTSwap.tokenPriceWithSettle()` functions, did not validate if the synth rate was valid. This could lead to an incorrect token price being used when buying or selling through the `DHPTSwap` contract, or return an inaccurate fund composition.

#### Recommendation

The `ExchangeRates.rateAndInvalid()` function should be used instead of the `ExchangeRates.rateForCurrency()` function. This function returns the rate as well as an `isInvalid` flag which should be validated to be false.

### 5.3.2 Hardcoded constants
*[DHPTSwap.sol#L79](https://github.com/dhedge/dhedge-solidity/blob/f22fc29c0ce434ab45c7b77b339c8d611f41abe0/contracts/DHPTSwap.sol#L79), [DHPTSwap.sol#L113](https://github.com/dhedge/dhedge-solidity/blob/f22fc29c0ce434ab45c7b77b339c8d611f41abe0/contracts/DHPTSwap.sol#L113), [DHPTSwap.sol#L154](https://github.com/dhedge/dhedge-solidity/blob/f22fc29c0ce434ab45c7b77b339c8d611f41abe0/contracts/DHPTSwap.sol#L154), [DHPTSwap.sol#L195](https://github.com/dhedge/dhedge-solidity/blob/f22fc29c0ce434ab45c7b77b339c8d611f41abe0/contracts/DHPTSwap.sol#L195),  [DHPTSwap.sol#L422](https://github.com/dhedge/dhedge-solidity/blob/f22fc29c0ce434ab45c7b77b339c8d611f41abe0/contracts/DHPTSwap.sol#L422), [DHedge.sol#L624](https://github.com/dhedge/dhedge-solidity/blob/f22fc29c0ce434ab45c7b77b339c8d611f41abe0/contracts/DHedge.sol#L624)*

#### Description

The `DHPTSwap` contract included validation to ensure that the amount of DHPT being sold or the amount of sUSD used to buy DHPT was above a certain threshold. These thresholds were hardcoded constants, while the value of DHPT was subject to change. If the value of DHPT changes dramatically, the hardcoded constants may be outside of an appropriate range for the intended purpose.

A similar issue was found in the `DHedge.mintManagerFee()` and `DHPTSwap.tokenPriceWithSettle()` functions when determining to mint the manager fees or calculate the adjusted token price, respectively.

#### Recommendation

Where sensible, all hardcoded constants should be replaced with configurable state variables. As these values are sensitive, the setters should be restricted to the contract administrators. The exact value should be tested to verify its usefulness, and adjusted where necessary. It may be deemed necessary to include a timelock on setting these variables.

Where a value is truly constant, a contract wide constant should be defined and used throughout the code.

## 5.4 Informational

### 5.4.1 Missing `poolPrice` validation in `oracleSellDHPT()` and `oracleBuyDHPT()`
*[DHPTSwap.sol#L147](https://github.com/dhedge/dhedge-solidity/blob/f22fc29c0ce434ab45c7b77b339c8d611f41abe0/contracts/DHPTSwap.sol#L147), [DHPTSwap.sol#L188](https://github.com/dhedge/dhedge-solidity/blob/f22fc29c0ce434ab45c7b77b339c8d611f41abe0/contracts/DHPTSwap.sol#L188)*

#### Description

The `DHPTSwap.oracleSellDHPT()` and `DHPTSwap.oracleBuyDHPT()` functions relied on an external oracle to provide the price of DHPT tokens. This price, the `poolPrice` parameter, should be validated to be non-zero in the unlikely event of an oracle failure. This will prevent users from buying and selling DHPT at a zero rate, as well as prevent a division by zero error.  

#### Recommendation

A `require` statement should be added at the beginning of the affected functions to validate that the `poolPrice` is non-zero.

### 5.4.2 Missing function events
*[DHedgeFactory.sol#L268](https://github.com/dhedge/dhedge-solidity/blob/f22fc29c0ce434ab45c7b77b339c8d611f41abe0/contracts/DHedgeFactory.sol#L268), [DHedgeFactory.sol#L276](https://github.com/dhedge/dhedge-solidity/blob/f22fc29c0ce434ab45c7b77b339c8d611f41abe0/contracts/DHedgeFactory.sol#L276), [DHedgeFactory.sol#L185](https://github.com/dhedge/dhedge-solidity/blob/f22fc29c0ce434ab45c7b77b339c8d611f41abe0/contracts/DHedgeFactory.sol#L185), [DHedgeFactory.sol#L342](https://github.com/dhedge/dhedge-solidity/blob/f22fc29c0ce434ab45c7b77b339c8d611f41abe0/contracts/DHedgeFactory.sol#L342), [DHedgeFactory.sol#L368](https://github.com/dhedge/dhedge-solidity/blob/f22fc29c0ce434ab45c7b77b339c8d611f41abe0/contracts/DHedgeFactory.sol#L368), [DHPTSwap.sol#L299](https://github.com/dhedge/dhedge-solidity/blob/f22fc29c0ce434ab45c7b77b339c8d611f41abe0/contracts/DHPTSwap.sol#L299), [DHPTSwap.sol#L258](https://github.com/dhedge/dhedge-solidity/blob/f22fc29c0ce434ab45c7b77b339c8d611f41abe0/contracts/DHPTSwap.sol#L258), [DHPTSwap.sol#L265](https://github.com/dhedge/dhedge-solidity/blob/f22fc29c0ce434ab45c7b77b339c8d611f41abe0/contracts/DHPTSwap.sol#L265), [DHPTSwap.sol#L272](https://github.com/dhedge/dhedge-solidity/blob/f22fc29c0ce434ab45c7b77b339c8d611f41abe0/contracts/DHPTSwap.sol#L272), [DHPTSwap.sol#L279](https://github.com/dhedge/dhedge-solidity/blob/f22fc29c0ce434ab45c7b77b339c8d611f41abe0/contracts/DHPTSwap.sol#L279)*

#### Description

Several functions did not emit any events when executed. Events aid in the visibility of contract state changes. This information could be used on the dApp frontend, and could also be useful for users querying the blockchain.

#### Recommendation

Events containing affected state changes should be emitted for the following functions:

1. `DHedgeFactory.setMaximumManagerFeeNumeratorChange()`
2. `DHedgeFactory.setManagerFeeNumeratorChangeDelay()`
3. `DHedgeFactory.setAddressResolver()`
4. `DHedgeFactory._setTrackingCode()`
5. `DHedgeFactory._upgradePool()`
6. `DHPTSwap.enableBuySell()`
7. `DHPTSwap.setAddressResolver()`
8. `DHPTSwap.setFactory()`
9. `DHPTSwap.setOracle()`
10. `DHPTSwap.setOracleBlockBias()`

### 5.4.3 Contract gaps not adjusted
*[DHedge.sol#L768](https://github.com/dhedge/dhedge-solidity/blob/f22fc29c0ce434ab45c7b77b339c8d611f41abe0/contracts/DHedge.sol#L768), [DHedgeFactory.sol#L395](https://github.com/dhedge/dhedge-solidity/blob/f22fc29c0ce434ab45c7b77b339c8d611f41abe0/contracts/DHedgeFactory.sol#L395)*

#### Description

Contracts that are behind a proxy may make use of a storage gap to reserve storage slots in the contract. This is useful since the contract's storage slots can be adjusted while leaving any child contracts unaffected. As new state variables are added during contract upgrades, the gap needs to be resized to accommodate the newly used slots.

The `DHedge` and `DHedgeFactory` contracts did not resize their storage gaps, which could affect any child contracts using the code. The risk was significantly lowered as there were no child contracts of either the `DHedge` and `DHedgeFactory` contracts in the in-scope codebase. However, the gap should still be adjusted to adhere to upgradeable contract coding practices and in the event of any external parties inheriting from the affected contracts.

#### Recommendation

The `DHedge` storage gap should be modified to 48 to accommodate for the 2 new state variables. Similarly, the `DHedgeFactory` storage gap should be adjusted to 45 to accommodate for the 5 new state variables.

### 5.4.4 Insufficient unit test quality

#### Description

Although the code coverage of the `DHedge` smart contract was satisfactory, it was determined that some common scenarios were not explicitly tested. In particular, the unit tests relied on the value set during initialization to emulate the pool’s performance and did not test more realistic changes in the pool’s value.

No vulnerabilities were identified due to the lack of these types of tests, but adding additional tests of this nature will reduce the likelihood that issues will be introduced in future.

#### Recommendation

The unit test suite should be expanded to include scenarios where the pool has underperformed and lost value, as well as various other performance over time scenarios. This will require significant changes to the mocks that have been developed, to allow for adjusting the exchanges rates of the underlying assets.

### 5.4.5 Not using `safeTransfer`

#### Description

The `DHedge.withdraw()` function did not make use of the `safeTransfer` function from the [OpenZeppelin SafeERC20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/utils/SafeERC20.sol) library. The `safeTransfer` function abstracts the standard ERC-20 `transfer` function and throws an exception if the transfer returns `false`. This adds an additional layer of validation in case the ERC-20 token returns `false` on failed transfers instead of reverting. A mitigating factor was the assumption that the contracts would only interact with synths, which should not require `safeTransfer` to transfer safely.

#### Recommendation

The OpenZeppelin SafeERC20 library should be used to wrap all important ERC-20 functions as a defense in-depth measure. Alternatively, the transfer could be wrapped in a `require` statement, which achieves a similar effect.

### 5.4.6 Design comments

Actions to improve the functionality and readability of the codebase are outlined below.

#### Redundant function argument

The function `DHedgeFactory.setPoolManagerFeeNumerator()` function validated that the pool argument is equal to the `msg.sender`. Since, it also validated that the `msg.sender` is a pool address, the `pool` argument was redundant.

The code is given below for reference:
require(pool == msg.sender && isPool[msg.sender] == true, "only a pool can change own fee");

To simplify the function logic and reduce gas, the `pool` argument should not be used in the function and all instances should just be replaced with `msg.sender`. The requirement that the `pool` is equal to the `msg.sender` can then also be removed. However, in order to maintain backwards compatibility the function prototype should remain as is.

#### Refactoring suggestions

1. [DHPTSwap.sol#L370](https://github.com/dhedge/dhedge-solidity/blob/f22fc29c0ce434ab45c7b77b339c8d611f41abe0/contracts/DHPTSwap.sol#L370) The `tokenPriceWithSettle()` function should be renamed to `tokenPriceWithPendingSettlement()` to indicate that that the settlement is pending, and the rebate and reclaim amounts are not transferred.
2. [DHPTSwap.sol#L299](https://github.com/dhedge/dhedge-solidity/blob/f22fc29c0ce434ab45c7b77b339c8d611f41abe0/contracts/DHPTSwap.sol#L299) The `enableBuySell()` function should be renamed to `toggleBuySell()` since the function can allow for enabling or disabling the buys and sells.
3. [DHedgeFactory.sol#L98](https://github.com/dhedge/dhedge-solidity/blob/f22fc29c0ce434ab45c7b77b339c8d611f41abe0/contracts/DHedgeFactory.sol#L98), [DHedgeFactory.sol#L99](https://github.com/dhedge/dhedge-solidity/blob/f22fc29c0ce434ab45c7b77b339c8d611f41abe0/contracts/DHedgeFactory.sol#L99)  These `_exitFeeNumerator` and `_exitFeeDenominator` state variables could be renamed to show that the state variables are no longer in use but should not be removed. An example of this is `_exitFeeNumerator_STUBBED_DO_NOT_REMOVE` and `_exitFeeDenominator_STUBBED_DO_NOT_REMOVE`.
4. [DHPTSwap.sol#L235](https://github.com/dhedge/dhedge-solidity/blob/f22fc29c0ce434ab45c7b77b339c8d611f41abe0/contracts/DHPTSwap.sol#L235) The `if` statement at the end of the `_isOracleSigValid` function in the DHPTSwap contract was redundant and should be removed. The function could instead just return the result of the comparison ` return ECDSA.recover(ethHash, signature) == oracle;`

#### Code cleanup

1. The `DHedgeFactory` contains several mutators that modify state variables that pools read from, such as the manager fees and important contract addresses. All of these state variables, including the `DHedgeFactory` state variables, could be abstracted into a `Config` contract. This contract can house all of the configurable state for all contracts, resulting in more succinct code. This change also eliminates the need for all pools to have a reference back to the factory contract.
2. Pool exit fees were removed in this iteration of the system. However, several functions relating to setting and getting exit fee parameters were still present, such as `DHedgeFactory.setExitFee()` and `DHedgeFactory.getExitFee()`.  These functions can be removed, however, care should be taken to ensure that the exit fee state variables remain to prevent storage conflict.
3. The `DHedge.setManagerFeeNumerator()` function could be modified to reuse the internal `DHedge._setManagerFeeNumerator()` function. The public function could be modified to require that `numerator < managerFeeNumerator` and then call `_setManagerFeeNumerator()` if it passes.
4. The DHedgeFactory contract included import statements for the following unused contracts: `ISynthetix.sol`, `IExchangeRates.sol`.
5.  The IExchanger instance declared at [DHedge.sol#L346](https://github.com/dhedge/dhedge-solidity/blob/f22fc29c0ce434ab45c7b77b339c8d611f41abe0/contracts/DHedge.sol#L346) was not used and should be removed.
6.  The public functions in the DHPTSwap contract had large segments of duplicated code. To reduce the contract size and also ensure that the implementations remain consistent, the code should be refactored to make use of internal function calls. The lines of code in the token buying functions at [DHPTSwap.sol#L116-L132](https://github.com/dhedge/dhedge-solidity/blob/f22fc29c0ce434ab45c7b77b339c8d611f41abe0/contracts/DHPTSwap.sol#L116-L132) and [DHPTSwap.sol#L156-L174](https://github.com/dhedge/dhedge-solidity/blob/f22fc29c0ce434ab45c7b77b339c8d611f41abe0/contracts/DHPTSwap.sol#L156-L174) are identical and could be replaced by an internal function, such as `_buyDHPT`. Similarly, lines [DHPTSwap.sol#L82-L95](https://github.com/dhedge/dhedge-solidity/blob/f22fc29c0ce434ab45c7b77b339c8d611f41abe0/contracts/DHPTSwap.sol#L82-L95) and [DHPTSwap.sol#L200-L214](https://github.com/dhedge/dhedge-solidity/blob/f22fc29c0ce434ab45c7b77b339c8d611f41abe0/contracts/DHPTSwap.sol#L200-L214) could be refactored as an internal function called `_sellDHPT`.

#### Gas optimization

1. [DHedge.sol#L395](https://github.com/dhedge/dhedge-solidity/blob/f22fc29c0ce434ab45c7b77b339c8d611f41abe0/contracts/DHedge.sol#L395) The `_settleAll()` can be modified to check for suspended synths before trying to settle. This avoids wasting gas if it is found that the function will revert due to a suspended synth.

#### Non-standard Proxy Pattern

The `DHedgeFactory` smart contract was used to create new instances of the `DHedge` smart contract using an upgradable proxy pattern. However, the pattern was non-standard as the implementation method of the proxy contract linked back to the `DHedgeFactory`’s `getLogic` function.

Furthermore, the custom implementation was within the `BaseUpgradeabilityProxy` contract, which has the same name as that developed by OpenZeppelin. This could cause confusion or result in incorrect assumptions about the behaviour of the proxy during development.

To make it clear that this is a non-standard implementation, it is recommended that contract be renamed and that in-line source comments are added to describe the deviations in logic.

Secure your system.
Request a service
Start Now