Web3 and Program Analysis

Dr. Saurabh Joshi

Principal Researcher

Supra Research

What is a blockchain?

Execution trace of a deterministic state machine

What is a blockchain?

s_1
s_2
s_3
s_4
s_4
s_5
t_1
t_3
t_5
t_2
t_4

What is a blockchain?

Programs are state transformers

x=x+1
x = 0
x = 1
x=x+1
x = 1
x = 2
x=x+1
x = 255
x = ?

Need for determinism

Without deterministic operational semantics, given the same sequence of transactions, output state may be different when executed on a different hardware, or on the same hardware at a different time

What is a blockchain?

Execution trace of a deterministic state machine agreed upon by a network of distributed, possibly heterogenous and decentralized computers

Determinism

  • Floating point arithmetic
  • Signed integer arithmetic
  • Concurrency
  • Interaction with external environment
  • ..and many more

Termination

  • All transactions are executed with a pre-determined upperbound on gas (resources) consumed
gas : Instr \rightarrow \mathbb{N}

Gas Optimization

  • Reduce the amount of gas used while retaining the same input/output behaviour
minimize \sum gas(Instr_i)
  • Gas for storage and gas for computation makes gas optimization a bit tricky

Gas Estimation

  • Provide the number of gas units that would be consumed by the transaction
  • Undecidability
  • Input context is not known until execution
  • Provide an estimate for the number of gas units that would be consumed by the transaction
  • Accurate estimation needed both for users and for the network

Compilers and Virtual Machines

  • From high level programming languages to blockchain VMs (e.g., Solidity -> EVM, Move -> Move VM, Rust/C++ -> Solana VM)
  • Enabling smart contracts written in one language to work on another VM (e.g., Fractal, A transpiler that makes Solidity work on Move VM)
  • Enabling smart contracts written in one language to work on near native assembly (e.g., Rust/C++ -> Wasm)

Safety and security of smart contracts

Example Vulnerability

function multiClaim(uint256[] memory _tickets) external {   
	uint256 totalReward = 0;     
    for (uint i = 0; i < _tickets.length; i++) {  
    	require (msg.sender == lotteryNFT.ownerOf(_tickets[i]),    “not from owner”); 
        require (!lotteryNFT.getClaimStatus(_tickets[i]), “claimed”);  
        uint256 reward = getRewardView(_tickets[i]);  
        
        if(reward>0) {
        	totalReward = reward.add(totalReward);   
            }
     }
     
     lotteryNFT.multiClaimReward(_tickets); 
     
     if(totalReward>0) {      
     	cake.safeTransfer(address(msg.sender), totalReward); 
     }    
     
     emit MultiClaim(msg.sender, totalReward);
     
     }

“If we want to be serious about quality, it is time to get tired of finding bugs and start preventing their happening in the first place.”Alan Page

Made with Slides.com