commit
561ae7002c
@ -0,0 +1,866 @@ |
|||||||
|
var test = require('tape') |
||||||
|
var remixLib = require('remix-lib') |
||||||
|
|
||||||
|
var StatRunner = require('../../src/solidity-analyzer') |
||||||
|
var compilerInput = remixLib.helpers.compiler.compilerInput |
||||||
|
|
||||||
|
const niv = require('npm-install-version') |
||||||
|
niv.install('solc@0.5.0') |
||||||
|
var compiler = niv.require('solc@0.5.0') |
||||||
|
|
||||||
|
var fs = require('fs') |
||||||
|
var path = require('path') |
||||||
|
var folder = 'solidity-v0.5' |
||||||
|
|
||||||
|
var testFiles = [ |
||||||
|
'KingOfTheEtherThrone.sol', |
||||||
|
'assembly.sol', |
||||||
|
'ballot.sol', |
||||||
|
'ballot_reentrant.sol', |
||||||
|
'ballot_withoutWarnings.sol', |
||||||
|
'cross_contract.sol', |
||||||
|
'inheritance.sol', |
||||||
|
'modifier1.sol', |
||||||
|
'modifier2.sol', |
||||||
|
'notReentrant.sol', |
||||||
|
'structReentrant.sol', |
||||||
|
'thisLocal.sol', |
||||||
|
'globals.sol', |
||||||
|
'library.sol', |
||||||
|
'transfer.sol', |
||||||
|
'ctor.sol', |
||||||
|
'forgottenReturn.sol', |
||||||
|
'selfdestruct.sol', |
||||||
|
'deleteDynamicArray.sol', |
||||||
|
'deleteFromDynamicArray.sol', |
||||||
|
'blockLevelCompare.sol', |
||||||
|
'intDivisionTruncate.sol', |
||||||
|
'ERC20.sol', |
||||||
|
'stringBytesLength.sol', |
||||||
|
'forLoopIteratesOverDynamicArray.sol' |
||||||
|
] |
||||||
|
|
||||||
|
var testFileAsts = {} |
||||||
|
|
||||||
|
testFiles.forEach((fileName) => { |
||||||
|
var content = fs.readFileSync(path.join(__dirname, 'test-contracts/' + folder, fileName), 'utf8') |
||||||
|
testFileAsts[fileName] = JSON.parse(compiler.compile(compilerInput(content))) |
||||||
|
}) |
||||||
|
|
||||||
|
test('Integration test thisLocal.js', function (t) { |
||||||
|
t.plan(testFiles.length) |
||||||
|
|
||||||
|
var module = require('../../src/solidity-analyzer/modules/thisLocal') |
||||||
|
|
||||||
|
var lengthCheck = { |
||||||
|
'KingOfTheEtherThrone.sol': 0, |
||||||
|
'assembly.sol': 0, |
||||||
|
'ballot.sol': 0, |
||||||
|
'ballot_reentrant.sol': 1, |
||||||
|
'ballot_withoutWarnings.sol': 0, |
||||||
|
'cross_contract.sol': 0, |
||||||
|
'inheritance.sol': 0, |
||||||
|
'modifier1.sol': 0, |
||||||
|
'modifier2.sol': 0, |
||||||
|
'notReentrant.sol': 0, |
||||||
|
'structReentrant.sol': 0, |
||||||
|
'thisLocal.sol': 1, |
||||||
|
'globals.sol': 0, |
||||||
|
'library.sol': 0, |
||||||
|
'transfer.sol': 0, |
||||||
|
'ctor.sol': 0, |
||||||
|
'forgottenReturn.sol': 0, |
||||||
|
'selfdestruct.sol': 0, |
||||||
|
'deleteDynamicArray.sol': 0, |
||||||
|
'deleteFromDynamicArray.sol': 0, |
||||||
|
'blockLevelCompare.sol': 0, |
||||||
|
'intDivisionTruncate.sol': 0, |
||||||
|
'ERC20.sol': 0, |
||||||
|
'stringBytesLength.sol': 0, |
||||||
|
'forLoopIteratesOverDynamicArray.sol': 0 |
||||||
|
} |
||||||
|
|
||||||
|
runModuleOnFiles(module, t, (file, report) => { |
||||||
|
t.equal(report.length, lengthCheck[file], `${file} has right amount of this local warnings`) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
test('Integration test checksEffectsInteraction.js', function (t) { |
||||||
|
t.plan(testFiles.length) |
||||||
|
|
||||||
|
var module = require('../../src/solidity-analyzer/modules/checksEffectsInteraction') |
||||||
|
|
||||||
|
var lengthCheck = { |
||||||
|
'KingOfTheEtherThrone.sol': 1, |
||||||
|
'assembly.sol': 1, |
||||||
|
'ballot.sol': 0, |
||||||
|
'ballot_reentrant.sol': 1, |
||||||
|
'ballot_withoutWarnings.sol': 0, |
||||||
|
'cross_contract.sol': 0, |
||||||
|
'inheritance.sol': 1, |
||||||
|
'modifier1.sol': 0, |
||||||
|
'modifier2.sol': 0, |
||||||
|
'notReentrant.sol': 0, |
||||||
|
'structReentrant.sol': 1, |
||||||
|
'thisLocal.sol': 0, |
||||||
|
'globals.sol': 1, |
||||||
|
'library.sol': 1, |
||||||
|
'transfer.sol': 1, |
||||||
|
'ctor.sol': 0, |
||||||
|
'forgottenReturn.sol': 0, |
||||||
|
'selfdestruct.sol': 0, |
||||||
|
'deleteDynamicArray.sol': 0, |
||||||
|
'deleteFromDynamicArray.sol': 0, |
||||||
|
'blockLevelCompare.sol': 0, |
||||||
|
'intDivisionTruncate.sol': 0, |
||||||
|
'ERC20.sol': 0, |
||||||
|
'stringBytesLength.sol': 0, |
||||||
|
'forLoopIteratesOverDynamicArray.sol': 0 |
||||||
|
} |
||||||
|
|
||||||
|
runModuleOnFiles(module, t, (file, report) => { |
||||||
|
t.equal(report.length, lengthCheck[file], `${file} has right amount of checks-effects-interaction warnings`) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
test('Integration test constantFunctions.js', function (t) { |
||||||
|
t.plan(testFiles.length) |
||||||
|
|
||||||
|
var module = require('../../src/solidity-analyzer/modules/constantFunctions') |
||||||
|
|
||||||
|
var lengthCheck = { |
||||||
|
'KingOfTheEtherThrone.sol': 0, |
||||||
|
'assembly.sol': 0, |
||||||
|
'ballot.sol': 0, |
||||||
|
'ballot_reentrant.sol': 0, |
||||||
|
'ballot_withoutWarnings.sol': 0, |
||||||
|
'cross_contract.sol': 0, |
||||||
|
'inheritance.sol': 0, |
||||||
|
'modifier1.sol': 1, |
||||||
|
'modifier2.sol': 0, |
||||||
|
'notReentrant.sol': 0, |
||||||
|
'structReentrant.sol': 1, |
||||||
|
'thisLocal.sol': 1, |
||||||
|
'globals.sol': 0, |
||||||
|
'library.sol': 3, |
||||||
|
'transfer.sol': 0, |
||||||
|
'ctor.sol': 0, |
||||||
|
'forgottenReturn.sol': 0, |
||||||
|
'selfdestruct.sol': 0, |
||||||
|
'deleteDynamicArray.sol': 0, |
||||||
|
'deleteFromDynamicArray.sol': 0, |
||||||
|
'blockLevelCompare.sol': 0, |
||||||
|
'intDivisionTruncate.sol': 0, |
||||||
|
'ERC20.sol': 0, |
||||||
|
'stringBytesLength.sol': 0, |
||||||
|
'forLoopIteratesOverDynamicArray.sol': 0 |
||||||
|
} |
||||||
|
|
||||||
|
runModuleOnFiles(module, t, (file, report) => { |
||||||
|
t.equal(report.length, lengthCheck[file], `${file} has right amount of constant warnings`) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
test('Integration test inlineAssembly.js', function (t) { |
||||||
|
t.plan(testFiles.length) |
||||||
|
|
||||||
|
var module = require('../../src/solidity-analyzer/modules/inlineAssembly') |
||||||
|
|
||||||
|
var lengthCheck = { |
||||||
|
'KingOfTheEtherThrone.sol': 0, |
||||||
|
'assembly.sol': 2, |
||||||
|
'ballot.sol': 0, |
||||||
|
'ballot_reentrant.sol': 0, |
||||||
|
'ballot_withoutWarnings.sol': 0, |
||||||
|
'cross_contract.sol': 0, |
||||||
|
'inheritance.sol': 0, |
||||||
|
'modifier1.sol': 0, |
||||||
|
'modifier2.sol': 0, |
||||||
|
'notReentrant.sol': 0, |
||||||
|
'structReentrant.sol': 0, |
||||||
|
'thisLocal.sol': 0, |
||||||
|
'globals.sol': 0, |
||||||
|
'library.sol': 0, |
||||||
|
'transfer.sol': 0, |
||||||
|
'ctor.sol': 0, |
||||||
|
'forgottenReturn.sol': 0, |
||||||
|
'selfdestruct.sol': 0, |
||||||
|
'deleteDynamicArray.sol': 0, |
||||||
|
'deleteFromDynamicArray.sol': 0, |
||||||
|
'blockLevelCompare.sol': 0, |
||||||
|
'intDivisionTruncate.sol': 0, |
||||||
|
'ERC20.sol': 0, |
||||||
|
'stringBytesLength.sol': 0, |
||||||
|
'forLoopIteratesOverDynamicArray.sol': 0 |
||||||
|
} |
||||||
|
|
||||||
|
runModuleOnFiles(module, t, (file, report) => { |
||||||
|
t.equal(report.length, lengthCheck[file], `${file} has right amount of inline assembly warnings`) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
test('Integration test txOrigin.js', function (t) { |
||||||
|
t.plan(testFiles.length) |
||||||
|
|
||||||
|
var module = require('../../src/solidity-analyzer/modules/txOrigin') |
||||||
|
|
||||||
|
var lengthCheck = { |
||||||
|
'KingOfTheEtherThrone.sol': 0, |
||||||
|
'assembly.sol': 1, |
||||||
|
'ballot.sol': 0, |
||||||
|
'ballot_reentrant.sol': 0, |
||||||
|
'ballot_withoutWarnings.sol': 0, |
||||||
|
'cross_contract.sol': 0, |
||||||
|
'inheritance.sol': 0, |
||||||
|
'modifier1.sol': 0, |
||||||
|
'modifier2.sol': 0, |
||||||
|
'notReentrant.sol': 0, |
||||||
|
'structReentrant.sol': 0, |
||||||
|
'thisLocal.sol': 0, |
||||||
|
'globals.sol': 1, |
||||||
|
'library.sol': 0, |
||||||
|
'transfer.sol': 0, |
||||||
|
'ctor.sol': 0, |
||||||
|
'forgottenReturn.sol': 0, |
||||||
|
'selfdestruct.sol': 0, |
||||||
|
'deleteDynamicArray.sol': 0, |
||||||
|
'deleteFromDynamicArray.sol': 0, |
||||||
|
'blockLevelCompare.sol': 0, |
||||||
|
'intDivisionTruncate.sol': 0, |
||||||
|
'ERC20.sol': 0, |
||||||
|
'stringBytesLength.sol': 0, |
||||||
|
'forLoopIteratesOverDynamicArray.sol': 0 |
||||||
|
} |
||||||
|
|
||||||
|
runModuleOnFiles(module, t, (file, report) => { |
||||||
|
t.equal(report.length, lengthCheck[file], `${file} has right amount of tx.origin warnings`) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
test('Integration test gasCosts.js', function (t) { |
||||||
|
t.plan(testFiles.length) |
||||||
|
|
||||||
|
var module = require('../../src/solidity-analyzer/modules/gasCosts') |
||||||
|
|
||||||
|
var lengthCheck = { |
||||||
|
'KingOfTheEtherThrone.sol': 2, |
||||||
|
'assembly.sol': 2, |
||||||
|
'ballot.sol': 3, |
||||||
|
'ballot_reentrant.sol': 2, |
||||||
|
'ballot_withoutWarnings.sol': 0, |
||||||
|
'cross_contract.sol': 1, |
||||||
|
'inheritance.sol': 1, |
||||||
|
'modifier1.sol': 0, |
||||||
|
'modifier2.sol': 1, |
||||||
|
'notReentrant.sol': 1, |
||||||
|
'structReentrant.sol': 1, |
||||||
|
'thisLocal.sol': 1, |
||||||
|
'globals.sol': 1, |
||||||
|
'library.sol': 1, |
||||||
|
'transfer.sol': 1, |
||||||
|
'ctor.sol': 0, |
||||||
|
'forgottenReturn.sol': 3, |
||||||
|
'selfdestruct.sol': 0, |
||||||
|
'deleteDynamicArray.sol': 2, |
||||||
|
'deleteFromDynamicArray.sol': 1, |
||||||
|
'blockLevelCompare.sol': 1, |
||||||
|
'intDivisionTruncate.sol': 1, |
||||||
|
'ERC20.sol': 2, |
||||||
|
'stringBytesLength.sol': 1, |
||||||
|
'forLoopIteratesOverDynamicArray.sol': 1 |
||||||
|
} |
||||||
|
|
||||||
|
runModuleOnFiles(module, t, (file, report) => { |
||||||
|
t.equal(report.length, lengthCheck[file], `${file} has right amount of gasCost warnings`) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
test('Integration test similarVariableNames.js', function (t) { |
||||||
|
t.plan(testFiles.length) |
||||||
|
|
||||||
|
var module = require('../../src/solidity-analyzer/modules/similarVariableNames') |
||||||
|
|
||||||
|
var lengthCheck = { |
||||||
|
'KingOfTheEtherThrone.sol': 0, |
||||||
|
'assembly.sol': 0, |
||||||
|
'ballot.sol': 2, |
||||||
|
'ballot_reentrant.sol': 11, |
||||||
|
'ballot_withoutWarnings.sol': 0, |
||||||
|
'cross_contract.sol': 0, |
||||||
|
'inheritance.sol': 0, |
||||||
|
'modifier1.sol': 0, |
||||||
|
'modifier2.sol': 0, |
||||||
|
'notReentrant.sol': 1, |
||||||
|
'structReentrant.sol': 0, |
||||||
|
'thisLocal.sol': 0, |
||||||
|
'globals.sol': 0, |
||||||
|
'library.sol': 0, |
||||||
|
'transfer.sol': 0, |
||||||
|
'ctor.sol': 1, |
||||||
|
'forgottenReturn.sol': 0, |
||||||
|
'selfdestruct.sol': 0, |
||||||
|
'deleteDynamicArray.sol': 1, |
||||||
|
'deleteFromDynamicArray.sol': 0, |
||||||
|
'blockLevelCompare.sol': 0, |
||||||
|
'intDivisionTruncate.sol': 0, |
||||||
|
'ERC20.sol': 0, |
||||||
|
'stringBytesLength.sol': 0, |
||||||
|
'forLoopIteratesOverDynamicArray.sol': 0 |
||||||
|
} |
||||||
|
|
||||||
|
runModuleOnFiles(module, t, (file, report) => { |
||||||
|
t.equal(report.length, lengthCheck[file], `${file} has right amount of similarVariableNames warnings`) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
test('Integration test inlineAssembly.js', function (t) { |
||||||
|
t.plan(testFiles.length) |
||||||
|
|
||||||
|
var module = require('../../src/solidity-analyzer/modules/inlineAssembly') |
||||||
|
|
||||||
|
var lengthCheck = { |
||||||
|
'KingOfTheEtherThrone.sol': 0, |
||||||
|
'assembly.sol': 2, |
||||||
|
'ballot.sol': 0, |
||||||
|
'ballot_reentrant.sol': 0, |
||||||
|
'ballot_withoutWarnings.sol': 0, |
||||||
|
'cross_contract.sol': 0, |
||||||
|
'inheritance.sol': 0, |
||||||
|
'modifier1.sol': 0, |
||||||
|
'modifier2.sol': 0, |
||||||
|
'notReentrant.sol': 0, |
||||||
|
'structReentrant.sol': 0, |
||||||
|
'thisLocal.sol': 0, |
||||||
|
'globals.sol': 0, |
||||||
|
'library.sol': 0, |
||||||
|
'transfer.sol': 0, |
||||||
|
'ctor.sol': 0, |
||||||
|
'forgottenReturn.sol': 0, |
||||||
|
'selfdestruct.sol': 0, |
||||||
|
'deleteDynamicArray.sol': 0, |
||||||
|
'deleteFromDynamicArray.sol': 0, |
||||||
|
'blockLevelCompare.sol': 0, |
||||||
|
'intDivisionTruncate.sol': 0, |
||||||
|
'ERC20.sol': 0, |
||||||
|
'stringBytesLength.sol': 0, |
||||||
|
'forLoopIteratesOverDynamicArray.sol': 0 |
||||||
|
} |
||||||
|
|
||||||
|
runModuleOnFiles(module, t, (file, report) => { |
||||||
|
t.equal(report.length, lengthCheck[file], `${file} has right amount of inlineAssembly warnings`) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
test('Integration test blockTimestamp.js', function (t) { |
||||||
|
t.plan(testFiles.length) |
||||||
|
|
||||||
|
var module = require('../../src/solidity-analyzer/modules/blockTimestamp') |
||||||
|
|
||||||
|
var lengthCheck = { |
||||||
|
'KingOfTheEtherThrone.sol': 1, |
||||||
|
'assembly.sol': 0, |
||||||
|
'ballot.sol': 0, |
||||||
|
'ballot_reentrant.sol': 3, |
||||||
|
'ballot_withoutWarnings.sol': 0, |
||||||
|
'cross_contract.sol': 0, |
||||||
|
'inheritance.sol': 0, |
||||||
|
'modifier1.sol': 0, |
||||||
|
'modifier2.sol': 0, |
||||||
|
'notReentrant.sol': 0, |
||||||
|
'structReentrant.sol': 0, |
||||||
|
'thisLocal.sol': 0, |
||||||
|
'globals.sol': 2, |
||||||
|
'library.sol': 0, |
||||||
|
'transfer.sol': 0, |
||||||
|
'ctor.sol': 0, |
||||||
|
'forgottenReturn.sol': 0, |
||||||
|
'selfdestruct.sol': 0, |
||||||
|
'deleteDynamicArray.sol': 0, |
||||||
|
'deleteFromDynamicArray.sol': 0, |
||||||
|
'blockLevelCompare.sol': 0, |
||||||
|
'intDivisionTruncate.sol': 0, |
||||||
|
'ERC20.sol': 0, |
||||||
|
'stringBytesLength.sol': 0, |
||||||
|
'forLoopIteratesOverDynamicArray.sol': 0 |
||||||
|
} |
||||||
|
|
||||||
|
runModuleOnFiles(module, t, (file, report) => { |
||||||
|
t.equal(report.length, lengthCheck[file], `${file} has right amount of blockTimestamp warnings`) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
test('Integration test lowLevelCalls.js', function (t) { |
||||||
|
t.plan(testFiles.length) |
||||||
|
|
||||||
|
var module = require('../../src/solidity-analyzer/modules/lowLevelCalls') |
||||||
|
|
||||||
|
var lengthCheck = { |
||||||
|
'KingOfTheEtherThrone.sol': 1, |
||||||
|
'assembly.sol': 1, |
||||||
|
'ballot.sol': 0, |
||||||
|
'ballot_reentrant.sol': 7, |
||||||
|
'ballot_withoutWarnings.sol': 0, |
||||||
|
'cross_contract.sol': 1, |
||||||
|
'inheritance.sol': 1, |
||||||
|
'modifier1.sol': 0, |
||||||
|
'modifier2.sol': 0, |
||||||
|
'notReentrant.sol': 1, |
||||||
|
'structReentrant.sol': 1, |
||||||
|
'thisLocal.sol': 2, |
||||||
|
'globals.sol': 1, |
||||||
|
'library.sol': 1, |
||||||
|
'transfer.sol': 0, |
||||||
|
'ctor.sol': 0, |
||||||
|
'forgottenReturn.sol': 0, |
||||||
|
'selfdestruct.sol': 0, |
||||||
|
'deleteDynamicArray.sol': 0, |
||||||
|
'deleteFromDynamicArray.sol': 0, |
||||||
|
'blockLevelCompare.sol': 0, |
||||||
|
'intDivisionTruncate.sol': 0, |
||||||
|
'ERC20.sol': 0, |
||||||
|
'stringBytesLength.sol': 0, |
||||||
|
'forLoopIteratesOverDynamicArray.sol': 0 |
||||||
|
} |
||||||
|
|
||||||
|
runModuleOnFiles(module, t, (file, report) => { |
||||||
|
t.equal(report.length, lengthCheck[file], `${file} has right amount of lowLevelCalls warnings`) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
test('Integration test blockBlockhash.js', function (t) { |
||||||
|
t.plan(testFiles.length) |
||||||
|
|
||||||
|
var module = require('../../src/solidity-analyzer/modules/blockBlockhash') |
||||||
|
|
||||||
|
var lengthCheck = { |
||||||
|
'KingOfTheEtherThrone.sol': 0, |
||||||
|
'assembly.sol': 0, |
||||||
|
'ballot.sol': 0, |
||||||
|
'ballot_reentrant.sol': 0, |
||||||
|
'ballot_withoutWarnings.sol': 0, |
||||||
|
'cross_contract.sol': 0, |
||||||
|
'inheritance.sol': 0, |
||||||
|
'modifier1.sol': 0, |
||||||
|
'modifier2.sol': 0, |
||||||
|
'notReentrant.sol': 0, |
||||||
|
'structReentrant.sol': 0, |
||||||
|
'thisLocal.sol': 0, |
||||||
|
'globals.sol': 0, // was 1 !! @TODO
|
||||||
|
'library.sol': 0, |
||||||
|
'transfer.sol': 0, |
||||||
|
'ctor.sol': 0, |
||||||
|
'forgottenReturn.sol': 0, |
||||||
|
'selfdestruct.sol': 0, |
||||||
|
'deleteDynamicArray.sol': 0, |
||||||
|
'deleteFromDynamicArray.sol': 0, |
||||||
|
'blockLevelCompare.sol': 0, |
||||||
|
'intDivisionTruncate.sol': 0, |
||||||
|
'ERC20.sol': 0, |
||||||
|
'stringBytesLength.sol': 0, |
||||||
|
'forLoopIteratesOverDynamicArray.sol': 0 |
||||||
|
} |
||||||
|
|
||||||
|
runModuleOnFiles(module, t, (file, report) => { |
||||||
|
t.equal(report.length, lengthCheck[file], `${file} has right amount of blockBlockhash warnings`) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
/* |
||||||
|
|
||||||
|
! No return gives compilation error with solidity 0.5.0 |
||||||
|
|
||||||
|
test('Integration test noReturn.js', function (t) { |
||||||
|
t.plan(testFiles.length) |
||||||
|
|
||||||
|
var module = require('../../src/solidity-analyzer/modules/noReturn') |
||||||
|
|
||||||
|
var lengthCheck = { |
||||||
|
'KingOfTheEtherThrone.sol': 0, |
||||||
|
'assembly.sol': 1, |
||||||
|
'ballot.sol': 0, |
||||||
|
'ballot_reentrant.sol': 0, |
||||||
|
'ballot_withoutWarnings.sol': 0, |
||||||
|
'cross_contract.sol': 0, |
||||||
|
'inheritance.sol': 0, |
||||||
|
'modifier1.sol': 1, |
||||||
|
'modifier2.sol': 0, |
||||||
|
'notReentrant.sol': 0, |
||||||
|
'structReentrant.sol': 0, |
||||||
|
'thisLocal.sol': 1, |
||||||
|
'globals.sol': 0, |
||||||
|
'library.sol': 0, |
||||||
|
'transfer.sol': 0, |
||||||
|
'ctor.sol': 0, |
||||||
|
'forgottenReturn.sol': 1, |
||||||
|
'selfdestruct.sol': 0, |
||||||
|
'deleteDynamicArray.sol': 0, |
||||||
|
'deleteFromDynamicArray.sol': 0, |
||||||
|
'blockLevelCompare.sol': 0, |
||||||
|
'intDivisionTruncate.sol': 0, |
||||||
|
'ERC20.sol': 0, |
||||||
|
'stringBytesLength.sol': 0, |
||||||
|
'forLoopIteratesOverDynamicArray.sol': 0 |
||||||
|
} |
||||||
|
|
||||||
|
runModuleOnFiles(module, t, (file, report) => { |
||||||
|
t.equal(report.length, lengthCheck[file], `${file} has right amount of noReturn warnings`) |
||||||
|
}) |
||||||
|
}) |
||||||
|
*/ |
||||||
|
|
||||||
|
test('Integration test selfdestruct.js', function (t) { |
||||||
|
t.plan(testFiles.length) |
||||||
|
|
||||||
|
var module = require('../../src/solidity-analyzer/modules/selfdestruct') |
||||||
|
|
||||||
|
var lengthCheck = { |
||||||
|
'KingOfTheEtherThrone.sol': 0, |
||||||
|
'assembly.sol': 0, |
||||||
|
'ballot.sol': 0, |
||||||
|
'ballot_reentrant.sol': 0, |
||||||
|
'ballot_withoutWarnings.sol': 0, |
||||||
|
'cross_contract.sol': 0, |
||||||
|
'inheritance.sol': 0, |
||||||
|
'modifier1.sol': 0, |
||||||
|
'modifier2.sol': 0, |
||||||
|
'notReentrant.sol': 0, |
||||||
|
'structReentrant.sol': 0, |
||||||
|
'thisLocal.sol': 0, |
||||||
|
'globals.sol': 2, |
||||||
|
'library.sol': 0, |
||||||
|
'transfer.sol': 0, |
||||||
|
'ctor.sol': 0, |
||||||
|
'forgottenReturn.sol': 0, |
||||||
|
'selfdestruct.sol': 3, |
||||||
|
'deleteDynamicArray.sol': 0, |
||||||
|
'deleteFromDynamicArray.sol': 0, |
||||||
|
'blockLevelCompare.sol': 0, |
||||||
|
'ERC20.sol': 0, |
||||||
|
'intDivisionTruncate.sol': 5, |
||||||
|
'stringBytesLength.sol': 0, |
||||||
|
'forLoopIteratesOverDynamicArray.sol': 0 |
||||||
|
} |
||||||
|
|
||||||
|
runModuleOnFiles(module, t, (file, report) => { |
||||||
|
t.equal(report.length, lengthCheck[file], `${file} has right amount of selfdestruct warnings`) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
test('Integration test guardConditions.js', function (t) { |
||||||
|
t.plan(testFiles.length) |
||||||
|
|
||||||
|
var module = require('../../src/solidity-analyzer/modules/guardConditions') |
||||||
|
|
||||||
|
var lengthCheck = { |
||||||
|
'KingOfTheEtherThrone.sol': 0, |
||||||
|
'assembly.sol': 1, |
||||||
|
'ballot.sol': 0, |
||||||
|
'ballot_reentrant.sol': 0, |
||||||
|
'ballot_withoutWarnings.sol': 0, |
||||||
|
'cross_contract.sol': 0, |
||||||
|
'inheritance.sol': 0, |
||||||
|
'modifier1.sol': 0, |
||||||
|
'modifier2.sol': 0, |
||||||
|
'notReentrant.sol': 0, |
||||||
|
'structReentrant.sol': 0, |
||||||
|
'thisLocal.sol': 0, |
||||||
|
'globals.sol': 1, |
||||||
|
'library.sol': 0, |
||||||
|
'transfer.sol': 0, |
||||||
|
'ctor.sol': 0, |
||||||
|
'forgottenReturn.sol': 0, |
||||||
|
'selfdestruct.sol': 0, |
||||||
|
'deleteDynamicArray.sol': 1, |
||||||
|
'deleteFromDynamicArray.sol': 0, |
||||||
|
'blockLevelCompare.sol': 0, |
||||||
|
'intDivisionTruncate.sol': 1, |
||||||
|
'ERC20.sol': 0, |
||||||
|
'stringBytesLength.sol': 0, |
||||||
|
'forLoopIteratesOverDynamicArray.sol': 0 |
||||||
|
} |
||||||
|
|
||||||
|
runModuleOnFiles(module, t, (file, report) => { |
||||||
|
t.equal(report.length, lengthCheck[file], `${file} has right amount of guardCondition warnings`) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
test('Integration test deleteDynamicArrays.js', function (t) { |
||||||
|
t.plan(testFiles.length) |
||||||
|
|
||||||
|
var module = require('../../src/solidity-analyzer/modules/deleteDynamicArrays') |
||||||
|
|
||||||
|
var lengthCheck = { |
||||||
|
'KingOfTheEtherThrone.sol': 0, |
||||||
|
'assembly.sol': 0, |
||||||
|
'ballot.sol': 0, |
||||||
|
'ballot_reentrant.sol': 0, |
||||||
|
'ballot_withoutWarnings.sol': 0, |
||||||
|
'cross_contract.sol': 0, |
||||||
|
'inheritance.sol': 0, |
||||||
|
'modifier1.sol': 0, |
||||||
|
'modifier2.sol': 0, |
||||||
|
'notReentrant.sol': 0, |
||||||
|
'structReentrant.sol': 0, |
||||||
|
'thisLocal.sol': 0, |
||||||
|
'globals.sol': 0, |
||||||
|
'library.sol': 0, |
||||||
|
'transfer.sol': 0, |
||||||
|
'ctor.sol': 0, |
||||||
|
'forgottenReturn.sol': 0, |
||||||
|
'selfdestruct.sol': 0, |
||||||
|
'deleteDynamicArray.sol': 2, |
||||||
|
'deleteFromDynamicArray.sol': 0, |
||||||
|
'blockLevelCompare.sol': 0, |
||||||
|
'intDivisionTruncate.sol': 0, |
||||||
|
'ERC20.sol': 0, |
||||||
|
'stringBytesLength.sol': 0, |
||||||
|
'forLoopIteratesOverDynamicArray.sol': 0 |
||||||
|
} |
||||||
|
|
||||||
|
runModuleOnFiles(module, t, (file, report) => { |
||||||
|
t.equal(report.length, lengthCheck[file], `${file} has right amount of deleteDynamicArrays warnings`) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
test('Integration test deleteFromDynamicArray.js', function (t) { |
||||||
|
t.plan(testFiles.length) |
||||||
|
|
||||||
|
var module = require('../../src/solidity-analyzer/modules/deleteFromDynamicArray') |
||||||
|
|
||||||
|
var lengthCheck = { |
||||||
|
'KingOfTheEtherThrone.sol': 0, |
||||||
|
'assembly.sol': 0, |
||||||
|
'ballot.sol': 0, |
||||||
|
'ballot_reentrant.sol': 0, |
||||||
|
'ballot_withoutWarnings.sol': 0, |
||||||
|
'cross_contract.sol': 0, |
||||||
|
'inheritance.sol': 0, |
||||||
|
'modifier1.sol': 0, |
||||||
|
'modifier2.sol': 0, |
||||||
|
'notReentrant.sol': 0, |
||||||
|
'structReentrant.sol': 0, |
||||||
|
'thisLocal.sol': 0, |
||||||
|
'globals.sol': 0, |
||||||
|
'library.sol': 0, |
||||||
|
'transfer.sol': 0, |
||||||
|
'ctor.sol': 0, |
||||||
|
'forgottenReturn.sol': 0, |
||||||
|
'selfdestruct.sol': 0, |
||||||
|
'deleteDynamicArray.sol': 0, |
||||||
|
'deleteFromDynamicArray.sol': 1, |
||||||
|
'blockLevelCompare.sol': 0, |
||||||
|
'intDivisionTruncate.sol': 0, |
||||||
|
'ERC20.sol': 0, |
||||||
|
'stringBytesLength.sol': 0, |
||||||
|
'forLoopIteratesOverDynamicArray.sol': 0 |
||||||
|
} |
||||||
|
|
||||||
|
runModuleOnFiles(module, t, (file, report) => { |
||||||
|
t.equal(report.length, lengthCheck[file], `${file} has right amount of deleteFromDynamicArray warnings`) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
test('Integration test assignAndCompare.js', function (t) { |
||||||
|
t.plan(testFiles.length) |
||||||
|
|
||||||
|
var module = require('../../src/solidity-analyzer/modules/assignAndCompare') |
||||||
|
|
||||||
|
var lengthCheck = { |
||||||
|
'KingOfTheEtherThrone.sol': 0, |
||||||
|
'assembly.sol': 0, |
||||||
|
'ballot.sol': 0, |
||||||
|
'ballot_reentrant.sol': 0, |
||||||
|
'ballot_withoutWarnings.sol': 0, |
||||||
|
'cross_contract.sol': 0, |
||||||
|
'inheritance.sol': 0, |
||||||
|
'modifier1.sol': 0, |
||||||
|
'modifier2.sol': 0, |
||||||
|
'notReentrant.sol': 0, |
||||||
|
'structReentrant.sol': 0, |
||||||
|
'thisLocal.sol': 0, |
||||||
|
'globals.sol': 0, |
||||||
|
'library.sol': 0, |
||||||
|
'transfer.sol': 0, |
||||||
|
'ctor.sol': 0, |
||||||
|
'forgottenReturn.sol': 0, |
||||||
|
'selfdestruct.sol': 0, |
||||||
|
'deleteDynamicArray.sol': 0, |
||||||
|
'deleteFromDynamicArray.sol': 0, |
||||||
|
'blockLevelCompare.sol': 8, |
||||||
|
'intDivisionTruncate.sol': 0, |
||||||
|
'ERC20.sol': 0, |
||||||
|
'stringBytesLength.sol': 0, |
||||||
|
'forLoopIteratesOverDynamicArray.sol': 0 |
||||||
|
} |
||||||
|
|
||||||
|
runModuleOnFiles(module, t, (file, report) => { |
||||||
|
t.equal(report.length, lengthCheck[file], `${file} has right amount of assignAndCompare warnings`) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
test('Integration test intDivisionTruncate.js', function (t) { |
||||||
|
t.plan(testFiles.length) |
||||||
|
|
||||||
|
var module = require('../../src/solidity-analyzer/modules/intDivisionTruncate') |
||||||
|
|
||||||
|
var lengthCheck = { |
||||||
|
'KingOfTheEtherThrone.sol': 0, |
||||||
|
'assembly.sol': 0, |
||||||
|
'ballot.sol': 0, |
||||||
|
'ballot_reentrant.sol': 0, |
||||||
|
'ballot_withoutWarnings.sol': 0, |
||||||
|
'cross_contract.sol': 0, |
||||||
|
'inheritance.sol': 0, |
||||||
|
'modifier1.sol': 0, |
||||||
|
'modifier2.sol': 0, |
||||||
|
'notReentrant.sol': 0, |
||||||
|
'structReentrant.sol': 0, |
||||||
|
'thisLocal.sol': 0, |
||||||
|
'globals.sol': 0, |
||||||
|
'library.sol': 0, |
||||||
|
'transfer.sol': 0, |
||||||
|
'ctor.sol': 0, |
||||||
|
'forgottenReturn.sol': 0, |
||||||
|
'selfdestruct.sol': 0, |
||||||
|
'deleteDynamicArray.sol': 0, |
||||||
|
'deleteFromDynamicArray.sol': 0, |
||||||
|
'blockLevelCompare.sol': 0, |
||||||
|
'intDivisionTruncate.sol': 2, |
||||||
|
'ERC20.sol': 0, |
||||||
|
'stringBytesLength.sol': 0, |
||||||
|
'forLoopIteratesOverDynamicArray.sol': 0 |
||||||
|
} |
||||||
|
|
||||||
|
runModuleOnFiles(module, t, (file, report) => { |
||||||
|
t.equal(report.length, lengthCheck[file], `${file} has right amount of intDivisionTruncate warnings`) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
test('Integration test erc20Decimal.js', function (t) { |
||||||
|
t.plan(testFiles.length) |
||||||
|
|
||||||
|
var module = require('../../src/solidity-analyzer/modules/erc20Decimals') |
||||||
|
|
||||||
|
var lengthCheck = { |
||||||
|
'KingOfTheEtherThrone.sol': 0, |
||||||
|
'assembly.sol': 0, |
||||||
|
'ballot.sol': 0, |
||||||
|
'ballot_reentrant.sol': 0, |
||||||
|
'ballot_withoutWarnings.sol': 0, |
||||||
|
'cross_contract.sol': 0, |
||||||
|
'inheritance.sol': 0, |
||||||
|
'modifier1.sol': 0, |
||||||
|
'modifier2.sol': 0, |
||||||
|
'notReentrant.sol': 0, |
||||||
|
'structReentrant.sol': 0, |
||||||
|
'thisLocal.sol': 0, |
||||||
|
'globals.sol': 0, |
||||||
|
'library.sol': 0, |
||||||
|
'transfer.sol': 0, |
||||||
|
'ctor.sol': 0, |
||||||
|
'forgottenReturn.sol': 0, |
||||||
|
'selfdestruct.sol': 0, |
||||||
|
'deleteDynamicArray.sol': 0, |
||||||
|
'deleteFromDynamicArray.sol': 0, |
||||||
|
'blockLevelCompare.sol': 0, |
||||||
|
'intDivisionTruncate.sol': 0, |
||||||
|
'ERC20.sol': 1, |
||||||
|
'stringBytesLength.sol': 0, |
||||||
|
'forLoopIteratesOverDynamicArray.sol': 0 |
||||||
|
} |
||||||
|
|
||||||
|
runModuleOnFiles(module, t, (file, report) => { |
||||||
|
t.equal(report.length, lengthCheck[file], `${file} has right amount of erc20Decimals warnings`) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
test('Integration test stringBytesLength.js', function (t) { |
||||||
|
t.plan(testFiles.length) |
||||||
|
|
||||||
|
var module = require('../../src/solidity-analyzer/modules/stringBytesLength') |
||||||
|
|
||||||
|
var lengthCheck = { |
||||||
|
'KingOfTheEtherThrone.sol': 0, |
||||||
|
'assembly.sol': 0, |
||||||
|
'ballot.sol': 0, |
||||||
|
'ballot_reentrant.sol': 0, |
||||||
|
'ballot_withoutWarnings.sol': 0, |
||||||
|
'cross_contract.sol': 0, |
||||||
|
'inheritance.sol': 0, |
||||||
|
'modifier1.sol': 0, |
||||||
|
'modifier2.sol': 0, |
||||||
|
'notReentrant.sol': 0, |
||||||
|
'structReentrant.sol': 0, |
||||||
|
'thisLocal.sol': 0, |
||||||
|
'globals.sol': 0, |
||||||
|
'library.sol': 0, |
||||||
|
'transfer.sol': 0, |
||||||
|
'ctor.sol': 0, |
||||||
|
'forgottenReturn.sol': 0, |
||||||
|
'selfdestruct.sol': 0, |
||||||
|
'deleteDynamicArray.sol': 0, |
||||||
|
'deleteFromDynamicArray.sol': 0, |
||||||
|
'blockLevelCompare.sol': 0, |
||||||
|
'intDivisionTruncate.sol': 0, |
||||||
|
'ERC20.sol': 0, |
||||||
|
'stringBytesLength.sol': 1, |
||||||
|
'forLoopIteratesOverDynamicArray.sol': 0 |
||||||
|
} |
||||||
|
|
||||||
|
runModuleOnFiles(module, t, (file, report) => { |
||||||
|
t.equal(report.length, lengthCheck[file], `${file} has right amount of stringBytesLength warnings`) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
test('Integration test forLoopIteratesOverDynamicArray.js', function (t) { |
||||||
|
t.plan(testFiles.length) |
||||||
|
|
||||||
|
var module = require('../../src/solidity-analyzer/modules/forLoopIteratesOverDynamicArray') |
||||||
|
|
||||||
|
var lengthCheck = { |
||||||
|
'KingOfTheEtherThrone.sol': 0, |
||||||
|
'assembly.sol': 0, |
||||||
|
'ballot.sol': 2, |
||||||
|
'ballot_reentrant.sol': 1, |
||||||
|
'ballot_withoutWarnings.sol': 0, |
||||||
|
'cross_contract.sol': 0, |
||||||
|
'inheritance.sol': 0, |
||||||
|
'modifier1.sol': 0, |
||||||
|
'modifier2.sol': 0, |
||||||
|
'notReentrant.sol': 0, |
||||||
|
'structReentrant.sol': 0, |
||||||
|
'thisLocal.sol': 0, |
||||||
|
'globals.sol': 0, |
||||||
|
'library.sol': 0, |
||||||
|
'transfer.sol': 0, |
||||||
|
'ctor.sol': 0, |
||||||
|
'forgottenReturn.sol': 0, |
||||||
|
'selfdestruct.sol': 0, |
||||||
|
'deleteDynamicArray.sol': 0, |
||||||
|
'deleteFromDynamicArray.sol': 0, |
||||||
|
'blockLevelCompare.sol': 0, |
||||||
|
'intDivisionTruncate.sol': 0, |
||||||
|
'ERC20.sol': 0, |
||||||
|
'stringBytesLength.sol': 0, |
||||||
|
'forLoopIteratesOverDynamicArray.sol': 1 |
||||||
|
} |
||||||
|
|
||||||
|
runModuleOnFiles(module, t, (file, report) => { |
||||||
|
t.equal(report.length, lengthCheck[file], `${file} has right amount of forLoopIteratesOverDynamicArray warnings`) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
// #################### Helpers
|
||||||
|
function runModuleOnFiles (module, t, cb) { |
||||||
|
var statRunner = new StatRunner() |
||||||
|
|
||||||
|
testFiles.forEach((fileName) => { |
||||||
|
statRunner.runWithModuleList(testFileAsts[fileName], [{ name: module.name, mod: new module.Module() }], (reports) => { |
||||||
|
let report = reports[0].report |
||||||
|
if (report.some((x) => x['warning'].includes('INTERNAL ERROR'))) { |
||||||
|
t.comment('Error while executing Module: ' + JSON.stringify(report)) |
||||||
|
} |
||||||
|
cb(fileName, report) |
||||||
|
}) |
||||||
|
}) |
||||||
|
} |
@ -0,0 +1,37 @@ |
|||||||
|
var test = require('tape') |
||||||
|
var remixLib = require('remix-lib') |
||||||
|
|
||||||
|
var StatRunner = require('../../src/solidity-analyzer') |
||||||
|
var compilerInput = remixLib.helpers.compiler.compilerInput |
||||||
|
|
||||||
|
const niv = require('npm-install-version') |
||||||
|
niv.install('solc@0.4.24') |
||||||
|
var compiler = niv.require('solc@0.4.24') |
||||||
|
|
||||||
|
var fs = require('fs') |
||||||
|
var path = require('path') |
||||||
|
var folder = 'solidity-v0.4.24' |
||||||
|
|
||||||
|
function compile (fileName) { |
||||||
|
var content = fs.readFileSync(path.join(__dirname, 'test-contracts/' + folder, fileName), 'utf8') |
||||||
|
return JSON.parse(compiler.compileStandardWrapper(compilerInput(content))) |
||||||
|
} |
||||||
|
|
||||||
|
test('staticAnalysisIssues.functionParameterPassingError', function (t) { |
||||||
|
// https://github.com/ethereum/remix-ide/issues/889#issuecomment-351746474
|
||||||
|
t.plan(2) |
||||||
|
var res = compile('functionParameters.sol') |
||||||
|
|
||||||
|
var module = require('../../src/solidity-analyzer/modules/checksEffectsInteraction') |
||||||
|
|
||||||
|
var statRunner = new StatRunner() |
||||||
|
|
||||||
|
t.doesNotThrow(() => { |
||||||
|
statRunner.runWithModuleList(res, [{ name: module.name, mod: new module.Module() }], (reports) => { |
||||||
|
}) |
||||||
|
}, true, 'Analysis should not throw') |
||||||
|
|
||||||
|
statRunner.runWithModuleList(res, [{ name: module.name, mod: new module.Module() }], (reports) => { |
||||||
|
t.ok(!reports.some((mod) => mod.report.some((rep) => rep.warning.includes('INTERNAL ERROR')), 'Should not have internal errors')) |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,46 @@ |
|||||||
|
|
||||||
|
pragma solidity >=0.4.9 <0.6.0; |
||||||
|
contract EIP20 { |
||||||
|
|
||||||
|
uint public decimals = 12; |
||||||
|
|
||||||
|
// optional |
||||||
|
function name() public pure returns (string memory) { |
||||||
|
return "MYTOKEN"; |
||||||
|
} |
||||||
|
|
||||||
|
// optional |
||||||
|
function symbol() public pure returns (string memory) { |
||||||
|
return "MT"; |
||||||
|
} |
||||||
|
|
||||||
|
// optional |
||||||
|
//function decimals() internal pure returns (uint8) { |
||||||
|
// return 12; |
||||||
|
//} |
||||||
|
|
||||||
|
function totalSupply() public pure returns (uint256) { |
||||||
|
return 12000; |
||||||
|
} |
||||||
|
|
||||||
|
function balanceOf(address _owner) public pure returns (uint256) { |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
function transfer(address _to, uint256 _value) public pure returns (bool success) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
function transferFrom(address _from, address _to, uint256 _value) public pure returns (bool) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
function approve(address _spender, uint256 _value) public pure returns (bool) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
function allowance(address _owner, address _spender) public pure returns (uint256) { |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,23 @@ |
|||||||
|
// return value send |
||||||
|
contract KingOfTheEtherThrone{ |
||||||
|
struct Monarch { |
||||||
|
// address of the king . |
||||||
|
address payable ethAddr ; |
||||||
|
string name ; |
||||||
|
// how much he pays to previous king |
||||||
|
uint claimPrice ; |
||||||
|
uint coronationTimestamp; |
||||||
|
} |
||||||
|
Monarch public currentMonarch ; |
||||||
|
|
||||||
|
function claimThrone ( string memory name ) public { |
||||||
|
address wizardAddress; |
||||||
|
uint compensation = 100; |
||||||
|
uint valuePaid = 10; |
||||||
|
|
||||||
|
if ( currentMonarch.ethAddr != wizardAddress ) |
||||||
|
if (currentMonarch.ethAddr.send( compensation )) revert(); |
||||||
|
|
||||||
|
currentMonarch = Monarch(msg.sender,name,valuePaid,block.timestamp); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,30 @@ |
|||||||
|
pragma solidity >=0.4.9 <0.6.0; |
||||||
|
contract test { |
||||||
|
|
||||||
|
address owner; |
||||||
|
|
||||||
|
function at(address _addr) public returns (bytes memory o_code) { |
||||||
|
assert(_addr != address(0x0)); |
||||||
|
assembly { |
||||||
|
// retrieve the size of the code, this needs assembly |
||||||
|
let size := extcodesize(_addr) |
||||||
|
// allocate output byte array - this could also be done without assembly |
||||||
|
// by using o_code = new bytes(size) |
||||||
|
o_code := mload(0x40) |
||||||
|
// new "memory end" including padding |
||||||
|
mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), not(0x1f)))) |
||||||
|
// store length in memory |
||||||
|
mstore(o_code, size) |
||||||
|
// actually retrieve the code, this needs assembly |
||||||
|
extcodecopy(_addr, add(o_code, 0x20), 0, size) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function bla() public { |
||||||
|
require(tx.origin == owner); |
||||||
|
msg.sender.send(19); |
||||||
|
assembly { |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,145 @@ |
|||||||
|
pragma solidity >=0.4.9 <0.6.0; |
||||||
|
|
||||||
|
/// @title Voting with delegation. |
||||||
|
contract Ballot { |
||||||
|
// This declares a new complex type which will |
||||||
|
// be used for variables later. |
||||||
|
// It will represent a single voter. |
||||||
|
struct Voter { |
||||||
|
uint weight; // weight is accumulated by delegation |
||||||
|
bool voted; // if true, that person already voted |
||||||
|
address delegate; // person delegated to |
||||||
|
uint vote; // index of the voted proposal |
||||||
|
} |
||||||
|
|
||||||
|
// This is a type for a single proposal. |
||||||
|
struct Proposal |
||||||
|
{ |
||||||
|
bytes32 name; // short name (up to 32 bytes) |
||||||
|
uint voteCount; // number of accumulated votes |
||||||
|
} |
||||||
|
|
||||||
|
address public chairperson; |
||||||
|
|
||||||
|
// This declares a state variable that |
||||||
|
// stores a `Voter` struct for each possible address. |
||||||
|
mapping(address => Voter) public voters; |
||||||
|
|
||||||
|
// A dynamically-sized array of `Proposal` structs. |
||||||
|
Proposal[] public proposals; |
||||||
|
|
||||||
|
/// Create a new ballot to choose one of `proposalNames`. |
||||||
|
constructor(bytes32[] memory proposalNames) public { |
||||||
|
chairperson = msg.sender; |
||||||
|
voters[chairperson].weight = 1; |
||||||
|
|
||||||
|
// For each of the provided proposal names, |
||||||
|
// create a new proposal object and add it |
||||||
|
// to the end of the array. |
||||||
|
for (uint i = 0; i < proposalNames.length; i++) { |
||||||
|
// `Proposal({...})` creates a temporary |
||||||
|
// Proposal object and `proposals.push(...)` |
||||||
|
// appends it to the end of `proposals`. |
||||||
|
proposals.push(Proposal({ |
||||||
|
name: proposalNames[i], |
||||||
|
voteCount: 0 |
||||||
|
})); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Give `voter` the right to vote on this ballot. |
||||||
|
// May only be called by `chairperson`. |
||||||
|
function giveRightToVote(address voter) public { |
||||||
|
if (msg.sender != chairperson || voters[voter].voted) { |
||||||
|
// `throw` terminates and reverts all changes to |
||||||
|
// the state and to Ether balances. It is often |
||||||
|
// a good idea to use this if functions are |
||||||
|
// called incorrectly. But watch out, this |
||||||
|
// will also consume all provided gas. |
||||||
|
revert(); |
||||||
|
} |
||||||
|
voters[voter].weight = 1; |
||||||
|
} |
||||||
|
|
||||||
|
/// Delegate your vote to the voter `to`. |
||||||
|
function delegate(address to) public { |
||||||
|
// assigns reference |
||||||
|
Voter memory sender = voters[msg.sender]; |
||||||
|
if (sender.voted) |
||||||
|
revert(); |
||||||
|
|
||||||
|
// Forward the delegation as long as |
||||||
|
// `to` also delegated. |
||||||
|
// In general, such loops are very dangerous, |
||||||
|
// because if they run too long, they might |
||||||
|
// need more gas than is available in a block. |
||||||
|
// In this case, the delegation will not be executed, |
||||||
|
// but in other situations, such loops might |
||||||
|
// cause a contract to get "stuck" completely. |
||||||
|
while ( |
||||||
|
voters[to].delegate != address(0) && |
||||||
|
voters[to].delegate != msg.sender |
||||||
|
) { |
||||||
|
to = voters[to].delegate; |
||||||
|
} |
||||||
|
|
||||||
|
// We found a loop in the delegation, not allowed. |
||||||
|
if (to == msg.sender) { |
||||||
|
revert(); |
||||||
|
} |
||||||
|
|
||||||
|
// Since `sender` is a reference, this |
||||||
|
// modifies `voters[msg.sender].voted` |
||||||
|
sender.voted = true; |
||||||
|
sender.delegate = to; |
||||||
|
Voter memory delegate = voters[to]; |
||||||
|
if (delegate.voted) { |
||||||
|
// If the delegate already voted, |
||||||
|
// directly add to the number of votes |
||||||
|
proposals[delegate.vote].voteCount += sender.weight; |
||||||
|
} else { |
||||||
|
// If the delegate did not vote yet, |
||||||
|
// add to her weight. |
||||||
|
delegate.weight += sender.weight; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// Give your vote (including votes delegated to you) |
||||||
|
/// to proposal `proposals[proposal].name`. |
||||||
|
function vote(uint proposal) public { |
||||||
|
Voter memory sender = voters[msg.sender]; |
||||||
|
if (sender.voted) |
||||||
|
revert(); |
||||||
|
sender.voted = true; |
||||||
|
sender.vote = proposal; |
||||||
|
|
||||||
|
// If `proposal` is out of the range of the array, |
||||||
|
// this will throw automatically and revert all |
||||||
|
// changes. |
||||||
|
proposals[proposal].voteCount += sender.weight; |
||||||
|
} |
||||||
|
|
||||||
|
/// @dev Computes the winning proposal taking all |
||||||
|
/// previous votes into account. |
||||||
|
function winningProposal() view public |
||||||
|
returns (uint winningProposal) |
||||||
|
{ |
||||||
|
uint winningVoteCount = 0; |
||||||
|
for (uint p = 0; p < proposals.length; p++) { |
||||||
|
if (proposals[p].voteCount > winningVoteCount) { |
||||||
|
winningVoteCount = proposals[p].voteCount; |
||||||
|
winningProposal = p; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Calls winningProposal() function to get the index |
||||||
|
// of the winner contained in the proposals array and then |
||||||
|
// returns the name of the winner |
||||||
|
function winnerName() view public |
||||||
|
returns (bytes32 winnerName) |
||||||
|
{ |
||||||
|
winnerName = proposals[winningProposal()].name; |
||||||
|
} |
||||||
|
} |
||||||
|
|
@ -0,0 +1,111 @@ |
|||||||
|
pragma solidity >=0.4.9 <0.6.0; |
||||||
|
|
||||||
|
contract InfoFeed { |
||||||
|
function info() public payable returns (uint ret); |
||||||
|
function call1(uint a) public payable returns (bool); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
contract Ballot { |
||||||
|
|
||||||
|
InfoFeed feed; |
||||||
|
|
||||||
|
struct Voter { |
||||||
|
uint weight; |
||||||
|
bool voted; |
||||||
|
uint8 vote; |
||||||
|
address delegate; |
||||||
|
} |
||||||
|
struct Proposal { |
||||||
|
uint voteCount; |
||||||
|
} |
||||||
|
|
||||||
|
address chairperson; |
||||||
|
mapping(address => Voter) voters; |
||||||
|
Proposal[] proposals; |
||||||
|
|
||||||
|
function send1(address a) public { |
||||||
|
giveRightToVote(a,a); |
||||||
|
} |
||||||
|
|
||||||
|
/// Create a new ballot with $(_numProposals) different proposals. |
||||||
|
constructor(uint8 _numProposals) public { |
||||||
|
address payable d; |
||||||
|
|
||||||
|
(bool success, bytes memory data) = d.delegatecall.gas(800)(abi.encodeWithSignature('function_name', 'arg1', 'arg2')); |
||||||
|
if(!success) revert(); |
||||||
|
|
||||||
|
(bool success2, bytes memory data2) = d.delegatecall.gas(800)(abi.encodeWithSignature('function_name', 'arg1', 'arg2')); |
||||||
|
if(!success2) revert(); |
||||||
|
|
||||||
|
(bool success3, bytes memory data3) = d.call.value(10).gas(800)(abi.encodeWithSignature('function_name', 'arg1', 'arg2')); |
||||||
|
if(!success3) revert(); |
||||||
|
|
||||||
|
(bool success4, bytes memory data4) = d.call.value(10).gas(800)(abi.encodeWithSignature('function_name', 'arg1', 'arg2')); |
||||||
|
if(!success4) revert(); |
||||||
|
|
||||||
|
|
||||||
|
address payable o = msg.sender; |
||||||
|
if(!o.send(1 wei)) revert(); |
||||||
|
|
||||||
|
(bool success5, bytes memory data5) = d.call(abi.encodeWithSignature('function_name', 'arg1', 'arg2')); |
||||||
|
if(!success5) revert(); |
||||||
|
|
||||||
|
|
||||||
|
uint a = now; |
||||||
|
uint c = block.timestamp; |
||||||
|
if(block.timestamp < 100){} |
||||||
|
chairperson = msg.sender; |
||||||
|
voters[chairperson].weight = 1; |
||||||
|
proposals.length = _numProposals; |
||||||
|
if(!d.send(1 wei)) revert(); |
||||||
|
feed.info.value(10).gas(800)(); |
||||||
|
|
||||||
|
feed.call1(1); |
||||||
|
|
||||||
|
this.send1(d); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/// Give $(voter) the right to vote on this ballot. |
||||||
|
/// May only be called by $(chairperson). |
||||||
|
function giveRightToVote(address voter, address b) public payable returns (bool){ |
||||||
|
if (msg.sender != chairperson || voters[voter].voted) return false; |
||||||
|
voters[voter].weight = 1; |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
/// Delegate your vote to the voter $(to). |
||||||
|
function delegate(address to) public { |
||||||
|
Voter memory sender = voters[msg.sender]; // assigns reference |
||||||
|
if (sender.voted) return; |
||||||
|
while (voters[to].delegate != address(0) && voters[to].delegate != msg.sender) |
||||||
|
to = voters[to].delegate; |
||||||
|
if (to == msg.sender) return; |
||||||
|
sender.voted = true; |
||||||
|
sender.delegate = to; |
||||||
|
Voter memory delegate = voters[to]; |
||||||
|
if (delegate.voted) |
||||||
|
proposals[delegate.vote].voteCount += sender.weight; |
||||||
|
else |
||||||
|
delegate.weight += sender.weight; |
||||||
|
} |
||||||
|
|
||||||
|
/// Give a single vote to proposal $(proposal). |
||||||
|
function vote(uint8 proposal) public { |
||||||
|
Voter memory sender = voters[msg.sender]; |
||||||
|
if (sender.voted || proposal >= proposals.length) return; |
||||||
|
sender.voted = true; |
||||||
|
sender.vote = proposal; |
||||||
|
proposals[proposal].voteCount += sender.weight; |
||||||
|
} |
||||||
|
|
||||||
|
function winningProposal() view public returns (uint8 winningProposal) { |
||||||
|
uint256 winningVoteCount = 0; |
||||||
|
for (uint8 proposal = 0; proposal < proposals.length; proposal++) |
||||||
|
if (proposals[proposal].voteCount > winningVoteCount) { |
||||||
|
winningVoteCount = proposals[proposal].voteCount; |
||||||
|
winningProposal = proposal; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,31 @@ |
|||||||
|
pragma solidity >=0.4.9 <0.6.0; |
||||||
|
|
||||||
|
/// @title Voting with delegation. |
||||||
|
contract Ballot { |
||||||
|
|
||||||
|
struct Proposal |
||||||
|
{ |
||||||
|
bytes32 name; // short name (up to 32 bytes) |
||||||
|
uint voteCount; // number of accumulated votes |
||||||
|
} |
||||||
|
|
||||||
|
// A dynamically-sized array of `Proposal` structs. |
||||||
|
Proposal[] public proposals; |
||||||
|
|
||||||
|
/// @dev Computes the winning proposal taking all |
||||||
|
/// previous votes into account. |
||||||
|
function winningProposal() public view |
||||||
|
returns (uint winningProposal) |
||||||
|
{ |
||||||
|
winningProposal = 0; |
||||||
|
} |
||||||
|
|
||||||
|
// Calls winningProposal() function to get the index |
||||||
|
// of the winner contained in the proposals array and then |
||||||
|
// returns the name of the winner |
||||||
|
function winnerName() public view |
||||||
|
returns (bytes32 winnerName) |
||||||
|
{ |
||||||
|
winnerName = proposals[winningProposal()].name; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,45 @@ |
|||||||
|
pragma solidity >=0.4.9 <0.6.0; |
||||||
|
contract grr { |
||||||
|
bool breaker; |
||||||
|
|
||||||
|
function() external { |
||||||
|
uint a = 1; |
||||||
|
string memory sig = "withdraw()"; |
||||||
|
uint b = 3; |
||||||
|
|
||||||
|
bytes4 selector = bytes4(keccak256(abi.encodePacked(sig))); |
||||||
|
|
||||||
|
abi.encode(a,b); |
||||||
|
|
||||||
|
abi.encodePacked(a,b); |
||||||
|
|
||||||
|
a = -b; |
||||||
|
|
||||||
|
a == b; |
||||||
|
|
||||||
|
if(a == b) { |
||||||
|
abi.encodeWithSelector(selector, a, b); |
||||||
|
abi.encodeWithSignature(sig, a, b); |
||||||
|
} |
||||||
|
|
||||||
|
if(b < 4) { a == b; } |
||||||
|
|
||||||
|
if(b > 4) b == a; |
||||||
|
|
||||||
|
while(true) a == b; |
||||||
|
|
||||||
|
for(int i = 0; i < 3; i++) b == a; |
||||||
|
|
||||||
|
while(false) { |
||||||
|
int c = 3; |
||||||
|
uint(c) + a; |
||||||
|
|
||||||
|
c == 5; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
a + b; |
||||||
|
breaker = false; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,19 @@ |
|||||||
|
pragma solidity >=0.4.9 <0.6.0; |
||||||
|
|
||||||
|
contract a { |
||||||
|
|
||||||
|
uint x; |
||||||
|
|
||||||
|
function foo() public { |
||||||
|
x++; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
contract b { |
||||||
|
a x; |
||||||
|
function bar() public { |
||||||
|
address payable a; |
||||||
|
a.send(100 wei); |
||||||
|
x.foo(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,8 @@ |
|||||||
|
contract c { |
||||||
|
uint x; |
||||||
|
uint x_abc; |
||||||
|
constructor(uint _x, uint _abc) public { |
||||||
|
x=_x; |
||||||
|
x_abc=_abc; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,37 @@ |
|||||||
|
pragma solidity >=0.4.9 <0.6.0; |
||||||
|
contract arr { |
||||||
|
uint[] users; |
||||||
|
|
||||||
|
bytes access_rights_per_user; |
||||||
|
|
||||||
|
uint user_index; |
||||||
|
|
||||||
|
address owner; |
||||||
|
|
||||||
|
string grr = "message"; |
||||||
|
|
||||||
|
uint[100] last_100_users; |
||||||
|
|
||||||
|
constructor(address owner1) public { |
||||||
|
owner = owner1; |
||||||
|
user_index = 0; |
||||||
|
} |
||||||
|
|
||||||
|
function addUser(uint id, byte rights) public{ |
||||||
|
users[user_index] = id; |
||||||
|
last_100_users[user_index % 100] = id; |
||||||
|
access_rights_per_user[user_index] = rights; |
||||||
|
user_index++; |
||||||
|
} |
||||||
|
|
||||||
|
function resetState() public{ |
||||||
|
require(msg.sender == owner, grr); |
||||||
|
delete users; |
||||||
|
delete access_rights_per_user; |
||||||
|
delete last_100_users; |
||||||
|
} |
||||||
|
|
||||||
|
function bla(string memory bal) public { |
||||||
|
grr = bal; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,22 @@ |
|||||||
|
pragma solidity >=0.4.9 <0.6.0; |
||||||
|
contract arr { |
||||||
|
uint[] array = [1,2,3]; |
||||||
|
function removeAtIndex() public returns (uint[] memory) { |
||||||
|
delete array[1]; |
||||||
|
return array; |
||||||
|
} |
||||||
|
|
||||||
|
// TODO: deleteFromDynamicArray should not generate warnings if array item is shifted and removed |
||||||
|
/* function safeRemoveAtIndex(uint index) returns (uint[] memory) { |
||||||
|
if (index >= array.length) return; |
||||||
|
|
||||||
|
for (uint i = index; i < array.length-1; i++) { |
||||||
|
array[i] = array[i+1]; |
||||||
|
} |
||||||
|
|
||||||
|
delete array[array.length-1]; |
||||||
|
array.length--; |
||||||
|
|
||||||
|
return array; |
||||||
|
} */ |
||||||
|
} |
@ -0,0 +1,15 @@ |
|||||||
|
pragma solidity >=0.4.9 <0.6.0; |
||||||
|
contract forLoopArr { |
||||||
|
uint[] array; |
||||||
|
constructor(uint[] memory _array) public { |
||||||
|
array = _array; |
||||||
|
} |
||||||
|
|
||||||
|
function shiftArrItem(uint index) public returns(uint[] memory) { |
||||||
|
// TODO: for (uint i = index; i < array.length-1; i++) should also generate warning |
||||||
|
for (uint i = index; i < array.length; i++) { |
||||||
|
array[i] = array[i+1]; |
||||||
|
} |
||||||
|
return array; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,13 @@ |
|||||||
|
contract Sheep { |
||||||
|
string public name; |
||||||
|
string public dna; |
||||||
|
bool g = true; |
||||||
|
constructor(string memory _name, string memory _dna) public { |
||||||
|
name = _name; |
||||||
|
dna = _dna; |
||||||
|
} |
||||||
|
|
||||||
|
function geneticallyEngineer(string memory _dna) public returns (bool) { |
||||||
|
dna = _dna; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,16 @@ |
|||||||
|
pragma solidity >=0.4.9 <0.6.0; |
||||||
|
|
||||||
|
contract B { |
||||||
|
function plus(uint a, uint b) pure internal returns (uint) { |
||||||
|
return a + b; |
||||||
|
} |
||||||
|
|
||||||
|
function eval(function (uint, uint) pure internal returns (uint) f, uint x, uint y) pure internal returns (uint) { |
||||||
|
return f(x, y); |
||||||
|
} |
||||||
|
|
||||||
|
function calc(uint x, uint y) pure public returns (uint) { |
||||||
|
return eval(plus, x, y); |
||||||
|
// return plus(x, y); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,57 @@ |
|||||||
|
pragma solidity >=0.4.9 <0.6.0; |
||||||
|
contract bla { |
||||||
|
uint brr; |
||||||
|
function duper() public { |
||||||
|
brr++; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
contract a is bla { |
||||||
|
|
||||||
|
function blub() public { |
||||||
|
brr++; |
||||||
|
} |
||||||
|
|
||||||
|
function r () public payable { |
||||||
|
address payable a; |
||||||
|
bytes32 hash; |
||||||
|
uint8 v; |
||||||
|
bytes32 r; |
||||||
|
bytes32 s; |
||||||
|
|
||||||
|
blockhash(1); |
||||||
|
block.coinbase; |
||||||
|
block.difficulty; |
||||||
|
block.gaslimit; |
||||||
|
block.number; |
||||||
|
block.timestamp; |
||||||
|
msg.data; |
||||||
|
gasleft(); |
||||||
|
msg.sender; |
||||||
|
msg.value; |
||||||
|
now; |
||||||
|
tx.gasprice; |
||||||
|
tx.origin; |
||||||
|
// assert(1 == 2); |
||||||
|
// require(1 == 1); |
||||||
|
keccak256(abi.encodePacked(a)); |
||||||
|
sha256(abi.encodePacked(a)); |
||||||
|
ripemd160(abi.encodePacked(a)); |
||||||
|
ecrecover(hash, v, r, s); |
||||||
|
addmod(1, 2, 2); |
||||||
|
mulmod(4,4,12); |
||||||
|
|
||||||
|
a.balance; |
||||||
|
blub(); |
||||||
|
a.send(a.balance); |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
super.duper(); |
||||||
|
//a.transfer(a.balance); |
||||||
|
selfdestruct(a); |
||||||
|
//revert(); |
||||||
|
assert(a.balance == 0); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,41 @@ |
|||||||
|
pragma solidity >=0.4.9 <0.6.0; |
||||||
|
|
||||||
|
contract r { |
||||||
|
function s() public view {} |
||||||
|
} |
||||||
|
|
||||||
|
contract a is r { |
||||||
|
uint x = 1; |
||||||
|
|
||||||
|
function getX() public view returns (uint) { |
||||||
|
return x; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
contract b is a { |
||||||
|
uint y = 2; |
||||||
|
uint x = 3; |
||||||
|
|
||||||
|
|
||||||
|
function getY(uint z, bool r) public returns (uint) { |
||||||
|
return y++; |
||||||
|
} |
||||||
|
|
||||||
|
function getY(string storage n) internal view returns (uint) { return 10; } |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
contract c is b { |
||||||
|
string x; |
||||||
|
|
||||||
|
function d() public returns (uint a, uint b) { |
||||||
|
//d(); |
||||||
|
//sha3("bla"); |
||||||
|
address payable o = msg.sender; |
||||||
|
o.call.gas(200000).value(address(this).balance)(abi.encode("pay()")); |
||||||
|
//x++; |
||||||
|
getY(x); |
||||||
|
a = getX() + getY(1, false); |
||||||
|
b = getX() + getY(x); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,38 @@ |
|||||||
|
pragma solidity >=0.4.9 <0.6.0; |
||||||
|
|
||||||
|
contract CharityCampaign { |
||||||
|
mapping (address => uint) contributions; |
||||||
|
int128 feePercentage; |
||||||
|
uint p2; |
||||||
|
address payable processor; |
||||||
|
address payable beneficiary; |
||||||
|
|
||||||
|
constructor(address payable _beneficiary, int128 _feePercentage) public { |
||||||
|
processor = msg.sender; |
||||||
|
beneficiary = _beneficiary; |
||||||
|
feePercentage = _feePercentage; |
||||||
|
} |
||||||
|
|
||||||
|
function contribute() payable public returns (uint feeCollected) { |
||||||
|
uint fee = msg.value * uint256(feePercentage / 100); |
||||||
|
fee = msg.value * (p2 / 100); |
||||||
|
contributions[msg.sender] = msg.value - fee; |
||||||
|
processor.transfer(fee); |
||||||
|
return fee; |
||||||
|
} |
||||||
|
|
||||||
|
function endCampaign() public returns (bool) { |
||||||
|
require(msg.sender == processor || msg.sender == beneficiary); |
||||||
|
selfdestruct(beneficiary); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
// FALSE POSITIVE FOR SELFDESTRUCT TERMINAL |
||||||
|
function endAmbiguous() public { |
||||||
|
if(msg.sender == address(0x0)) { |
||||||
|
selfdestruct(beneficiary); |
||||||
|
} else { |
||||||
|
selfdestruct(processor); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,54 @@ |
|||||||
|
pragma solidity >=0.4.9 <0.6.0; |
||||||
|
|
||||||
|
library Set { |
||||||
|
// We define a new struct datatype that will be used to |
||||||
|
// hold its data in the calling contract. |
||||||
|
struct Data { mapping(uint => bool) flags; } |
||||||
|
|
||||||
|
// Note that the first parameter is of type "storage |
||||||
|
// reference" and thus only its storage address and not |
||||||
|
// its contents is passed as part of the call. This is a |
||||||
|
// special feature of library functions. It is idiomatic |
||||||
|
// to call the first parameter 'self', if the function can |
||||||
|
// be seen as a method of that object. |
||||||
|
function insert(Data storage self, uint value) public |
||||||
|
returns (bool) |
||||||
|
{ |
||||||
|
if (self.flags[value]) |
||||||
|
return false; // already there |
||||||
|
self.flags[value] = true; |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
function remove(Data storage self, uint value) public |
||||||
|
returns (bool) |
||||||
|
{ |
||||||
|
if (!self.flags[value]) |
||||||
|
return false; // not there |
||||||
|
self.flags[value] = false; |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
function contains(Data storage self, uint value) public |
||||||
|
returns (bool) |
||||||
|
{ |
||||||
|
return self.flags[value]; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
contract C { |
||||||
|
Set.Data knownValues; |
||||||
|
|
||||||
|
function register(uint value) public { |
||||||
|
// The library functions can be called without a |
||||||
|
// specific instance of the library, since the |
||||||
|
// "instance" will be the current contract. |
||||||
|
address payable a; |
||||||
|
a.send(10 wei); |
||||||
|
if (!Set.insert(knownValues, value)) |
||||||
|
revert(); |
||||||
|
} |
||||||
|
// In this contract, we can also directly access knownValues.flags, if we want. |
||||||
|
} |
@ -0,0 +1,17 @@ |
|||||||
|
pragma solidity >=0.4.9 <0.6.0; |
||||||
|
|
||||||
|
contract test { |
||||||
|
|
||||||
|
address owner; |
||||||
|
|
||||||
|
modifier onlyOwner { |
||||||
|
uint a = 0; |
||||||
|
if (msg.sender != owner) |
||||||
|
revert(); |
||||||
|
_; |
||||||
|
} |
||||||
|
|
||||||
|
function b(address a) public onlyOwner returns (bool) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,28 @@ |
|||||||
|
pragma solidity >=0.4.9 <0.6.0; |
||||||
|
|
||||||
|
contract owned { |
||||||
|
|
||||||
|
uint r=0; |
||||||
|
|
||||||
|
modifier ntimes(uint n) { |
||||||
|
for(uint i=0;i<n-1;i++){ |
||||||
|
_; |
||||||
|
} |
||||||
|
_; |
||||||
|
} |
||||||
|
|
||||||
|
modifier plus100 { |
||||||
|
uint bla=1; |
||||||
|
r+=100; |
||||||
|
_; |
||||||
|
} |
||||||
|
|
||||||
|
function a() ntimes(10) plus100 public payable returns (uint) { |
||||||
|
{ |
||||||
|
uint bla=5; |
||||||
|
r += bla; |
||||||
|
} |
||||||
|
return r; |
||||||
|
} |
||||||
|
} |
||||||
|
|
@ -0,0 +1,13 @@ |
|||||||
|
pragma solidity >=0.4.9 <0.6.0; |
||||||
|
|
||||||
|
contract Fund { |
||||||
|
/// Mapping of ether shares of the contract. |
||||||
|
mapping(address => uint) shares; |
||||||
|
/// Withdraw your share. |
||||||
|
function withdraw() public { |
||||||
|
uint share = shares[msg.sender]; |
||||||
|
shares[msg.sender] = 0; |
||||||
|
if (!msg.sender.send(share)) |
||||||
|
revert(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,49 @@ |
|||||||
|
pragma solidity >=0.4.9 <0.6.0; |
||||||
|
|
||||||
|
contract InfoFeed { |
||||||
|
uint c; |
||||||
|
function info() constant returns (uint ret) {return c;} |
||||||
|
function call1(uint a) constant returns (bool) {return true;} |
||||||
|
} |
||||||
|
|
||||||
|
// THIS CONTRACT CONTAINS A BUG - DO NOT USE |
||||||
|
contract Fund { |
||||||
|
/// Mapping of ether shares of the contract. |
||||||
|
//mapping(address => uint) shares; |
||||||
|
/// Withdraw your share. |
||||||
|
|
||||||
|
uint c = 0; |
||||||
|
function withdraw() constant { |
||||||
|
InfoFeed f; |
||||||
|
|
||||||
|
|
||||||
|
//shares[msg.sender] /= 1; |
||||||
|
|
||||||
|
f.info(); |
||||||
|
|
||||||
|
//if (msg.sender.send(shares[msg.sender])) throw; |
||||||
|
// shares[msg.sender] = 0; |
||||||
|
|
||||||
|
|
||||||
|
b(true, false); |
||||||
|
//shares[msg.sender]++; |
||||||
|
//c++; |
||||||
|
|
||||||
|
} |
||||||
|
mapping(address => uint) shares; |
||||||
|
|
||||||
|
function b(bool a, bool b) returns (bool) { |
||||||
|
mapping(address => uint) c = shares; |
||||||
|
c[msg.sender] = 0; |
||||||
|
//f(); |
||||||
|
//withdraw(); |
||||||
|
//shares[msg.sender]++; |
||||||
|
//c++; |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
function f() { |
||||||
|
c++; |
||||||
|
withdraw(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,14 @@ |
|||||||
|
contract sd { |
||||||
|
|
||||||
|
uint x = 0; |
||||||
|
function() external payable { } |
||||||
|
|
||||||
|
function c () public { |
||||||
|
selfdestruct(address(0xdeadbeef)); |
||||||
|
} |
||||||
|
|
||||||
|
function b () public { |
||||||
|
selfdestruct(address(0xdeadbeef)); |
||||||
|
x = 1; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,10 @@ |
|||||||
|
pragma solidity >=0.4.9 <0.6.0; |
||||||
|
contract bytesString { |
||||||
|
|
||||||
|
function length(string memory a) public pure returns(uint) { |
||||||
|
bytes memory x = bytes(a); |
||||||
|
|
||||||
|
return x.length; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,36 @@ |
|||||||
|
pragma solidity >=0.4.9 <0.6.0; |
||||||
|
|
||||||
|
contract Ballot { |
||||||
|
|
||||||
|
struct Voter { |
||||||
|
uint weight; |
||||||
|
bool voted; |
||||||
|
uint8 vote; |
||||||
|
address delegate; |
||||||
|
baz foo; |
||||||
|
} |
||||||
|
|
||||||
|
struct baz{ |
||||||
|
uint bar; |
||||||
|
} |
||||||
|
|
||||||
|
mapping(address => Voter) voters; |
||||||
|
|
||||||
|
/// Create a new ballot with $(_numProposals) different proposals. |
||||||
|
function bla(address payable a) public { |
||||||
|
Voter storage x = voters[a]; |
||||||
|
|
||||||
|
if (!a.send(10)) |
||||||
|
revert(); |
||||||
|
|
||||||
|
//voters[a] = Voter(10,true,1,a); |
||||||
|
//x.foo.bar *= 100; |
||||||
|
bli(x); |
||||||
|
} |
||||||
|
|
||||||
|
//function bla(){} |
||||||
|
|
||||||
|
function bli(Voter storage x) private { |
||||||
|
x.foo.bar++; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,16 @@ |
|||||||
|
pragma solidity >=0.4.9 <0.6.0; |
||||||
|
|
||||||
|
contract test { |
||||||
|
|
||||||
|
function () external { |
||||||
|
address payable x; |
||||||
|
this.b(x); |
||||||
|
x.call('something'); |
||||||
|
x.send(1 wei); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
function b(address a) public returns (bool) { |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,7 @@ |
|||||||
|
contract c { |
||||||
|
uint x; |
||||||
|
function f(address payable r) public payable { |
||||||
|
r.transfer(1); |
||||||
|
x = 2; |
||||||
|
} |
||||||
|
} |
@ -1,4 +1,7 @@ |
|||||||
|
|
||||||
require('./analysis/staticAnalysisCommon-test.js') |
require('./analysis/staticAnalysisCommon-test.js') |
||||||
require('./analysis/staticAnalysisIntegration-test.js') |
|
||||||
require('./analysis/staticAnalysisIssues-test.js') |
require('./analysis/staticAnalysisIntegration-test-0.4.24.js') |
||||||
|
require('./analysis/staticAnalysisIssues-test-0.4.24.js') |
||||||
|
|
||||||
|
require('./analysis/staticAnalysisIntegration-test-0.5.0.js') |
||||||
|
require('./analysis/staticAnalysisIssues-test-0.5.0.js') |
||||||
|
Loading…
Reference in new issue