Skip to content

Instantly share code, notes, and snippets.

@hrkrshnn
hrkrshnn / Readme.md
Last active April 4, 2023 08:11
Instructions to see raw SMTLib queries generated by SMTChecker from solc

Compile solc locally after applying the below patch (solc.patch).Build instructions.

./solc example.sol --model-checker-engine bmc
Call to check. Solver state:
(declare-datatypes ((bytes_tuple 0)) (((bytes_tuple (bytes_tuple_accessor_array (Array Int Int)) (bytes_tuple_accessor_length Int)))))
(declare-datatypes ((tx_type 0)) (((tx_type (block.basefee Int) (block.chainid Int) (block.coinbase Int) (block.difficulty Int) (block.gaslimit Int) (block.number Int) (block.timestamp Int) (blockhash (Array Int Int)) (msg.data bytes_tuple) (msg.sender Int) (msg.sig Int) (msg.value Int) (tx.gasprice Int) (tx.origin Int)))))
pragma solidity ^0.8.5;
contract C {
function convert(bytes memory m) external pure returns (bytes4) {
return bytes4(m);
}
}
@hrkrshnn
hrkrshnn / BribeContract.yul
Last active October 10, 2022 14:42
Run by `solc --strict-assembly --optimize --ir-optimized`. Context: https://twitter.com/NoahZinsmeister/status/1499845282598731782 Need to use Yul, since there is no `verbatim` in Solidity's inline assembly.
// UNTESTED!
object "BribeContract" {
code {
let size := datasize("BribeRuntime")
codecopy(0, dataoffset("BribeRuntime"), size)
return(0, size)
}
object "BribeRuntime" {
code {
// Bribe by sending ETH. To try and claim, send a tx without ETH. Assumes that a tx with
@hrkrshnn
hrkrshnn / generic.org
Last active April 21, 2024 01:51
Some generic writeup about common gas optimizations, etc.

Upgrade to at least 0.8.4

Using newer compiler versions and the optimizer gives gas optimizations and additional safety checks for free!

The advantages of versions 0.8.* over <0.8.0 are:

  • Safemath by default from 0.8.0 (can be more gas efficient than some library based safemath).
  • Low level inliner from 0.8.2, leads to cheaper runtime gas. Especially relevant when the contract has small functions. For
@hrkrshnn
hrkrshnn / calldata_example.sol
Created September 30, 2021 09:41
An example of using calldata parameter in internal functions.
contract C {
function f(uint[] calldata arr) external returns(uint) {
return sum(arr);
}
function sum(uint[] calldata arr) internal returns(uint _sum) {
for(uint i = 0; i < arr.length; i++) {
_sum += arr[i];
}
}
}
@hrkrshnn
hrkrshnn / diff.diff
Created September 28, 2021 12:00
The new file is after the storateBytes fix.
diff -u /tmp/old.yul /tmp/new.yul
--- /tmp/old.yul 2021-09-28 13:41:14.873051780 +0200
+++ /tmp/new.yul 2021-09-28 13:39:28.096229030 +0200
@@ -53,8 +53,8 @@
}
- function update_byte_slice_32_shift_0(value, toInsert) -> result {
- let mask := 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ function update_byte_slice_1_shift_0(value, toInsert) -> result {
Optimized IR:
/*=====================================================*
* WARNING *
* Solidity to Yul compilation is still EXPERIMENTAL *
* It can result in LOSS OF FUNDS or worse *
* !USE AT YOUR OWN RISK! *
*=====================================================*/
/// @use-src 0:"/home/hari/s/4/test/libsolidity/semanticTests/userDefinedValueType/calldata.sol"
object "C_294" {
modified test/libsolidity/semanticTests/userDefinedValueType/erc20.sol
@@ -114,32 +114,32 @@ contract ERC20 {
// constructor()
// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14
// gas irOptimized: 460447
-// gas legacy: 833310
-// gas legacyOptimized: 416135
+// gas legacy: 855430
+// gas legacyOptimized: 420959
// totalSupply() -> 20
contract C
{
constructor() payable {}
function f(address payable a) public returns(bool) {
require(1000 == address(this).balance);
require(100 == a.balance);
a.send(600);
// a == this is not possible because address(this).balance == 1000
// and a.balance == 100,
// so this should hold in CHC, ignoring the transfer revert.
@hrkrshnn
hrkrshnn / erc20.sol
Created August 19, 2021 15:53
ERC20 using user defined type name
pragma solidity ^0.8.7;
// User defined type name. Indicating a type with 18 decimals.
type UFixed18 is uint256;
library FixedMath
{
function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {
return UFixed18(uint(a) + uint(b));
}