If you notice some outdated information please let us know!
PASS
The final review score is indicated as a percentage. The percentage is calculated as Achieved Points due to MAX Possible Points. For each element the answer can be either Yes/No or a percentage. For a detailed breakdown of the individual weights of each question, please consult this document.
Very simply, the audit looks for the following declarations from the developer's site. With these declarations, it is reasonable to trust the smart contracts.
This report is for informational purposes only and does not constitute investment advice of any kind, nor does it constitute an offer to provide investment advisory or other services. Nothing in this report shall be considered a solicitation or offer to buy or sell any security, token, future, option or other financial instrument or to offer or provide any investment advice or service to any person in any jurisdiction. Nothing contained in this report constitutes investment advice or offers any opinion with respect to the suitability of any security, and the views expressed in this report should not be taken as advice to buy, sell or hold any security. The information in this report should not be relied upon for the purpose of investing. In preparing the information contained in this report, we have not taken into account the investment needs, objectives and financial circumstances of any particular investor. This information has no regard to the specific investment objectives, financial situation and particular needs of any specific recipient of this information and investments discussed may not be suitable for all investors.
Any views expressed in this report by us were prepared based upon the information available to us at the time such views were written. The views expressed within this report are limited to DeFiSafety and the author and do not reflect those of any additional or third party and are strictly based upon DeFiSafety, its authors, interpretations and evaluation of relevant data. Changed or additional information could cause such views to change. All information is subject to possible correction. Information may quickly become unreliable for various reasons, including changes in market conditions or economic circumstances.
This completed report is copyright (c) DeFiSafety 2023. Permission is given to copy in whole, retaining this copyright label.
This section looks at the code deployed on the relevant chain that gets reviewed and its corresponding software repository. The document explaining these questions is here.
1. Are the smart contract addresses easy to find? (%)
All smart contract addresses can be found here. They have a dedicated subsection in the documentation and were quite easy to find.
2. How active is the primary contract? (%)
Contract Proxy sUSD (Synth) is used an average over 10 times a day, as indicated here.
3. Does the protocol have a public software repository? (Y/N)
Synthetix has a public software repository at Github.
4. Is there a development history visible? (%)
This protocol has a robust development history at 4,438 commits and 279 branches.
5. Is the team public (not anonymous)?
Synthetix LinkedIn features 28 employees.
This section looks at the software documentation. The document explaining these questions is here.
6. Is there a whitepaper? (Y/N)
Location: https://docs.synthetix.io/litepaper/
7. Is the protocol's software architecture documented? (Y/N)
This protocol's software architecture is extensively documented here.
8. Does the software documentation fully cover the deployed contracts' source code? (%)
There is 100% coverage of deployed contracts by software function documentation.
9. Is it possible to trace the documented software to its implementation in the protocol's source code? (%)
There is 100% traceability between software documentation and implemented code. Synthetix links each documented smart contract to its respective location in their GitHub source code.
10. Has the protocol tested their deployed code? (%)
Code examples are in the Appendix at the end of this report.. As per the SLOC, there is 374% testing to code (TtC). This score is guided by the Test to Code ratio (TtC). Generally a good test to code ratio is over 100%. However, the reviewer's best judgement is the final deciding factor.
11. How covered is the protocol's code? (%)
Synthetix code coverage is 94.95%.
12. Does the protocol provide scripts and instructions to run their tests? (Y/N)
Scripts/Instructions location: https://github.com/Synthetixio/synthetix-scripts
13. Is there a detailed report of the protocol's test results?(%)
Synthetix has a very detailed "Actions" repository in their GitHub that includes regular Slither test logs, CodeQL logs, and (outdated) CI.
14. Has the protocol undergone Formal Verification? (Y/N)
Synthetix has undergone formal verification. Report can be found here.
15. Were the smart contracts deployed to a testnet? (Y/N)
Synthetix has 100% been deployed to a testnet.
This section looks at the 3rd party software audits done. It is explained in this document.
16. Is the protocol sufficiently audited? (%)
Synthetix has been audited 20+ times, both before and after deployment. Audit history can be found here.
17. Is the bounty value acceptably high (%)
Synthetix offers an active bug bounty of $100k with Immunefi.
This section covers the documentation of special access controls for a DeFi protocol. The admin access controls are the contracts that allow updating contracts or coefficients in the protocol. Since these contracts can allow the protocol admins to "change the rules", complete disclosure of capabilities is vital for user's transparency. It is explained in this document.
18. Is the protocol's admin control information easy to find?
Synthetix' admin control information was documented at this location. This was quick to find. In addition, Synthetix further breaks down this governance architecture in their documentation..
19. Are relevant contracts clearly labelled as upgradeable or immutable? (%)
Synthetix' relevant contracts (Synthetix, FeePool, Synths) are identified as upgradeable via its Proxy structure, as identified here.
20. Is the type of smart contract ownership clearly indicated? (%)
Ownership via a MultiSig is clearly indicated in this location.
21. Are the protocol's smart contract change capabilities described? (%)
Synthetix mentions that the Proxy contract allows for state upgrades in their key smart contracts. The protocol further explains change capabilities as being essentially limitless. However, each change must go through a rigorous voting process.
22. Is the protocol's admin control information easy to understand? (%)
Synthetix very clearly details admin control information in user-friendly language.
23. Is there sufficient Pause Control documentation? (%)
Synthetix's pause control is documented and explained in this location. The author explains that the introduction of pause control will be iterated and tested regularly. However, no "fire drill" was visibly recorded in the past 3 months.
24. Is there sufficient Timelock documentation? (%)
Synthetix no longer uses timelocks, as described here. However, each improvement proposal has to go through a voting period as well as an implementation period which both require MultiSig votes. As such, the second MultiSig vote for implementation following the proposal approval vote essentially acts as the two-factor verification process that a timelock typically offers, since there are no other ways to upgrade the protocol. Furthermore, implementation can be further delayed in the event of an emergency, but this must also be voted upon by the MultiSig.
25. Is the Timelock of an adequate length? (Y/N)
There are no clear voting period lengths described, but the DAO's respective snapshots seem to indicate that each enacted proposal takes around a week to implement.
This section goes over the documentation that a protocol may or may not supply about their Oracle usage. Oracles are a fundamental part of DeFi as they are responsible for relaying tons of price data information to thousands of protocols using blockchain technology. Not only are they important for price feeds, but they are also an essential component of transaction verification and security. These questions are explained in this document.
26. Is the protocol's Oracle sufficiently documented? (%)
The protocol's oracle source is Chainlink documented at this location. In addition, all synthetic tokens covered by these oracles are identified here, and data refresh rate is provided for each one.
27. Is front running mitigated by this protocol? (Y/N)
Synthetix documents all front running mitigation techniques at this location.
28. Can flashloan attacks be applied to the protocol, and if so, are those flashloan attack risks mitigated? (Y/N)
Flash loans are not applicable for Synthetix's synthetic assets. In addition, SNX could theoretically be flash loaned, but the only use case for those tokens would be to stake them. Since staked tokens enter a 7-day burn period, potential for flash loan manipulations is effectively mitigated.
1pragma solidity ^0.5.16;
2
3pragma experimental ABIEncoderV2;
4
5import "openzeppelin-solidity-2.3.0/contracts/token/ERC20/SafeERC20.sol";
6
7// Inheritance
8import "./Owned.sol";
9import "./MixinSystemSettings.sol";
10import "./interfaces/ICollateralLoan.sol";
11
12// Libraries
13import "./SafeDecimalMath.sol";
14
15// Internal references
16import "./interfaces/ICollateralUtil.sol";
17import "./interfaces/ICollateralManager.sol";
18import "./interfaces/ISystemStatus.sol";
19import "./interfaces/IFeePool.sol";
20import "./interfaces/IIssuer.sol";
21import "./interfaces/ISynth.sol";
22import "./interfaces/IExchangeRates.sol";
23import "./interfaces/IExchanger.sol";
24import "./interfaces/IShortingRewards.sol";
25
26contract Collateral is ICollateralLoan, Owned, MixinSystemSettings {
27 /* ========== LIBRARIES ========== */
28 using SafeMath for uint;
29 using SafeDecimalMath for uint;
30 using SafeERC20 for IERC20;
31
32 /* ========== CONSTANTS ========== */
33
34 bytes32 private constant sUSD = "sUSD";
35
36 // ========== STATE VARIABLES ==========
37
38 // The synth corresponding to the collateral.
39 bytes32 public collateralKey;
40
41 // Stores open loans.
42 mapping(uint => Loan) public loans;
43
44 ICollateralManager public manager;
45
46 // The synths that this contract can issue.
47 bytes32[] public synths;
48
49 // Map from currency key to synth contract name.
50 mapping(bytes32 => bytes32) public synthsByKey;
51
52 // Map from currency key to the shorting rewards contract
53 mapping(bytes32 => address) public shortingRewards;
54
55 // ========== SETTER STATE VARIABLES ==========
56
57 // The minimum collateral ratio required to avoid liquidation.
58 uint public minCratio;
59
60 // The minimum amount of collateral to create a loan.
61 uint public minCollateral;
62
63 // The fee charged for issuing a loan.
64 uint public issueFeeRate;
65
66 bool public canOpenLoans = true;
67
68 /* ========== ADDRESS RESOLVER CONFIGURATION ========== */
69
70 bytes32 private constant CONTRACT_SYSTEMSTATUS = "SystemStatus";
71 bytes32 private constant CONTRACT_EXRATES = "ExchangeRates";
72 bytes32 private constant CONTRACT_EXCHANGER = "Exchanger";
73 bytes32 private constant CONTRACT_FEEPOOL = "FeePool";
74 bytes32 private constant CONTRACT_SYNTHSUSD = "SynthsUSD";
75 bytes32 private constant CONTRACT_COLLATERALUTIL = "CollateralUtil";
76
77 /* ========== CONSTRUCTOR ========== */
78
79 constructor(
80 address _owner,
81 ICollateralManager _manager,
82 address _resolver,
83 bytes32 _collateralKey,
84 uint _minCratio,
85 uint _minCollateral
86 ) public Owned(_owner) MixinSystemSettings(_resolver) {
87 manager = _manager;
88 collateralKey = _collateralKey;
89 minCratio = _minCratio;
90 minCollateral = _minCollateral;
91 }
92
93 /* ========== VIEWS ========== */
94
95 function resolverAddressesRequired() public view returns (bytes32[] memory addresses) {
96 bytes32[] memory existingAddresses = MixinSystemSettings.resolverAddressesRequired();
97 bytes32[] memory newAddresses = new bytes32[](6);
98 newAddresses[0] = CONTRACT_FEEPOOL;
99 newAddresses[1] = CONTRACT_EXRATES;
100 newAddresses[2] = CONTRACT_EXCHANGER;