Link to this headingSmart Contract Scanning

Blockchain Security 101

How Coinbase made a tool to automate Smart Contract Scanning

https://github.com/crytic/rattle
https://swcregistry.io/

Link to this headingCode Review Smart Contracts

Link to this headingEthereum Smart Contracts

https://consensys.github.io/smart-contract-best-practices/security-tools/

Example Bad Contracts:
https://swcregistry.io/
https://github.com/crytic/not-so-smart-contracts
https://github.com/smartbugs/smartbugs-wild
https://www.damnvulnerabledefi.xyz/
https://github.com/cclabsInc/BlockChainExploitation

Smart Contract Scanners:
https://github.com/crytic/medusa
https://github.com/crytic/slither
https://github.com/smartbugs/smartbugs
https://github.com/crytic/building-secure-contracts

Link to this headingSolana Smart Contracts

https://medium.com/coinmonks/how-to-audit-solana-smart-contracts-part-1-a-systematic-approach-56a434f6c9ed
https://medium.com/coinmonks/how-to-audit-solana-smart-contracts-part-2-automated-scanning-ceb88830ae6d

Paid Programs

Link to this headingSlither

Slither, the Solidity source analyzer

  • The installed solc version must be exactly the same as the version being used.

Run on a Token Address:

slither-check-erc 0x2A46f2fFD99e19a89476E2f62270e0a35bBf0756 DigitalMediaCore --erc ERC721 Installing '0.4.25'... Version '0.4.25' installed. WARNING:CryticCompile:Warning: crytic-export/etherscan-contracts/0x2A46f2fFD99e19a89476E2f62270e0a35bBf0756-DigitalMediaCore.sol:169:3: Warning: Defining constructors as functions with the same name as the contract is deprecated. Use "constructor(...) { ... }" instead. function Ownable() public { ^ (Relevant source part starts here and spans across multiple lines). Warning: crytic-export/etherscan-contracts/0x2A46f2fFD99e19a89476E2f62270e0a35bBf0756-DigitalMediaCore.sol:960:3: Warning: Defining constructors as functions with the same name as the contract is deprecated. Use "constructor(...) { ... }" instead. function ERC721Token(string _name, string _symbol) public { ^ (Relevant source part starts here and spans across multiple lines). Warning: crytic-export/etherscan-contracts/0x2A46f2fFD99e19a89476E2f62270e0a35bBf0756-DigitalMediaCore.sol:362:17: Warning: This function only accepts a single "bytes" argument. Please use "abi.encodePacked(...)" or a similar function to encode the data. require(keccak256(candidateCreatorRegistryStore.typeOfContract()) == keccak256("approvedCreatorRegistry")); ^-------------------------------------------------------^ Warning: crytic-export/etherscan-contracts/0x2A46f2fFD99e19a89476E2f62270e0a35bBf0756-DigitalMediaCore.sol:362:17: Warning: The provided argument of type string memory is not implicitly convertible to expected type bytes memory. require(keccak256(candidateCreatorRegistryStore.typeOfContract()) == keccak256("approvedCreatorRegistry")); ^-------------------------------------------------------^ # Check DigitalMediaCore ## Check functions [✓] balanceOf(address) is present [✓] balanceOf(address) -> () (correct return value) [✓] balanceOf(address) is view [✓] ownerOf(uint256) is present [✓] ownerOf(uint256) -> () (correct return value) [✓] ownerOf(uint256) is view [✓] safeTransferFrom(address,address,uint256,bytes) is present [✓] safeTransferFrom(address,address,uint256,bytes) -> () (correct return type) [✓] Transfer(address,address,uint256) is emitted [✓] safeTransferFrom(address,address,uint256) is present [✓] safeTransferFrom(address,address,uint256) -> () (correct return type) [✓] Transfer(address,address,uint256) is emitted [✓] transferFrom(address,address,uint256) is present [✓] transferFrom(address,address,uint256) -> () (correct return type) [✓] Transfer(address,address,uint256) is emitted [✓] approve(address,uint256) is present [✓] approve(address,uint256) -> () (correct return type) [✓] Approval(address,address,uint256) is emitted [✓] setApprovalForAll(address,bool) is present [✓] setApprovalForAll(address,bool) -> () (correct return type) [✓] ApprovalForAll(address,address,bool) is emitted [✓] getApproved(uint256) is present [✓] getApproved(uint256) -> () (correct return value) [✓] getApproved(uint256) is view [✓] isApprovedForAll(address,address) is present [✓] isApprovedForAll(address,address) -> () (correct return value) [✓] isApprovedForAll(address,address) is view [✓] supportsInterface(bytes4) is present [✓] supportsInterface(bytes4) -> () (correct return value) [✓] supportsInterface(bytes4) is view [✓] name() is present [✓] name() -> () (correct return value) [✓] name() is view [✓] symbol() is present [✓] symbol() -> () (correct return value) [✓] tokenURI(uint256) is present [✓] tokenURI(uint256) -> () (correct return value) ## Check events [✓] Transfer(address,address,uint256) is present [✓] parameter 0 is indexed [✓] parameter 1 is indexed [ ] parameter 2 should be indexed [✓] Approval(address,address,uint256) is present [✓] parameter 0 is indexed [✓] parameter 1 is indexed [ ] parameter 2 should be indexed [✓] ApprovalForAll(address,address,bool) is present [✓] parameter 0 is indexed [✓] parameter 1 is indexed

Run on a Single File:

slither tests/uninitialized.sol

Run on a Folder:

slither .

Run with Docker:

docker pull trailofbits/eth-security-toolbox docker run -it -v /home/share:/share trailofbits/eth-security-toolbox

Link to this headingEchidna

TODO: https://secure-contracts.com/program-analysis/echidna/exercises/Exercise-2.html

>>> bat testtoken.sol pragma solidity ^0.8.0; import "./token.sol"; /// @dev Run the template with /// ``` /// solc-select use 0.8.0 /// echidna program-analysis/echidna/exercises/exercise1/template.sol /// ``` contract TestToken is Token { address echidna = tx.origin; constructor() { balances[echidna] = 10_000; } function echidna_test_balance() public view returns (bool) { return balances[echidna] <= 10_000; } } >>> echidna testtoken.sol [2025-06-26 20:17:06.32] Compiling testtoken.sol... Done! (0.647776s) Multiple contracts found, only analyzing the first Analyzing contract: /Users/brian.ridings/Documents/echidna_tests/testtoken.sol:TestToken [2025-06-26 20:17:06.97] Running slither on testtoken.sol... Done! (0.767738s) echidna_test_balance: failed!💥 Call sequence: TestToken.transfer(0x10000,10001) Time delay: 487078 seconds Block delay: 57071 Traces: Unique instructions: 641 Unique codehashes: 1 Corpus size: 3 Seed: 642813754373980386 Total calls: 404

Link to this headingManticore

ERROR: This has been abandoned and has many bugs.

From Docker:

>>> docker pull trailofbits/manticore >>> docker run --rm -it -v $(pwd):/wd --name manticore-docker trailofbits/manticore bash root@5c1b5456ab44:/# solc-select install 0.8.25 Installing solc '0.8.25'... Version '0.8.25' installed. root@5c1b5456ab44:/# solc-select use 0.8.25 Switched global version to 0.8.25 root@5c1b5456ab44:/# manticore /wd/ExampleERC20.sol

Link to this headingPublished Bytecode on Blockchain

Getting Blocks from the Mainnet:

Blockchain Scanners: