Upload
others
View
1
Download
0
Embed Size (px)
Citation preview
1
Smart Contract Security Audit
2
1. Executive Summary............................................................................................................................................... 4
2. Audit Methodology................................................................................................................................................. 5
3. Project Background (Context).............................................................................................................................6
3.1 Project Introduction......................................................................................................................................6
3.2 Project Structure...........................................................................................................................................8
3.3 Contract Structure..................................................................................................................................... 10
4. Code Overview......................................................................................................................................................11
4.1 Main File Hash............................................................................................................................................11
4.2 Main function visibility analysis..............................................................................................................12
4.3 Code Audit................................................................................................................................................... 15
4.3.1 Malicious contract deployment due to race condition........................................................ 15
4.3.2 Risks from evil community...........................................................................................................16
4.3.3 Risk of business function interruption caused by drip function........................................17
4.3.4 Too low liquidation preference may damage the enthusiasm of users for liquidation18
4.3.5 There is room for arbitrage when using USDJ to pay fees................................................19
4.3.6 Compiler version security.............................................................................................................20
4.3.7 Missing check of minimum mortgage amount......................................................................21
4.3.8 Web end functionality missing................................................................................................. 22
5. Audit Result............................................................................................................................................................22
5.1 Medium-risk Vulnerability........................................................................................................................22
5.2 Low-risk Vulnerability................................................................................................................................23
3
5.3 Conclusion................................................................................................................................................... 23
6. Statement............................................................................................................................................................... 24
4
1. Executive Summary
On May 29, 2020, the SlowMist security team received the JUST team's security audit application for
JUST system, developed the audit plan according to the agreement of both parties and the
characteristics of the project, and finally issued the security audit report.
The SlowMist security team adopts the strategy of “white box lead, black, grey box assists" to
conduct a complete security test on the project in the way closest to the real attack.
SlowMist Smart Contract DeFi project test method:
Black box
testing
Conduct security tests from an attacker's perspective externally.
Grey box
testing
Conduct security testing on code module through the scripting tool, observing
the internal running status, mining weaknesses.
White box
testing
Based on the open source code, non-open source code, to detect wether there
are vulnerabilities in programs suck as nodes, SDK, etc.
SlowMist Smart Contract DeFi project risk level:
Critical
vulnerabilities
Critical vulnerabilities will have a significant impact on the security of the DeFi
project, and it is strongly recommended to fix the critical vulnerabilities.
High-risk
vulnerabilities
High-risk vulnerabilities will affect the normal operation of DeFi project. It is
strongly recommended to fix high-risk vulnerabilities.
Medium-risk Medium vulnerability will affect the operation of DeFi project. It is recommended
5
vulnerablities to fix medium-risk vulnerabilities.
Low-risk
vulnerabilities
Low-risk vulnerabilities may affect the operation of DeFi project in certain
scenarios. It is suggested that the project party should evaluate and consider
whether these vulnerabilities need to be fixed.
WeaknessesThere are safety risks theoretically, but it is extremely difficult to reproduce in
engineering.
Enhancement
Suggestions
There are better practices for coding or architecture.
2. Audit Methodology
Our security audit process for smart contract includes two steps:
Smart contract codes are scanned/tested for commonly known and more specific
vulnerabilities using public and in-house automated analysis tools.
Manual audit of the codes for security issues. The contracts are manually analyzed to look
for any potential problems.
Following is the list of commonly known vulnerabilities that was considered during the audit of the
smart contract:
Reentrancy attack and other Race Conditions
Replay attack
Reordering attack
Short address attack
Denial of service attack
Transaction Ordering Dependence attack
6
Conditional Completion attack
Authority Control attack
Integer Overflow and Underflow attack
TimeStamp Dependence attack
Gas Usage, Gas Limit and Loops
Redundant fallback function
Unsafe type Inference
Explicit visibility of functions state variables
Logic Flaws
Uninitialized Storage Pointers
Floating Points and Numerical Precision
tx.origin Authentication
"False top-up" Vulnerability
Scoping and Declarations
3. Project Background (Context)
3.1 Project Introduction
JUST is a decentralized finance system of USDJ stablecoin for everyone, anywhere, anytime. With
JUST, anyone can pledge TRX as collateral to generate USDJ through decentralized smart contracts
on the TRON network. USDJ is a stablecoin pegged at 1:1 to USD. By holding USDJ, you can explore
the future of DeFi together with the global community.
Project website: https://www.just.network/
Project testnet website: https://djed-test.tronscan.io/
7
Audit code file:
contract-address.tar.gz
MD5: 7193043773f04c39fb02870c47a5ab63
Files provided by the project side:
White Paper - USDJ Stablecoin System.pdf
MD5: a99bcb4dc12058d31976f90ac9f72c5e
contract-address.tar.gz
MD5: 7193043773f04c39fb02870c47a5ab63
contract-tests.tar.gz
MD5: 3931a84c3cffacae3c9474c8f61ae3c0
contracts.tar.gz
MD5: 47213218b349bdc5272ecec5126a568d
just 测试网使用说明.tar.gz
MD5: 4145566f67a2ad5999a71e56ec91c1c1
8
3.2 Project Structure.
├── SaiProxyCreateAndExecute.sol
├── SaiProxyCreateAndExecute_v2.sol
├── SaiValuesAggregator.sol
├── fab.sol
├── lib
│ ├── ds
│ │ ├── auth.sol
│ │ ├── chief.sol
│ │ ├── guard.sol
│ │ ├── math.sol
│ │ ├── note.sol
│ │ ├── proxy.sol
│ │ ├── proxy_builder.sol
│ │ ├── proxy_builder_v2.sol
│ │ ├── proxy_cache.sol
│ │ ├── proxy_factory.sol
│ │ ├── proxy_factory_v2.sol
│ │ ├── proxy_registry.sol
│ │ ├── proxy_registry_v2.sol
│ │ ├── proxy_v2.sol
│ │ ├── roles.sol
│ │ ├── spell.sol
│ │ ├── stop.sol
│ │ ├── test.sol
│ │ ├── thing.sol
│ │ ├── token.sol
│ │ ├── token_base.sol
│ │ ├── token_factory.sol
│ │ └── value.sol
│ ├── interface
│ │ ├── otc.sol
│ │ ├── otc_proxy.sol
│ │ ├── pep.sol
│ │ ├── tap.sol
│ │ ├── token_deposit.sol
│ │ ├── top.sol
│ │ ├── tub.sol
│ │ └── vox.sol
│ ├── trc20
9
│ │ └── trc20.sol
│ └── utils
│ └── tokenHelper.sol
├── medianizer.sol
├── mom.sol
├── otc.sol
├── otc_proxy.sol
├── pit.sol
├── polling_emitter.sol
├── price_feed.sol
├── sai_proxy.sol
├── tap.sol
├── top.sol
├── tub.sol
├── vox.sol
└── wtrx.sol
10
3.3 Contract StructureThe JUST system is mainly divided into four parts, which are lending, liquidation, oracle machine and
system management. tub contract implements lending function, tap contract implements liquidation
function, and pep, pip and vox contracts provide external prices of JST, TRX and USDJ respectively.
mom contracts manage system parameters. The chief contract is a committee contract with the
highest authority over system administration and the ability to initiate and execute proposals. For
user convenience, the JUST system provides an additional otc contract for the conversion of USDJ
to JST, allowing the user to repay the loan fee via USDJ. The overall structure of the contract is as
follows:
11
4. Code Overview
4.1 Main File Hash
No File Name SHA-1 Hash
1 SaiProxyCreateAndExecute.sol f6c47dc6e69b4b5c1c80d06a7ec667cbd68dd762
2 wtrx.sol d1be9e68ed24a017692f47db4b24617be8302578
3 sai_proxy.sol 5a314847f06972befda3941e72cf535db69ee84b
4 SaiProxyCreateAndExecute_v2.sol31789985f69e614405d34938537f686610e93e89
5 otc_proxy.sol 45db9a13344a03dae9bee7029266ed990293cf63
6 SaiValuesAggregator.sol 5545d88a20dc543b24612373637d135e53a79a93
7 fab.sol faad8fdcdd5b609d5088f609e9d2a1cac5f12517
8 mom.sol 9467993d307fb18e08c2a1508f373e504dd8893f
9 tub.sol 2afa835c300558156b87d3fd81f4b8dd8f011801
10 vox.sol d501becad653d2a229daae7a263f3ecee140f685
11 top.sol 33356a409ceedf49be1580edf8054a0b0adb3f9d
12 tap.sol bdad237397bd0da56a349a6866629551ba6f8eb2
13 otc.sol ec9e5cfb018bc20beb30e0322c22151c0cc0fae7
14 pit.sol 4b6b9962ea59b925019c783903d36cd7ce58a39e
15 polling_emitter.sol b486d2e4e8c5563a5c24775e3b08d30b35c80938
12
4.2 Main function visibility analysis
Contract Name Function Name Visibility
SaiProxyCreateAndExecute
Implementation SaiProxy
createAndOpen Public
createOpenAndLock Public
createOpenLockAndDraw Public
WTRX
Implementation ITokenDeposit
Constructor Public
deposit Public
withdraw Public
totalSupply Public
balanceOf Public
allowance Public
approve Public
approve Public
transfer Public
16 price_feed.sol 45d8f903fa665b58e9802fdb2b923a174abd2a00
17 medianizer.sol 36d32f52e952500cc32445c3f69afb706770fba0
13
transferFrom Public
SaiProxy
Implementation DSMath
open Public
give Public
lock Public
draw Public
handleGovFee Internal
wipe Public
wipeOtc Public
wipe Public
free Public
lockAndDraw Public
lockAndDraw Public
wipeAndFree Public
wipeAndFree Public
shut Public
shut Public
SaiProxyCreateAndExecuteV2
Implementation SaiProxy, DSThing
Constructor Public
14
setRegistry Public
setOtcproxy Public
createAndOpen Public
createOpenAndLock Public
createOpenLockAndDraw Public
OtcProxy
Implementation DSThing, IOtcProxy
Constructor Public
getPayAmount Public
buyAllAmount Public
proxyWipe Public
withdraw Public
killMe Public
SaiValuesAggregator
Implementation DSMath
Constructor Public
tub Public
tap Public
vox Public
pit Public
pip Public
15
pep Public
gem Public
gov Public
skr Public
sai Public
sin Public
getContractsAddrs Public
aggregateValues Public
aggregateCDPValues Public
GemFab
Implementation None
newTok Public
VoxFab
Implementation None
newVox Public
4.3 Code Audit
4.3.1 Malicious contract deployment due to race condition
Because the tub contract will be deployed when step == 1, but the tap contract address in the tub
contract is set by the turn function at step == 2, and the turn function in the tub contract is set to
16
public, resulting in a race condition problem, the attacker can call the turn function when the tub
contract is deployed and set up a malicious tap contract, thereby destroying the entire system.
Code location: File fab.sol line 123
function makeTapTop() public auth {
require(step == 2, "wrong step");
tap = tapFab.newTap(tub);
tub.turn(tap);
top = topFab.newTop(tub, tap);
step += 1;
}
function turn(address tap_) public note {
require(tap == 0, "tap address is not empty");
require(tap_ != 0, "new tap address is empty");
tap = tap_;
}
Fix status: After confirming with the project party, this problem only occur if the step is 1. At present,
the JUST contract has been deployed and the step value is 7. This shows that the attack has not
been attacked, and because the step value cannot be modified, it means that similar attacks will not
be possible in the future.
4.3.2 Risks from evil community
The lock function does not restrict the up limit of user’s JST token, when a user have over 50% JST
tokens, malicious user can take all of the asset of JUST system by deploying a malicious contract.
Code location:File chief.sol line 59
function lock(uint wad)
public
17
note
{
GOV.pull(msg.sender, wad);
IOU.mint(msg.sender, wad);
deposits[msg.sender] = add(deposits[msg.sender], wad);
addWeight(wad, votes[msg.sender]);
}
Fix status: After confirming with the project party, JST are strictly locks and releases according to the
lock-up release plan. At present, there is no such possibility of having more than 50% of token. In
addition, if the community vote is not sufficient and leads a malicious proposal get the highest vote,
the contract also provides a protection mechanism for the delay of the highest vote proposal, so that
the community still has 12 hours to cast more votes to overthrow the malicious proposal.
4.3.3 Risk of business function interruption caused by drip function
The drip function uses the pow function of the ds library. Because the function uses O(n) complexity
calculation results, when the system incurs a fee and does not call the drip function for a long time,
the drip function cannot be called , which will cause the system to not operate normally.
Code Location: File tub.sol line 253
function drip() public note {
if (off) return;
uint256 rho_ = era();
uint256 age = rho_ - rho;
if (age == 0) return;
// optimised
rho = rho_;
uint256 inc = RAY;
18
if (tax != RAY) {// optimised
uint256 _chi_ = _chi;
inc = rpow(tax, age);
_chi = rmul(_chi, inc);
//如果 tax 不等于 1 则会按秒增发 sai 给 tap 合约
sai.mint(tap, rmul(sub(_chi, _chi_), rum));
}
// optimised
// fee 稳定费 fee ^(365*24*60*60) = 110%
if (fee != RAY) inc = rmul(inc, rpow(fee, age));
// _rhi 用于计算稳定费
if (inc != RAY) _rhi = rmul(_rhi, inc);
}
Fix status: After confirming with the project party, any cdp operation will directly call drip function
and refresh the rho in the contract. Moreover, even in the worse case, the interval between the two
drip functions needs more than one year to cause the drip function to be unable to be called, So the
scenario of no one use the system for a year will not happen.
4.3.4 Too low liquidation preference may damage the enthusiasm of users for
liquidation
The gap set by mold function does not require it must smaller than WAD, causing user may
exchange PTRX with excess USDJ token and damage the enthusiasm of users for liquidation. We
recommend to restrict it small than WAD.
Code location: File tap.sol line 62
function mold(bytes32 param, uint val) public note auth {
if (param == 'gap') gap = val;
}
19
Fix status: The gap of current parameters is a reasonable parameter, if the subsequent
communities have demands, they can adjust flexibly through proposals.
4.3.5 There is room for arbitrage when using USDJ to pay fees
In the contract, the buyAllAmount function uses USDJ to exchange JST for fee repayment. In
essence, JST is finally used for repayment, but there may be some arbitrage in the code.
Code location: File otc.sol line 58
function buyAllAmount(address mkr_addr, uint256 govAmt_, address sai_addr, uint256 daiAmt_) public returns (uint256) {
DSToken sai_ =DSToken(sai_addr);
DSToken mkr_=DSToken(mkr_addr);
require(sai_ == tub.sai() ,"not the address of USDJ ");
require( mkr_ == tub.gov(),"not the address of JST");
require(msg.sender == proxyAddress, "proxyAddress mismatch");
uint256 daiAmt = getPayAmount(sai_, mkr_, govAmt_);
require(daiAmt_ == daiAmt, "daiAmt mismatch");
require(sai_.transferFrom(msg.sender, address(this), daiAmt_),"USDJ transfer failed");
require(mkr_.transfer(msg.sender,govAmt_),"JST transfer failed");
return govAmt_;
}
Fix status: After confirming with the project party, there is no flash exchange facility in the current
TRON ecology. Under the current conditions, it is most appropriate to use the otc contract to convert
USDJ to JST. The project party has increased the frequency of feeding the otc contract, and the JST
exchanged are restricted to can only be used to return stable fees.
20
4.3.6 Compiler version security
The contracts use different Solidity compiler version, and the versions used are low
- ^0.4.8 (lib/trc20/trc20.sol)
- ^0.4.18 (tap.sol)
- ^0.4.18 (top.sol)
- ^0.4.18 (tub.sol)
- ^0.4.18 (vox.sol)
- ^0.4.24 (wtrx.sol)
- ^0.4.18 (fab.sol)
- ^0.4.23 (medianizer.sol)
- ^0.4.18 (mom.sol)
- >=0.4.23 (otc_proxy.sol)
- >=0.4.23 (otc.sol)
- ^0.4.25 (pit.sol)
- ^0.4.8 (price_feed.sol)
- ^0.4.25 (sai_proxy.sol)
- ^0.4.13 (SaiProxyCreateAndExecute.sol)
- ^0.4.23 (SaiProxyCreateAndExecute_V2.sol)
- ^0.4.24 (SaiValuesAggregator.sol)
Recommend to use 0.4.25 version.
21
Fix status : The compiler version used by the contract during compilation is TRON
Solidity_0.4.25_Odyssey_v3.2.3.
4.3.7 Missing check of minimum mortgage amount
The limits the minimum opening amount of font-end web page is 100 PTRX, but there is no relevant
limit in the contract. According to the current contract restrictions, users only need to mortgage more
than 1 PTRX to initiate a lock position, bypassing the web side restriction.
web end restriction:
Code restriction:
Code Location:File tub.sol line 313
function lock(bytes32 cup, uint wad) public note {
require(!off, "system is off");
wad = wad / (10 ** 12) * (10 ** 12);
cups[cup].ink = add(cups[cup].ink, wad);
skr.pull(msg.sender, wad);
require(cups[cup].ink == 0 || cups[cup].ink > minptrx, "can not reach minptrx num");
}
22
Fix status: After confirming with the project party, the limitation of the front-end web page is actually
to protect users. If there is too little trx deposited by the user, the proportion of the handling fee is too
high, causing the user to lose money.
4.3.8 Web end functionality missing
There is no automatic liquidation function on the web side, but the SaiTub contract has a bite
interface for liquidation, and users cannot directly perform liquidation through the web side.
Fix status: After confirming with the project party, the contract has a complete liquidation function
and is open to all users. Anyone calling the contract can realize liquidation. The official has provided
specific calling methods and documents, which can be invoked by the user to support more easily
customized strategies
5. Audit Result
5.1 Medium-risk Vulnerability
Race condition problem
Risks from evil community
Risk of business function interruption
23
5.2 Low-risk Vulnerability
Liquidation design flaws
Stability fee payment design flaws
Compiler version security
The minimum mortgage amount check is missing
Web side function is missing
5.3 Conclusion
Audit Result : Passed
Audit Number : 0X002006240001
Audit Date : June 24, 2020
Audit Team : SlowMist Security Team
Summary conclusion: The are 8 security issues found during the audit. After communication and
feedback, with the JUST team, confirms that the risks found in the audit process are within the
tolerable range.
24
6. Statement
SlowMist issues this report with reference to the facts that have occurred or existed before the
issuance of this report, and only assumes corresponding responsibility base on these.
For the facts that occurred or existed after the issuance, SlowMist is not able to
judge the security status of this project, and is not responsible for them. The security audit analysis
and other contents of this report are based on the documents and materials provided to SlowMist by
the information provider till the date of the insurance this report (referred to as "provided
information"). SlowMist assumes: The information provided is not missing, tampered with, deleted or
concealed. If the information provided is missing, tampered with, deleted, concealed, or inconsistent
with the actual situation, the SlowMist shall not be liable for any loss or adverse effect resulting
therefrom. SlowMist only conducts the agreed security audit on the security situation of the project
and issues this report. SlowMist is not responsible for the background and other conditions of the
project.
1