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 Mainnet that gets reviewed and its corresponding software repository. The document explaining these questions is here.
1. Are the executing code addresses readily available? (%)
Guidance: 100% Clearly labelled and on website, docs or repo, quick to find 70% Clearly labelled and on website, docs or repo but takes a bit of looking 40% Addresses in mainnet.json, in discord or sub graph, etc 20% Address found but labelling not clear or easy to find 0% Executing addresses could not be found
2. Is the code actively being used? (%)
Activity is below 10 transactions a day on contract MCDMonitorV2.sol , as indicated in the Appendix.
3. Is there a public software repository? (Y/N)
Is there a public software repository with the code at a minimum, but also normally test and scripts. Even if the repository was created just to hold the files and has just 1 transaction, it gets a "Yes". For teams with private repositories, this answer is "No"
4. Is there a development history visible? (%)
With over 253 commits and 14 branches across many software repositories, they have an excellent development history.
This metric checks if the software repository demonstrates a strong steady history. This is normally demonstrated by commits, branches and releases in a software repository. A healthy history demonstrates a history of more than a month (at a minimum).
5. Is the team public (not anonymous)? (Y/N)
For a "Yes" in this question, the real names of some team members must be public on the website or other documentation (LinkedIn, etc). If the team is anonymous, then this question is a "No".
This section looks at the software documentation. The document explaining these questions is here.
7. Are the basic software functions documented? (Y/N)
Software functions were found at https://docs.defisaver.com/protocol/core
8. Does the software function documentation fully (100%) cover the deployed contracts? (%)
Major functions documented at https://docs.defisaver.com/protocol/core
9. Are there sufficiently detailed comments for all functions within the deployed contract code (%)
The Comments to Code (CtC) ratio is the primary metric for this score.
10. Is it possible to trace from software documentation to the implementation in code (%)
Each contract is explained at https://docs.defisaver.com/protocol/core.
11. Full test suite (Covers all the deployed code) (%)
With a TtC of 109%, this is a clearly a complete test suite.
This score is guided by the Test to Code ratio (TtC). Generally a good test to code ratio is over 100%. However the reviewers best judgement is the final deciding factor.
12. Code coverage (Covers all the deployed lines of code, or explains misses) (%)
No indication of code coverage, but there is clearly a reasonably complete set of tests.
13. Scripts and instructions to run the tests? (Y/N)
Scripts and instructions to run test were found at https://github.com/DecenterApps/defisaver-v3-contracts
14. Report of the results (%)
Guidance: 100% Detailed test report as described below 70% GitHub Code coverage report visible 0% No test report evident
15. Formal Verification test done (%)
No evidence of a formal verification was found on the web.
16. Stress Testing environment (%)
Smart Contract Testing Addresses can be found on their Constants Directory.
This section looks at the 3rd party software audits done. It is explained in this document.
17. Did 3rd Party audits take place? (%)
Defi Saver has had an audit done by Debaub in Feb. 2021, an additional Debaub audit in Mar. 2021, and a Consensys audit in Mar. 2021. All of the audits had multiple significant issues. Many were fixed but given the concern we drop the 100% to 70%.
18. Is the bug bounty acceptable high? (%)
Bug Bounty Location: https://medium.com/defi-saver/defi-saver-bug-bounty-is-now-live-on-immunefi-56af32d0c220
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.
19. Can a user clearly and quickly find the status of the access controls (%)
Access controls are clearly labelled in their Documentation.
20. Is the information clear and complete (%)
a) upgradability is indicated clearly for automation smart contracts, and vaguely for protocol smart contracts: 20% b) Type of ownership is clearly indicated for Automation smart contracts, but not protocol action contracts: 15% c) Capabiilities for change in the contracts is not described: 0%
21. Is the information in non-technical terms that pertain to the investments (%)
It's easy to understand. Guidance: 100% All the contracts are immutable 90% Description relates to investments safety and updates in clear, complete non-software l language 30% Description all in software specific language 0% No admin control information could not be found
22. Is there Pause Control documentation including records of tests (%)
Pause control not documented or explained
1pragma solidity ^0.5.0;
2
3import "./interfaces/ERC20.sol";
4import "./ReentrancyGuard.sol";
5import "./DS/DSMath.sol";
6import "./constants/ConstantAddresses.sol";
7
8contract CTokenInterface is ERC20 {
9 function mint(uint mintAmount) external returns (uint);
10 function redeem(uint redeemTokens) external returns (uint);
11 function redeemUnderlying(uint redeemAmount) external returns (uint);
12 function borrow(uint borrowAmount) external returns (uint);
13 function repayBorrow(uint repayAmount) external returns (uint);
14 function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint);
15 function exchangeRateCurrent() external returns (uint);
16}
17
18contract SaverProxy {
19 function repay(bytes32 _cup, uint _amount, uint _minAmount) public;
20 function boost(bytes32 _cup, uint _amount, uint _minAmount) public;
21}
22
23/// @title Contract will hold cDai and use it for users to borrow and return in the sam tx
24contract DecenterLending is ReentrancyGuard, DSMath, ConstantAddresses {
25
26 //Kovan
27 CTokenInterface public cDai = CTokenInterface(CDAI_ADDRESS);
28 ERC20 public Dai = ERC20(COMPOUND_DAI_ADDRESS);
29
30 modifier onlyOwner() {
31 require(msg.sender == owner);
32 _;
33 }
34
35 address public owner;
36 address public feeAddress;
37 uint public feeAmount;
38 uint public sanityBalance;
39 address public sanityContractAddress;
40
41 constructor(address _owner, uint _feeAmount, address _feeAddress) public {
42 owner = _owner;
43 feeAmount = _feeAmount;
44 feeAddress = _feeAddress;
45 }
46
47 function borrow(uint _amountToBorrow, uint _type, bytes32 _cup, uint _amount, uint _minAmount) public nonReentrant {
48
49 require(cDai.redeemUnderlying(_amountToBorrow) == 0, "Reedem failed");
50
51 uint prevDaiBalance = Dai.balanceOf(address(this));
52
53 //Send money
54 Dai.transfer(msg.sender, _amountToBorrow);
55
56 if (_type == 1) {
57 SaverProxy(msg.sender).repay(_cup, _amount, _minAmount);
58 } else {
59 SaverProxy(msg.sender).boost(_cup, _amount, _minAmount);
60 }
61
62
63 uint currentDaiBalance = Dai.balanceOf(address(this));
64
65 // if feeAmount is 0, feeEarned will be 0
66 uint feeEarned = _amountToBorrow / feeAmount;
67
68 //Where my money bitch
69 require(currentDaiBalance >= add(prevDaiBalance, feeEarned));
70
71 // Transfer the fee earned to the feeAddress
72 Dai.transfer(feeAddress, feeEarned);
73
74 require(Dai.balanceOf(sanityContractAddress) >= sanityBalance, "Sanity check against hackers");
75
76 require(cDai.mint(_amountToBorrow) == 0, "Mint failed");
77 }
78
79
80 / ADMIN ONLY
81
82 / Owner can get his money back
83 function withdraw(uint _amount, address _tokenAddress) public onlyOwner {
84 ERC20(_tokenAddress).transfer(owner, _amount);
85 }
86
87 function changeFee(uint _newFee) public onlyOwner {
88 feeAmount = _newFee;
89 }
90
91 function setSanityAmount(uint _sanityAmount) public onlyOwner {
92 sanityBalance = _sanityAmount;
93 }
94
95 function setSanityContractAddress(address _contractAddress) public onlyOwner {
96 sanityContractAddress = _contractAddress;
97 }
98}
Comments to Code: 875 / 4755 = 18 %
Tests to Code: 5225 / 4755 = 110 %