-
Notifications
You must be signed in to change notification settings - Fork 3
Added 10 reentrancy vulnerability type smart contracts #94
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
|
||
contract Wallet { | ||
|
||
|
||
mapping (address => uint) m_txs; | ||
|
||
function confirm(address _h, uint value, byte data) returns (bool) { | ||
if (m_txs[_h] != 0) { | ||
_h.call.value(value)(data); | ||
m_txs[_h] -= value; | ||
return true; | ||
} | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
|
||
contract Bank{ | ||
|
||
mapping (address => uint256) public balances; | ||
|
||
function withdraw() { | ||
require(msg.sender.call.value(balances[msg.sender])()); | ||
balances[msg.sender] = 0; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,13 @@ | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
contract dumbDAO { | ||||||||||||||||||||||||||||||||||||
Comment on lines
+1
to
+2
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. 🛠️ Refactor suggestion Add SPDX and explicit pragma. +// SPDX-License-Identifier: UNLICENSED
+pragma solidity 0.4.26;
contract dumbDAO { 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
mapping (address => uint) public balances; | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
function withdraw(address _recipient) returns (bool) { | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
if (_recipient.call.value(balances[msg.sender])()) { | ||||||||||||||||||||||||||||||||||||
balances[msg.sender] = 0; | ||||||||||||||||||||||||||||||||||||
return true; | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
Comment on lines
+6
to
+12
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. 🛠️ Refactor suggestion Reentrancy + missing visibility + ambiguous return path.
- function withdraw(address _recipient) returns (bool) {
-
- if (_recipient.call.value(balances[msg.sender])()) {
- balances[msg.sender] = 0;
- return true;
- }
- }
+ function withdraw(address _recipient) public returns (bool) {
+ uint amount = balances[msg.sender];
+ require(amount > 0);
+ balances[msg.sender] = 0; // effects
+ if (!_recipient.call.value(amount)()) {
+ balances[msg.sender] = amount; // restore on failure
+ return false;
+ }
+ return true;
+ } If intentionally vulnerable, add a clear header comment stating so instead of fixing logic. 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||||||||||||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,14 @@ | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
contract EtherStore { | ||||||||||||||||||||||||||
Comment on lines
+1
to
+2
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. 🛠️ Refactor suggestion Add SPDX and pin pragma. +// SPDX-License-Identifier: UNLICENSED
+pragma solidity 0.4.26;
contract EtherStore { 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
uint256 public withdrawalLimit = 1 ether; | ||||||||||||||||||||||||||
mapping(address => uint256) public balances; | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
function withdrawFunds (uint256 _weiToWithdraw) public { | ||||||||||||||||||||||||||
require(balances[msg.sender] >= _weiToWithdraw); | ||||||||||||||||||||||||||
require(_weiToWithdraw <= withdrawalLimit); | ||||||||||||||||||||||||||
require(msg.sender.call.value(_weiToWithdraw)()); | ||||||||||||||||||||||||||
balances[msg.sender] -= _weiToWithdraw; | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
Comment on lines
+7
to
+12
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. 🛠️ Refactor suggestion Reentrancy in withdrawFunds (CEI violated). Calls msg.sender before reducing balance. Fix by moving effects before interactions; optionally add a reentrancy guard. - function withdrawFunds (uint256 _weiToWithdraw) public {
- require(balances[msg.sender] >= _weiToWithdraw);
- require(_weiToWithdraw <= withdrawalLimit);
- require(msg.sender.call.value(_weiToWithdraw)());
- balances[msg.sender] -= _weiToWithdraw;
- }
+ function withdrawFunds (uint256 _weiToWithdraw) public {
+ require(balances[msg.sender] >= _weiToWithdraw);
+ require(_weiToWithdraw <= withdrawalLimit);
+ balances[msg.sender] -= _weiToWithdraw; // effects
+ require(msg.sender.call.value(_weiToWithdraw)()); // interaction
+ } Optional: add a simple nonReentrant modifier. 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,10 @@ | ||||||||||||||||||||||
|
||||||||||||||||||||||
contract SendBalance { | ||||||||||||||||||||||
|
||||||||||||||||||||||
mapping (address => uint) userBalances ; | ||||||||||||||||||||||
|
||||||||||||||||||||||
function withdrawBalance() { | ||||||||||||||||||||||
if (!(msg.sender.call.value(userBalances[msg.sender])())) { throw ; } | ||||||||||||||||||||||
userBalances[msg.sender] = 0; | ||||||||||||||||||||||
} | ||||||||||||||||||||||
Comment on lines
+6
to
+9
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. Legacy throw + reentrancy window; state updated after external call. Replace throw with require/revert; move zeroing before the call (CEI). Also gate zero-withdrawals. - function withdrawBalance() {
- if (!(msg.sender.call.value(userBalances[msg.sender])())) { throw ; }
- userBalances[msg.sender] = 0;
- }
+ function withdrawBalance() {
+ uint amount = userBalances[msg.sender];
+ require(amount > 0);
+ userBalances[msg.sender] = 0; // effects
+ require(msg.sender.call.value(amount)()); // interaction
+ } 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,12 @@ | ||||||||||||||||||||||
|
||||||||||||||||||||||
contract SimpleDAO { | ||||||||||||||||||||||
Comment on lines
+1
to
+2
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. 🛠️ Refactor suggestion Add SPDX and pragma for deterministic builds. +// SPDX-License-Identifier: UNLICENSED
+pragma solidity 0.4.26;
contract SimpleDAO { 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||
|
||||||||||||||||||||||
mapping (address => uint) public credit; | ||||||||||||||||||||||
|
||||||||||||||||||||||
function withdraw(uint amount) { | ||||||||||||||||||||||
if (credit[msg.sender] >= amount) { | ||||||||||||||||||||||
msg.sender.call.value(amount)(); | ||||||||||||||||||||||
credit[msg.sender] -= amount; | ||||||||||||||||||||||
} | ||||||||||||||||||||||
Comment on lines
+6
to
+10
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. Unchecked low-level call + CEI violated → reentrancy. Return value is ignored and balance is reduced after the call. - function withdraw(uint amount) {
- if (credit[msg.sender] >= amount) {
- msg.sender.call.value(amount)();
- credit[msg.sender] -= amount;
- }
- }
+ function withdraw(uint amount) public {
+ require(credit[msg.sender] >= amount);
+ credit[msg.sender] -= amount; // effects
+ require(msg.sender.call.value(amount)()); // interaction
+ } If kept vulnerable on purpose, add an explicit “INTENTIONALLY VULNERABLE (reentrancy)” banner. 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||
} | ||||||||||||||||||||||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,12 @@ | ||||||||||||||||||||||
|
||||||||||||||||||||||
contract Victim { | ||||||||||||||||||||||
Comment on lines
+1
to
+2
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. 🛠️ Refactor suggestion Missing SPDX and pragma; code targets 0.4.x features. +// SPDX-License-Identifier: UNLICENSED
+pragma solidity 0.4.26;
contract Victim { 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||
|
||||||||||||||||||||||
mapping(address => uint) public balances; | ||||||||||||||||||||||
|
||||||||||||||||||||||
function withdraw(uint _amount) public { | ||||||||||||||||||||||
if(balances[msg.sender] >= _amount) { | ||||||||||||||||||||||
if(!msg.sender.call.value(_amount)()) { throw; } | ||||||||||||||||||||||
balances[msg.sender] -= _amount; | ||||||||||||||||||||||
} | ||||||||||||||||||||||
Comment on lines
+6
to
+10
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. Reentrancy and deprecated throw. External call precedes state update; - function withdraw(uint _amount) public {
- if(balances[msg.sender] >= _amount) {
- if(!msg.sender.call.value(_amount)()) { throw; }
- balances[msg.sender] -= _amount;
- }
- }
+ function withdraw(uint _amount) public {
+ require(balances[msg.sender] >= _amount);
+ balances[msg.sender] -= _amount; // effects
+ require(msg.sender.call.value(_amount)()); // interaction
+ } If this must stay vulnerable, annotate with a loud “DO NOT DEPLOY – reentrancy example” comment. 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||
} | ||||||||||||||||||||||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,15 @@ | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
contract PIGGY_BANK { | ||||||||||||||||||||||||
Comment on lines
+1
to
+2
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. 💡 Verification agent 🧩 Analysis chainPin compiler and add SPDX; code uses pre-0.6 syntax. Without an explicit pragma these may compile against incompatible solc versions. +// SPDX-License-Identifier: UNLICENSED
+pragma solidity 0.4.26;
contract PIGGY_BANK { Run to confirm pragma consistency across the repo: 🏁 Script executed: #!/bin/bash
rg -n --glob '**/*.sol' 'pragma solidity' Length of output: 0 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "PWD: $(pwd)"
echo "Checking for the specific reviewed file:"
if [ -f "audit_engine/smart_contracts/reentrancy/40747.sol" ]; then
echo "FOUND: audit_engine/smart_contracts/reentrancy/40747.sol"
sed -n '1,120p' audit_engine/smart_contracts/reentrancy/40747.sol || true
else
echo "Not found: audit_engine/smart_contracts/reentrancy/40747.sol"
fi
echo
echo "Searching repository for .sol files..."
mapfile -t sols < <(find . -type f -name '*.sol' -print)
if [ ${#sols[@]} -eq 0 ]; then
echo "No .sol files found in repo."
exit 0
fi
echo "Found ${#sols[@]} .sol files. Printing first 40 lines of each (filename header included):"
for f in "${sols[@]}"; do
echo "---- FILE: $f ----"
sed -n '1,40p' "$f" || true
done
echo
echo "Searching those files for 'pragma solidity' and 'SPDX-License-Identifier':"
for f in "${sols[@]}"; do
if grep -nE '^\s*pragma\s+solidity|SPDX-License-Identifier' "$f" >/dev/null 2>&1; then
echo "$f matches:"
grep -nE '^\s*pragma\s+solidity|SPDX-License-Identifier' "$f" || true
fi
done Length of output: 591 Add SPDX header and pin Solidity pragma; fix reentrancy in Collect. audit_engine/smart_contracts/reentrancy/40747.sol is missing an SPDX header and pragma (it uses pre-0.5 syntax). Add a pinned pragma (e.g. 0.4.26) and SPDX. Also fix the reentrancy: Collect calls msg.sender.call.value(_am)() before updating Accounts[msg.sender] — move the state update before the external call or switch to a withdraw/pull pattern and/or add a reentrancy guard. +// SPDX-License-Identifier: UNLICENSED
+pragma solidity 0.4.26;
contract PIGGY_BANK {
🤖 Prompt for AI Agents
|
||||||||||||||||||||||||
|
||||||||||||||||||||||||
mapping (address => uint) public Accounts; | ||||||||||||||||||||||||
uint public MinSum = 1 ether; | ||||||||||||||||||||||||
uint putBlock; | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
function Collect(uint _am) public payable { | ||||||||||||||||||||||||
if(Accounts[msg.sender] >= MinSum && _am <= Accounts[msg.sender]) { | ||||||||||||||||||||||||
if(msg.sender.call.value(_am)()) { | ||||||||||||||||||||||||
Accounts[msg.sender] -= _am; | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
Comment on lines
+8
to
+13
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. Reentrancy via external call before state update (CEI violated). External call forwards all gas and occurs before debiting balance; attacker can re-enter Collect and drain. If this is not intentionally vulnerable, apply CEI and check the call result. Apply this diff: - function Collect(uint _am) public payable {
- if(Accounts[msg.sender] >= MinSum && _am <= Accounts[msg.sender]) {
- if(msg.sender.call.value(_am)()) {
- Accounts[msg.sender] -= _am;
- }
- }
- }
+ function Collect(uint _am) public payable {
+ require(Accounts[msg.sender] >= MinSum && _am <= Accounts[msg.sender]);
+ Accounts[msg.sender] -= _am; // effects
+ require(msg.sender.call.value(_am)()); // interaction
+ } If this contract is intentionally vulnerable, add a prominent “DO NOT DEPLOY – intentionally vulnerable (reentrancy)” header. 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||||
} | ||||||||||||||||||||||||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,10 @@ | ||||||||||||||||||||
|
||||||||||||||||||||
contract BancorBuyer { | ||||||||||||||||||||
|
||||||||||||||||||||
mapping(address => uint256) public balances; | ||||||||||||||||||||
|
||||||||||||||||||||
function buyOne(address _exchange, uint256 _value, bytes _data) payable public { | ||||||||||||||||||||
require(_exchange.call.value(_value)(_data)); | ||||||||||||||||||||
balances[msg.sender] = balances[msg.sender] - _value; | ||||||||||||||||||||
} | ||||||||||||||||||||
Comment on lines
+6
to
+9
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. Unchecked subtraction can underflow; also CEI violation enables reentrancy. If balances[msg.sender] < _value (pre-0.8), Line 8 underflows. Deduct before the call with a bound check; then perform the external call. - function buyOne(address _exchange, uint256 _value, bytes _data) payable public {
- require(_exchange.call.value(_value)(_data));
- balances[msg.sender] = balances[msg.sender] - _value;
- }
+ function buyOne(address _exchange, uint256 _value, bytes _data) payable public {
+ require(balances[msg.sender] >= _value);
+ balances[msg.sender] -= _value; // effects
+ require(_exchange.call.value(_value)(_data)); // interaction
+ } 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,10 @@ | ||||||||||||||||||||||
|
||||||||||||||||||||||
contract Bank{ | ||||||||||||||||||||||
Comment on lines
+1
to
+2
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. 🛠️ Refactor suggestion Missing SPDX and pragma; legacy syntax requires 0.4.x. Without a pragma these files may compile against 0.8.x and fail. Pin a 0.4.x compiler (throw/call.value syntax compatible) and add license. +pragma solidity 0.4.24;
+// SPDX-License-Identifier: UNLICENSED
+
contract Bank{ 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||
|
||||||||||||||||||||||
mapping (address => uint256) public balances; | ||||||||||||||||||||||
|
||||||||||||||||||||||
function withdraw(){ | ||||||||||||||||||||||
require(msg.sender.call.value(balances[msg.sender])()); | ||||||||||||||||||||||
balances[msg.sender] = 0; | ||||||||||||||||||||||
} | ||||||||||||||||||||||
Comment on lines
+6
to
+9
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. Reentrancy: external call before zeroing balance (CEI violation). Attacker can reenter via fallback before Line 8 and drain funds. Zero-out balance before the call and gate zero withdrawals. Apply: - function withdraw(){
- require(msg.sender.call.value(balances[msg.sender])());
- balances[msg.sender] = 0;
- }
+ function withdraw() {
+ uint256 amount = balances[msg.sender];
+ require(amount > 0);
+ balances[msg.sender] = 0; // effects first
+ require(msg.sender.call.value(amount)()); // interaction after
+ } 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Multiple issues: reentrancy, unchecked call result, and underflow.
📝 Committable suggestion
🤖 Prompt for AI Agents