Skip to content

Commit

Permalink
Merge pull request #171 from eshaan-deepsource/master
Browse files Browse the repository at this point in the history
add Solidity and Vyper files for Slither and Solhint analyzers
  • Loading branch information
jai-deepsource authored Jan 16, 2024
2 parents c5684cb + fe63f2a commit cab3713
Show file tree
Hide file tree
Showing 36 changed files with 3,324 additions and 1 deletion.
10 changes: 9 additions & 1 deletion .deepsource.toml
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,12 @@ name = "go"
import_root = "github.com/QuackatronHQ/Gigarepo"

[[analyzers]]
name = "javascript"
name = "javascript"

[[analyzers]]
name = "slither"
type = "community"

[[analyzers]]
name = "solhint"
type = "community"
50 changes: 50 additions & 0 deletions .github/workflows/slither-solidity.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# ref: https://github.com/crytic/slither-action#how-to-use-1
name: Slither Analysis for Solidity

on:
# Note that both `push` and `pull_request` triggers should be present for GitHub to consistently present slither
# SARIF reports.
push:
branches: [main, master]
pull_request:

jobs:
scan:
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
env:
DEEPSOURCE_DSN: ${{ secrets.DEEPSOURCE_DSN }}
steps:
- uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha }}

- name: Run Slither
uses: crytic/[email protected]
id: slither
with:
slither-version: 0.10.0
target: "solidity/"
# The following makes slither produce scan analysis in SARIF format
sarif: ./slither.sarif
# The following line prevents aborting the workflow immediately in case your files fail Slither checks.
# This allows the following upload-sarif action to still upload the results.
continue-on-error: true

- name: Upload SARIF report files to DeepSource
id: upload-sarif
run: |
# Install the CLI
curl https://deepsource.io/cli | sh
# Send the report to DeepSource
./bin/deepsource report --analyzer slither --analyzer-type community --value-file ${{ steps.slither.outputs.sarif }}
# Ensure the workflow eventually fails if files did not pass slither checks.
- name: Verify slither-action succeeded
shell: bash
run: |
echo "If this step fails, slither found issues. Check the output of the scan step above."
[[ "${{ steps.slither.outcome }}" == "success" ]]
51 changes: 51 additions & 0 deletions .github/workflows/slither-vyper.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# ref: https://github.com/crytic/slither-action#how-to-use-1
name: Slither Analysis for Vyper

on:
# Note that both `push` and `pull_request` triggers should be present for GitHub to consistently present slither
# SARIF reports.
push:
branches: [main, master]
pull_request:

jobs:
scan:
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
env:
DEEPSOURCE_DSN: ${{ secrets.DEEPSOURCE_DSN }}
steps:
- uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha }}

- name: Run Slither
uses: crytic/[email protected]
id: slither
with:
slither-version: 0.10.0
solc-version: 0.8.21
target: "vyper/"
# The following makes slither produce scan analysis in SARIF format
sarif: ./slither.sarif
# The following line prevents aborting the workflow immediately in case your files fail Slither checks.
# This allows the following upload-sarif action to still upload the results.
continue-on-error: true

- name: Upload SARIF report files to DeepSource
id: upload-sarif
run: |
# Install the CLI
curl https://deepsource.io/cli | sh
# Send the report to DeepSource
./bin/deepsource report --analyzer slither --analyzer-type community --value-file ${{ steps.slither.outputs.sarif }}
# Ensure the workflow eventually fails if files did not pass slither checks.
- name: Verify slither-action succeeded
shell: bash
run: |
echo "If this step fails, slither found issues. Check the output of the scan step above."
[[ "${{ steps.slither.outcome }}" == "success" ]]
57 changes: 57 additions & 0 deletions .github/workflows/solhint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# A Github Actions config to run Solhint and report the artifact to DeepSource
name: Solhint Analysis for Solidity

on:
# Note that both `push` and `pull_request` triggers should be present for GitHub to consistently present solhint
# SARIF reports.
push:
branches: [main, master]
pull_request:

jobs:
scan:
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
env:
DEEPSOURCE_DSN: ${{ secrets.DEEPSOURCE_DSN }}
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}

- uses: actions/setup-node@v4
with:
node-version: "16"
cache: npm
cache-dependency-path: "solidity/package-lock.json"

- name: Install solhint
run: |
npm install solhint@^4.1.1
- name: Run solhint
id: solhint
run: |
cd solidity
npx solhint '*.sol' -f sarif > solhint.sarif
# The following line prevents aborting the workflow immediately in case your files fail solhint checks.
# This allows the following upload-sarif action to still upload the results.
continue-on-error: true

- name: Upload SARIF report files to DeepSource
id: upload-sarif
run: |
# Install the CLI
curl https://deepsource.io/cli | sh
# Send the report to DeepSource
./bin/deepsource report --analyzer solhint --analyzer-type community --value-file solidity/solhint.sarif
# Ensure the workflow eventually fails if files did not pass solhint checks.
- name: Verify solhint succeeded
shell: bash
run: |
echo "If this step fails, solhint found issues. Check the output of the scan step above."
[[ "${{ steps.solhint.outcome }}" == "success" ]]
3 changes: 3 additions & 0 deletions solidity/.solhint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "solhint:all"
}
18 changes: 18 additions & 0 deletions solidity/Alice.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

pragma solidity ^0.4.15;

contract Alice {
int public val;

function set(int new_val){
val = new_val;
}

function set_fixed(int new_val){
val = new_val;
}

function(){
val = 1;
}
}
17 changes: 17 additions & 0 deletions solidity/Bob.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

pragma solidity ^0.4.15;

contract Alice {
function set(uint);
function set_fixed(int);
}

contract Bob {
function set(Alice c){
c.set(42);
}

function set_fixed(Alice c){
c.set_fixed(42);
}
}
97 changes: 97 additions & 0 deletions solidity/Lottery.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* This is a distributed lottery that chooses random addresses as lucky addresses. If these
* participate, they get the jackpot: 7 times the price of their bet.
* Of course one address can only win once. The owner regularly reseeds the secret
* seed of the contract (based on which the lucky addresses are chosen), so if you did not win,
* just wait for a reseed and try again!
*
* Jackpot chance: 1 in 8
* Ticket price: Anything larger than (or equal to) 0.1 ETH
* Jackpot size: 7 times the ticket price
*
* HOW TO PARTICIPATE: Just send any amount greater than (or equal to) 0.1 ETH to the contract's address
* Keep in mind that your address can only win once
*
* If the contract doesn't have enough ETH to pay the jackpot, it sends the whole balance.
*/

contract OpenAddressLottery{
struct SeedComponents{
uint component1;
uint component2;
uint component3;
uint component4;
}

address owner; //address of the owner
uint private secretSeed; //seed used to calculate number of an address
uint private lastReseed; //last reseed - used to automatically reseed the contract every 1000 blocks
uint LuckyNumber = 7; //if the number of an address equals 7, it wins

mapping (address => bool) winner; //keeping track of addresses that have already won

function OpenAddressLottery() {
owner = msg.sender;
reseed(SeedComponents((uint)(block.coinbase), block.difficulty, block.gaslimit, block.timestamp)); //generate a quality random seed
}

function participate() payable {
if(msg.value<0.1 ether)
return; //verify ticket price

// make sure he hasn't won already
require(winner[msg.sender] == false);

if(luckyNumberOfAddress(msg.sender) == LuckyNumber){ //check if it equals 7
winner[msg.sender] = true; // every address can only win once

uint win=msg.value*7; //win = 7 times the ticket price

if(win>this.balance) //if the balance isnt sufficient...
win=this.balance; //...send everything we've got
msg.sender.transfer(win);
}

if(block.number-lastReseed>1000) //reseed if needed
reseed(SeedComponents((uint)(block.coinbase), block.difficulty, block.gaslimit, block.timestamp)); //generate a quality random seed
}

function luckyNumberOfAddress(address addr) constant returns(uint n){
// calculate the number of current address - 1 in 8 chance
n = uint(keccak256(uint(addr), secretSeed)[0]) % 8;
}

function reseed(SeedComponents components) internal {
secretSeed = uint256(keccak256(
components.component1,
components.component2,
components.component3,
components.component4
)); //hash the incoming parameters and use the hash to (re)initialize the seed
lastReseed = block.number;
}

function kill() {
require(msg.sender==owner);

selfdestruct(msg.sender);
}

function forceReseed() { //reseed initiated by the owner - for testing purposes
require(msg.sender==owner);

SeedComponents s;
s.component1 = uint(msg.sender);
s.component2 = uint256(block.blockhash(block.number - 1));
s.component3 = block.difficulty*(uint)(block.coinbase);
s.component4 = tx.gasprice * 7;

reseed(s); //reseed
}

function () payable { //if someone sends money without any function call, just assume he wanted to participate
if(msg.value>=0.1 ether && msg.sender!=owner) //owner can't participate, he can only fund the jackpot
participate();
}

}
43 changes: 43 additions & 0 deletions solidity/Reentrancy.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
pragma solidity ^0.4.15;

contract Reentrance {
mapping (address => uint) userBalance;

function getBalance(address u) constant returns(uint){
return userBalance[u];
}

function addToBalance() payable{
userBalance[msg.sender] += msg.value;
}

function withdrawBalance(){
// send userBalance[msg.sender] ethers to msg.sender
// if mgs.sender is a contract, it will call its fallback function
if( ! (msg.sender.call.value(userBalance[msg.sender])() ) ){
throw;
}
userBalance[msg.sender] = 0;
}

function withdrawBalance_fixed(){
// to protect against re-entrancy, the state variable
// has to be change before the call
uint amount = userBalance[msg.sender];
userBalance[msg.sender] = 0;
if( ! (msg.sender.call.value(amount)() ) ){
throw;
}
}

function withdrawBalance_fixed_2(){
// send() and transfer() are safe against reentrancy
// they do not transfer the remaining gas
// and they give just enough gas to execute few instructions
// in the fallback function (no further call possible)
msg.sender.transfer(userBalance[msg.sender]);
userBalance[msg.sender] = 0;
}

}

Loading

0 comments on commit cab3713

Please sign in to comment.