Penetration Test Report (TrailOfBits): Flexa

Flexa
Security Assessment
September 2 0th, 2 019
Prepared For:
Flexa Engineering
dev@flexa.network
Prepared By:
Josselin Feist | T rail of Bits
josselin.feist@trailofbits.com
Robert Tonic | T rail of Bits
robert.tonic@trailofbits.com
Changelog:
September 20th, 2019: Initial report delivered
September 26th, 2019: Added A ppendix C with retest results
Executive Summary
Project Dashboard
Engagement Goals
Coverage
Recommendations Summary
Short Term
Long Term
Findings Summary
1. Initial configuration may allow an attacker to refund an unconfirmed deposit early on
2. Front-running fallback root update might lead to additional withdrawal
3. Missing nonce on PendingDepositRefund event might lead to a double spend
4. A withdrawal root could be added again after removal
5. Missing validations on administration functions
6. setOwner should be split into two separate functions
7. Reentrancy could cause incorrect information to be emitted
A. Vulnerability Classifications
B. Code Quality
C. Fix Log
Detailed Fix Log
© 2019 Trail of Bits Flexa Assessment | 1
Executive Summary
From September 16th through September 20th, 2019, Flexa engaged Trail of Bits to review
the security of the Flexa staking system. Trail of Bits conducted this assessment over the
course of two person-weeks with two engineers working from commit 6 128...b54.
The review focused on the Flexa staking system’s Merkle tree operations, where off-chain
and on-chain operations complement each other. Situations where system operations and
state transitions could lead to lost, trapped, or stolen funds were of particular interest
during review. The codebase was reviewed using S lither, a Solidity static analysis tool, and
manual review.
In total, seven findings were identified, ranging from high to informational severity.
Notably, we found that an integer overflow will cause the withdrawal period to be activated
upon the contract’s deployment, and that a race condition can allow a user to perform one
additional withdrawal if the system is unstable.
To help prevent problems in the future, code quality recommendations have been detailed
in A ppendix B. These recommendations are oriented towards enhancing code readability
and preventing future vulnerabilities from being introduced.
Overall, the staking contract was written with an understanding of common smart contract
pitfalls. No critical flaws were found, and most issues were related to improper
configuration or abuse of off-chain resources. Improvements could be made in the
documentation, particularly the description of the withdrawal procedure and assumptions
for nonces.
Flexa should address these findings before production deployment, and consider adding
an incident response plan to the system documentation. Trail of Bits recommends an
assessment of the off-chain code before deploying the system.
Update: On September 26th, 2019, Trail of Bits reviewed fixes proposed by Flexa for the issues
presented in this report. See a detailed review of the current status of each issue in A ppendix C.
© 2019 Trail of Bits Flexa Assessment | 2
Project Dashboard
Application Summary
Name Flexa
Version 6128af62da3923d007e44637bfb2676c23e7ab54
Type Solidity, JavaScript
Platforms Ethereum
Engagement Summary
Dates September 16th to September 20th, 2019
Method Whitebox
Consultants Engaged 2
Level of Effort 2 person-weeks
Vulnerability Summary
◼◼
Total High-Severity Issues 2
◼
Total Medium-Severity Issues 1
◼
Total Low-Severity Issues 1
◼◼◼
Total Informational-Severity Issues 3
Total 7
Category Breakdown
◼
Access Controls 1
◼◼◼
Auditing and Logging 4
◼
Data Validation 1
◼
Timing 1
Total 7
© 2019 Trail of Bits Flexa Assessment | 3
Engagement Goals
The engagement was scoped to provide a security assessment of the Flexa staking system’s
Ethereum smart contracts. While the off-chain components of the system were not within
the scope of this engagement, the effect of malicious on-chain operations on off-chain
components was considered during review.
Specifically, we sought to answer the following questions:
● Can funds become trapped or non-withdrawable?
● Can funds be stolen by a malicious user withdrawing funds?
● Is there any way to cause a Denial of Service for off-chain infrastructure dependent
on on-chain infrastructure?
● Can a malicious user exploit the on-chain Merkle tree operations?
● Can the fallback root operations be manipulated maliciously?
● Can the withdrawal root operations be manipulated maliciously?
Coverage
Merkle tree. W e looked for flaws in the Merkle tree computation, including incorrect
proofs, validations, and potential out-of-gas exceptions.
Withdrawal. W e reviewed the nonce usage to ensure that a withdrawal could not take
place multiple times. We took into consideration front-running and replay attacks.
Withdrawal fallback. W e checked that a deposit could not be withdrawn if accepted by
the Merkle tree, and we looked for ways to bypass the fallback mechanism restrictions.
Only the smart contract was reviewed. We did not assess the off-chain code, and assumed
the correct Merkle tree generation and reporting. We assumed that deposits are included
in the fallback root before their amount are included in the standard withdrawal tree.
Additionally, Flexa was aware of the loss or benefit of funds due to the off-chain/on-chain
balance’s desynchronisation reached after the withdrawal period.
© 2019 Trail of Bits Flexa Assessment | 4
Recommendations Summary
This section combines all the recommendations made during the engagement. Short-term
recommendations address the immediate issues. Long-term recommendations pertain to
the development process and long-term design goals.
Short Term
❑ Change the initial value of _ fallbackSetDate (Staking.sol#L41) t o prevent overflow
with _ fallbackWithdrawalDelaySeconds ( Staking.sol#L25). The overflow will trigger the
withdrawal period upon the contract’s deployment.
❑ Prevent overflow on the withdrawal period verification in w ithdrawFallback and
refundPendingDeposit. The overflow will trigger the withdrawal period upon the contract’s
deployment.
❑
Document how to update the fallback root if the withdrawal period is active. T o
prevent additional withdrawals, the update should be split into two calls:
● the first call setting to the previous root, and
● the second to the updated one.
❑ Add the nonce to the P endingDepositRefund event. Ensure the off-chain code uses
it. The lack of nonce information can mislead off-chain code to think another deposit was
removed.
❑
Ensure documentation is provided on the expected functionality of the withdrawal
root–related functions. This should include the potential for duplicate roots to be posted.
❑
Ensure all inputs are appropriately validated for their zero values, including:
● newOwnerAddress != 0 in s etOwner (Staking.sol#L362-370)
● newFallbackDelaySeconds != 0 in s etFallbackWithdrawalDelay
(Staking.sol#L442-L451)
● root != 0 in a ddWithdrawalRoot (Staking.sol#L460-L488) and s etFallbackRoot
(Staking.sol#L517-L540)
The lack of a zero-value check might easily lead to incorrect configuration of the contract.
❑ Ensure in the off-chain code that the n ewOwnerAddress is always under control
before invocation of s etOwner. s etOwner will set the new owner without any verification
of the destination. Calling s etOwner with an incorrect value may be an irrevocable error.
© 2019 Trail of Bits Flexa Assessment | 5
❑ Use the C hecks-Effects-Interactions pattern for all the token interactions (d eposit,
withdraw, w ithdrawFallback, r efundPendingDeposit) . The current operations order
might allow reentrancies.
© 2019 Trail of Bits Flexa Assessment | 6
Long Term
❑ Use S afeMath for all arithmetic operations. It is a best practice to use S afeMath to
prevent arithmetic issues.
❑
Write an incident response plan that includes strategies to handle compromise
and network congestion. H aving a procedure to follow will prevent errors when reacting
quickly to a compromise.
❑
Document every field t