-
Notifications
You must be signed in to change notification settings - Fork 43
Sitvanit/add curve #14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
sitvanit83
wants to merge
12
commits into
master
Choose a base branch
from
sitvanit/add-curve
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
af657ed
added conf, builtin
sitvanit83 2291c31
fixed type
sitvanit83 55d4596
removed and added to .gitignore emv directories
sitvanit83 d5178cb
Added the original curve with the builin spec and renamed the previou…
sitvanit83 dc53bde
review comments
sitvanit83 9fe34e1
typo
sitvanit83 8b2bb6f
Updated readme
sitvanit83 d3dea70
renamed munged
sitvanit83 e1d1d9d
review comments
sitvanit83 adad2ed
Directory restructure
sitvanit83 1caa9af
Added comments
sitvanit83 e56d46c
added link to article on the vulnerability
sitvanit83 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,3 +7,5 @@ | |
**/package-lock.json | ||
**/.idea/ | ||
**/cache/ | ||
**/emv-* | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
|
||
#Curve | ||
|
||
This directory contains a simplified contract that is based on the past | ||
`read-only reentrancy` vulnerability of one of the `Curve` pools described [here](https://chainsecurity.com/curve-lp-oracle-manipulation-post-mortem/) | ||
|
||
##Contracts | ||
The original simplified contract is `SimplifiedCurve` whose weakness is found by the builtin rule `viewReentrancy`. | ||
Another | ||
contract is `ManualInstrumentationCurve` that allows finding the weakness also with a regular rule. This is used to | ||
demonstrate what the builtin rule actually does. | ||
|
||
##Specs | ||
`certora/specs` contains two spec files for exposing this weakness. | ||
|
||
1. `BuiltinViewReentrancy.spec` uses the builtin rule `viewReentrancy` that checks that for every solidity function and every | ||
DanieLion55 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
view function the read-only reentrancy weakness is not present. This spec is used for finding the weakness in SimplifiedCurve. | ||
2. `ViewReentrancy.spec` uses regular rules for checking that for every solidity function | ||
the read only reentrancy weakness is not present for the view function `getVirtualPrice()` only. | ||
It is not checked for all view functions. | ||
This is done by using ghosts for tracking: | ||
1. The value of `getVirtualPrice()` at the current state. | ||
2. The value of `getVirtualPrice()` before the unresolved call that is in the checked solidity function. | ||
3. The value of `getVirtualPrice()` after the unresolved call that is in the checked solidity function. | ||
4. The existence of a read-only weakness with respect to `getVirtualPrice()`. | ||
Two hooks are defined. One for updating (1) and one for updating (4). | ||
Additional instrumentation is required in order to catch the bug. This spec works on the contract | ||
`ManualInstrumentationSimplifiedCurve`. | ||
|
||
Both rules check the existence of the weakness by checking | ||
that the result of a view function after an | ||
unresolved call is equal either to the result of this view function at the beginning or at the end of the | ||
calling solidity function. | ||
|
||
Both specs find that the weakness exists in the the above contracts. | ||
|
||
## Failing Code: | ||
|
||
The rule `no_read_only_reentrancy` fails for function `remove_liquidity`. In `remove_liquidity` the unresolved call is performed in an unstable | ||
state, after the call to `CurveToken(lp_token).burnFrom` and before the call to `ERC20(coins_1).transfer`. | ||
|
||
For running the builtin rule run | ||
```certoraRun certora/conf/broken/runViewReentrancyBuiltinRule.conf``` | ||
|
||
For running the regular rule run | ||
|
||
```certoraRun certora/conf/broken/runViewReentrancyRegularRule.conf``` | ||
|
||
The report of this run can be found in | ||
|
||
[Report of failure with regular rule](https://prover.certora.com/output/1902/fac7a9437752438d85472b0446247aff?anonymousKey=a1fb2c1b2e88bd10a64601831ce2cd8912d2de53) | ||
|
||
## Correct Code | ||
|
||
The read-only reentrancy weakness was fixed by adding at the top of each view function a requiremt | ||
that prevents running the view function in case of an inconsistent state. | ||
|
||
The resulting code without instrumentation is `SimplifiedCurveFixed.sol`. The command to check the builtin rule | ||
on this contract is | ||
|
||
```certoraRun certora/conf/correct/runViewReentrancyFixedBuiltinRule.conf``` | ||
|
||
The report of this run can be found in | ||
|
||
[Report of correctness with builtin rule](https://prover.certora.com/output/1902/a2845c679b6a4028af918b842916ad8c?anonymousKey=fe54be4932f20347abe18ac7f7afeb9665d2a8f8) | ||
|
||
|
||
The resulting code with instrumentation is `ManualInstrumentationSimplifiedCurveFixed`. The command to check the regular rule | ||
on this contract is | ||
|
||
```certoraRun certora/conf/correct/runViewReentrancyFixedRegularRule.conf``` | ||
|
||
The report of this run can be found in | ||
|
||
[Report of correctness with regular rule](https://prover.certora.com/output/1902/a411fe10787b4a778f0b63848da18d78?anonymousKey=5c2538f9a28f026d9e471c76651212bb610bf488) | ||
|
||
|
20 changes: 20 additions & 0 deletions
20
CVLByExample/Curve/certora/conf/broken/runViewReentrancyBuiltinRule.conf
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
{ | ||
"files": [ | ||
"contracts/broken/SimplifiedCurve.sol", | ||
"contracts/CurveTokenExample.sol", | ||
"contracts/ERC20.sol" | ||
], | ||
"verify": "SimplifiedCurve:certora/specs/BuiltinViewReentrancy.spec", | ||
"link": [ | ||
"SimplifiedCurve:lp_token=CurveTokenExample", | ||
"SimplifiedCurve:coins_1=ERC20" | ||
], | ||
"msg": "Simplified Curve with view reentrancy guard", | ||
"send_only": true, | ||
"optimistic_loop": true, | ||
"loop_iter": "3", | ||
"prover_args": [ | ||
"-optimisticFallback true" | ||
], | ||
"server": "production" | ||
} |
20 changes: 20 additions & 0 deletions
20
CVLByExample/Curve/certora/conf/broken/runViewReentrancyRegularRule.conf
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
{ | ||
"files": [ | ||
"contracts/broken/ManualInstrumentationSimplifiedCurve.sol", | ||
"contracts/CurveTokenExample.sol", | ||
"contracts/ERC20.sol" | ||
], | ||
"verify": "ManualInstrumentationSimplifiedCurve:certora/specs/ViewReentrancy.spec", | ||
"link": [ | ||
"ManualInstrumentationSimplifiedCurve:lp_token=CurveTokenExample", | ||
"ManualInstrumentationSimplifiedCurve:coins_1=ERC20" | ||
], | ||
"msg": "Simplified Curve with view reentrancy guard", | ||
"send_only": true, | ||
"optimistic_loop": true, | ||
"loop_iter": "3", | ||
"prover_args": [ | ||
"-optimisticFallback true" | ||
], | ||
"server": "production" | ||
} |
20 changes: 20 additions & 0 deletions
20
CVLByExample/Curve/certora/conf/correct/runViewReentrancyFixedBuiltinRule.conf
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
{ | ||
"files": [ | ||
"contracts/correct/SimplifiedCurveFixed.sol", | ||
"contracts/CurveTokenExample.sol", | ||
"contracts/ERC20.sol" | ||
], | ||
"verify": "SimplifiedCurveFixed:certora/specs/BuiltinViewReentrancy.spec", | ||
"link": [ | ||
"SimplifiedCurveFixed:lp_token=CurveTokenExample", | ||
"SimplifiedCurveFixed:coins_1=ERC20" | ||
], | ||
"msg": "Simplified Curve with view reentrancy guard", | ||
"send_only": true, | ||
"optimistic_loop": true, | ||
"loop_iter": "3", | ||
"prover_args": [ | ||
"-optimisticFallback true" | ||
], | ||
"server": "production" | ||
} |
20 changes: 20 additions & 0 deletions
20
CVLByExample/Curve/certora/conf/correct/runViewReentrancyFixedRegularRule.conf
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
{ | ||
"files": [ | ||
"contracts/correct/ManualInstrumentationSimplifiedCurveFixed.sol", | ||
"contracts/CurveTokenExample.sol", | ||
"contracts/ERC20.sol" | ||
], | ||
"verify": "ManualInstrumentationSimplifiedCurveFixed:certora/specs/ViewReentrancy.spec", | ||
"link": [ | ||
"ManualInstrumentationSimplifiedCurveFixed:lp_token=CurveTokenExample", | ||
"ManualInstrumentationSimplifiedCurveFixed:coins_1=ERC20" | ||
], | ||
"msg": "Simplified Curve with view reentrancy guard", | ||
"send_only": true, | ||
"optimistic_loop": true, | ||
"loop_iter": "3", | ||
"prover_args": [ | ||
"-optimisticFallback true" | ||
], | ||
"server": "production" | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
use builtin rule viewReentrancy; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
|
||
using ERC20 as Token; | ||
using CurveTokenExample as LPToken; | ||
|
||
|
||
ghost uint256 before_func1; | ||
ghost uint256 after_func1; | ||
ghost uint256 current_func1; | ||
ghost bool cond; | ||
|
||
// hook on the return value of the view function | ||
hook Sstore solghost_return_func1 uint256 newValue (uint256 oldValue) STORAGE { | ||
current_func1 = newValue; | ||
} | ||
|
||
// hook on the read only reentrancy condition. | ||
// true is the current result of the view function is equal to the result before the unresolved or | ||
// to the result after the unresolved. | ||
hook Sstore solghost_trigger_check bool newValue (bool oldValue) STORAGE { | ||
cond = cond && ((current_func1 == before_func1) || (current_func1 == after_func1)); | ||
} | ||
|
||
// Using require for setting before_func1 to the value of getVirtualPrice before the unresolved call and | ||
// setting after_func1 to the value of getVirtualPrice after the unresolved call. | ||
rule no_read_only_reentrancy(method f) | ||
{ | ||
env e; | ||
env e_external; | ||
calldataarg data; | ||
require cond; | ||
require before_func1 == getVirtualPrice(e_external); | ||
f(e, data); | ||
require after_func1 == getVirtualPrice(e_external); | ||
assert cond; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is extremely hard to understand, lets wait for the summarization that can call solidity and it will be clean and easy to follow. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.