diff --git a/.gas-snapshot b/.gas-snapshot new file mode 100644 index 0000000..1e4e27b --- /dev/null +++ b/.gas-snapshot @@ -0,0 +1,2 @@ +TestSimpleTStore:testEmptyRead() (gas: 5614) +TestSimpleTStore:testStore() (gas: 6415) \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..f4b7dfb --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,29 @@ +name: CI +on: + push: + branches: + - master + pull_request: + +env: + FOUNDRY_PROFILE: ci + +jobs: + run-ci: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + + - name: Install deps + run: forge install + + - name: Check gas snapshots + run: forge snapshot --check --use bin/solc + + - name: Run tests + run: forge test --use bin/solc diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d8a1d07 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +cache/ +out/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..888d42d --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "lib/forge-std"] + path = lib/forge-std + url = https://github.com/foundry-rs/forge-std diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..68a49da --- /dev/null +++ b/LICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..296bb4e --- /dev/null +++ b/Readme.md @@ -0,0 +1,24 @@ +# Transient Store Foundry Template + +A foundry template with custom `solc` binaries (from [transient-storage](https://github.com/ethereum/solidity/tree/transient-store)) that supports transient storage opcodes in inline assembly. +```bash +forge build --use bin/solc +forge test --use bin/solc +``` + +## Example contract + +```solidity +contract SimpleTStore { + function tstore(uint key, uint value) external { + assembly { + tstore(key, value) + } + } + function tload(uint key) external view returns (uint value) { + assembly { + value := tload(key) + } + } +} +``` diff --git a/bin/solc b/bin/solc new file mode 100755 index 0000000..22f07b9 --- /dev/null +++ b/bin/solc @@ -0,0 +1,34 @@ +#!/bin/bash + +# Function to detect the operating system +detect_os() { + local os + if [[ "$(uname)" == "Darwin" ]]; then + os="mac" + elif [[ "$(uname)" == "Linux" ]]; then + os="linux" + else + os="unknown" + fi + echo "$os" +} + +# Main script logic +main() { + local os=$(detect_os) + + case $os in + mac) + ./bin/solc-osx "$@" + ;; + linux) + ./bin/solc-static-linux "$@" + ;; + *) + echo "Unsupported OS" + exit 1 + ;; + esac +} + +main "$@" diff --git a/bin/solc-osx b/bin/solc-osx new file mode 100755 index 0000000..e93f0cf Binary files /dev/null and b/bin/solc-osx differ diff --git a/bin/solc-static-linux b/bin/solc-static-linux new file mode 100755 index 0000000..5ad66fc Binary files /dev/null and b/bin/solc-static-linux differ diff --git a/foundry.toml b/foundry.toml new file mode 100644 index 0000000..4973cfd --- /dev/null +++ b/foundry.toml @@ -0,0 +1,4 @@ +[profile.default] +cancun = true +[profile.ci.fuzz] +runs = 10_000 diff --git a/lib/forge-std b/lib/forge-std new file mode 160000 index 0000000..40977d9 --- /dev/null +++ b/lib/forge-std @@ -0,0 +1 @@ +Subproject commit 40977d9e9444acd4c59c16b6782c658c786c0d05 diff --git a/src/SimpleTStore.sol b/src/SimpleTStore.sol new file mode 100644 index 0000000..4c1cbba --- /dev/null +++ b/src/SimpleTStore.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: Unlicense +pragma solidity ^0.8.20; + +contract SimpleTStore { + function tstore(uint key, uint value) external { + assembly { + tstore(key, value) + } + } + function tload(uint key) external view returns (uint value) { + assembly { + value := tload(key) + } + } +} diff --git a/test/SimpleTStore.t.sol b/test/SimpleTStore.t.sol new file mode 100644 index 0000000..e55d44c --- /dev/null +++ b/test/SimpleTStore.t.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: Unlicense +pragma solidity ^0.8.13; + +import "forge-std/Test.sol"; + +import "src/SimpleTStore.sol"; + +contract TestSimpleTStore is Test { + SimpleTStore c; + + function setUp() public { + c = new SimpleTStore(); + } + + function testEmptyRead() public { + assertEq(c.tload(0), 0); + } + + function testStore() public { + c.tstore(0, 1); + assertEq(c.tload(0), 1); + } +}