From ebf1779b3b6e5dd248819f4491d3aa5c4ea1f2a6 Mon Sep 17 00:00:00 2001 From: Ben Goebel Date: Mon, 29 Jan 2024 15:45:43 -0700 Subject: [PATCH] initial commit --- .github/CODEOWNERS | 1 + .github/ISSUE_TEMPLATE/01_FEATURE_REQUEST.md | 11 ++++ .github/ISSUE_TEMPLATE/02_BUG_REPORT.md | 13 ++++ .../ISSUE_TEMPLATE/03_CODEBASE_IMPROVEMENT.md | 7 +++ .github/PULL_REQUEST_TEMPLATE.md | 8 +++ .github/linter/base_style.rb | 4 ++ .github/linter/readme_style.rb | 10 +++ .github/workflows/build.yml | 18 ++++++ .github/workflows/check.yml | 26 ++++++++ .gitignore | 10 +++ .tool-versions | 2 + Contributing.md | 58 ++++++++++++++++++ LICENSE | 21 +++++++ README.md | 29 +++++++++ Scarb.lock | 14 +++++ Scarb.toml | 11 ++++ book/src/assets/piltover.png | Bin 0 -> 33091 bytes src/lib.cairo | 25 ++++++++ tests/test_contract.cairo | 45 ++++++++++++++ 19 files changed, 313 insertions(+) create mode 100644 .github/CODEOWNERS create mode 100644 .github/ISSUE_TEMPLATE/01_FEATURE_REQUEST.md create mode 100644 .github/ISSUE_TEMPLATE/02_BUG_REPORT.md create mode 100644 .github/ISSUE_TEMPLATE/03_CODEBASE_IMPROVEMENT.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/linter/base_style.rb create mode 100644 .github/linter/readme_style.rb create mode 100644 .github/workflows/build.yml create mode 100644 .github/workflows/check.yml create mode 100644 .gitignore create mode 100644 .tool-versions create mode 100644 Contributing.md create mode 100644 LICENSE create mode 100644 README.md create mode 100644 Scarb.lock create mode 100644 Scarb.toml create mode 100644 book/src/assets/piltover.png create mode 100644 src/lib.cairo create mode 100644 tests/test_contract.cairo diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..63a75c4 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @drspacemn @glihm \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/01_FEATURE_REQUEST.md b/.github/ISSUE_TEMPLATE/01_FEATURE_REQUEST.md new file mode 100644 index 0000000..ff34057 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/01_FEATURE_REQUEST.md @@ -0,0 +1,11 @@ +--- +name: Feature request +about: suggest new feature +title: "[feat] " +labels: "feature" +assignees: "" +--- + + + +#### References diff --git a/.github/ISSUE_TEMPLATE/02_BUG_REPORT.md b/.github/ISSUE_TEMPLATE/02_BUG_REPORT.md new file mode 100644 index 0000000..57a92f1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/02_BUG_REPORT.md @@ -0,0 +1,13 @@ +--- +name: Bug report +about: create bug report +title: "[bug] " +labels: "bug" +assignees: "" +--- + +**ver:** + + + +**How to reproduce:** diff --git a/.github/ISSUE_TEMPLATE/03_CODEBASE_IMPROVEMENT.md b/.github/ISSUE_TEMPLATE/03_CODEBASE_IMPROVEMENT.md new file mode 100644 index 0000000..0132b95 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/03_CODEBASE_IMPROVEMENT.md @@ -0,0 +1,7 @@ +--- +name: Codebase improvement +about: docs, ci, tooling, other +title: "[dev] " +labels: "dev" +assignees: "" +--- diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..539461b --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,8 @@ + + +- [ ] issue # +- [ ] follows contribution [guide](../CONTRIBUTING.md) +- [ ] code change includes tests +- [ ] breaking change + + diff --git a/.github/linter/base_style.rb b/.github/linter/base_style.rb new file mode 100644 index 0000000..8d98105 --- /dev/null +++ b/.github/linter/base_style.rb @@ -0,0 +1,4 @@ +all +# lame rules +exclude_rule 'MD002' +exclude_rule 'MD041' diff --git a/.github/linter/readme_style.rb b/.github/linter/readme_style.rb new file mode 100644 index 0000000..9b6cfc9 --- /dev/null +++ b/.github/linter/readme_style.rb @@ -0,0 +1,10 @@ +all +# allow inline HTML for README fmt +exclude_rule 'MD033' +# badges trigger rule +exclude_rule 'MD034' +# README img serves as 'First Header' +exclude_rule 'MD002' +exclude_rule 'MD041' +# TODO: disable/enable not working for all-contribs +exclude_rule 'MD013' diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..a46b060 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,18 @@ +name: build + +on: + workflow_dispatch: + push: + branches: + - main + pull_request: +permissions: read-all + +jobs: + check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: asdf-vm/actions/install@v3 + - run: scarb fmt --check + - run: scarb build diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml new file mode 100644 index 0000000..6b0977a --- /dev/null +++ b/.github/workflows/check.yml @@ -0,0 +1,26 @@ +name: check + +on: + workflow_dispatch: + push: + branches: + - main + pull_request: +permissions: read-all + +jobs: + markdown: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - run: | + sudo gem install mdl + mdl -s .github/linter/readme_style.rb README.md + mdl -s .github/linter/base_style.rb book .github + + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: asdf-vm/actions/install@v3 + - run: snforge test diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..85caaf6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +# Sys files +**/.DS_Store + +# Scarb and Starknet Foundry +**/target +.snfoundry_cache/ + +# Starkli +**/account.json +**/keystore.json diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 0000000..4267afd --- /dev/null +++ b/.tool-versions @@ -0,0 +1,2 @@ +scarb 2.4.4 +starknet-foundry 0.16.0 diff --git a/Contributing.md b/Contributing.md new file mode 100644 index 0000000..4baec02 --- /dev/null +++ b/Contributing.md @@ -0,0 +1,58 @@ +## 🛠️ Contributing to Piltover 🛠️ + +Welcome, contributing to `piltover` is easy! + +1. Submit or comment your intent on an issue +1. We will try to respond quickly +1. Fork this repo +1. Submit your PR against `main` +1. Address PR Review + +### Issue + +Project tracking is done via GitHub [issues](https://github.com/keep-starknet-strange/piltover/issues). +First look at open issues to see if your request is already submitted. +If it is comment on the issue requesting assignment, if not open an issue. + +We use 3 issue labels for development: + +- `feat` -> suggest new feature +- `bug` -> create a reproducible bug report +- `dev` -> non-functional repository changes + +These labels are used as prefixes as follows for `issue`, `branch name`, `pr title`: + +- `[feat]` -> `feat/{issue #}-{issue name}` -> `feat:` +- `[bug]` -> `bug/{issue #}-{issue name}` -> `bug:` +- `[dev]` -> `dev/{issue #}-{issue name}` -> `dev:` + +### Submit PR + +Ensure your code is well formatted, well tested and well documented. A core contributor +will review your work. Address changes, ensure ci passes, +and voilà you're a piltover contributor. + +Markdown [linter](https://github.com/markdownlint/markdownlint?tab=readme-ov-file#markdown-lint-tool): + +```bash +mdl -s .github/linter/readme_style.rb README.md +``` + +Scarb linter: + +```bash +scarb fmt +``` + +### Additional Resources + +- [Cairo Book](https://book.cairo-lang.org/) +- [Starknet Book](https://book.starknet.io/) +- [Starknet Foundry Book](https://foundry-rs.github.io/starknet-foundry/) +- [Starknet By Example](https://starknet-by-example.voyager.online/) +- [Starkli Book](https://book.starkli.rs/) +- [Syncing a Fork](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork) + +## + +Thank you for your contribution! diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..885707a --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Keep Starknet Strange + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +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 OR COPYRIGHT HOLDERS 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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..4bd68c9 --- /dev/null +++ b/README.md @@ -0,0 +1,29 @@ +
+ + + [![Check Workflow Status](https://github.com/keep-starknet-strange/blobstream-starknet/actions/workflows/check.yml/badge.svg)](https://github.com/keep-starknet-strange/blobstream-starknet/actions/workflows/check.yml) + [![Build Workflow Status](https://github.com/keep-starknet-strange/blobstream-starknet/actions/workflows/build.yml/badge.svg)](https://github.com/keep-starknet-strange/blobstream-starknet/actions/workflows/build.yml) + + [![Exploration_Team](https://img.shields.io/badge/Exploration_Team-29296E.svg?&style=for-the-badge&logo=data:image/svg%2bxml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIGlkPSJhIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxODEgMTgxIj48ZGVmcz48c3R5bGU+LmJ7ZmlsbDojZmZmO308L3N0eWxlPjwvZGVmcz48cGF0aCBjbGFzcz0iYiIgZD0iTTE3Ni43Niw4OC4xOGwtMzYtMzcuNDNjLTEuMzMtMS40OC0zLjQxLTIuMDQtNS4zMS0xLjQybC0xMC42MiwyLjk4LTEyLjk1LDMuNjNoLjc4YzUuMTQtNC41Nyw5LjktOS41NSwxNC4yNS0xNC44OSwxLjY4LTEuNjgsMS44MS0yLjcyLDAtNC4yN0w5Mi40NSwuNzZxLTEuOTQtMS4wNC00LjAxLC4xM2MtMTIuMDQsMTIuNDMtMjMuODMsMjQuNzQtMzYsMzcuNjktMS4yLDEuNDUtMS41LDMuNDQtLjc4LDUuMThsNC4yNywxNi41OGMwLDIuNzIsMS40Miw1LjU3LDIuMDcsOC4yOS00LjczLTUuNjEtOS43NC0xMC45Ny0xNS4wMi0xNi4wNi0xLjY4LTEuODEtMi41OS0xLjgxLTQuNCwwTDQuMzksODguMDVjLTEuNjgsMi4zMy0xLjgxLDIuMzMsMCw0LjUzbDM1Ljg3LDM3LjNjMS4zNiwxLjUzLDMuNSwyLjEsNS40NCwxLjQybDExLjQtMy4xMSwxMi45NS0zLjYzdi45MWMtNS4yOSw0LjE3LTEwLjIyLDguNzYtMTQuNzYsMTMuNzNxLTMuNjMsMi45OC0uNzgsNS4zMWwzMy40MSwzNC44NGMyLjIsMi4yLDIuOTgsMi4yLDUuMTgsMGwzNS40OC0zNy4xN2MxLjU5LTEuMzgsMi4xNi0zLjYsMS40Mi01LjU3LTEuNjgtNi4wOS0zLjI0LTEyLjMtNC43OS0xOC4zOS0uNzQtMi4yNy0xLjIyLTQuNjItMS40Mi02Ljk5LDQuMyw1LjkzLDkuMDcsMTEuNTIsMTQuMjUsMTYuNzEsMS42OCwxLjY4LDIuNzIsMS42OCw0LjQsMGwzNC4zMi0zNS43NHExLjU1LTEuODEsMC00LjAxWm0tNzIuMjYsMTUuMTVjLTMuMTEtLjc4LTYuMDktMS41NS05LjE5LTIuNTktMS43OC0uMzQtMy42MSwuMy00Ljc5LDEuNjhsLTEyLjk1LDEzLjg2Yy0uNzYsLjg1LTEuNDUsMS43Ni0yLjA3LDIuNzJoLS42NWMxLjMtNS4zMSwyLjcyLTEwLjYyLDQuMDEtMTUuOGwxLjY4LTYuNzNjLjg0LTIuMTgsLjE1LTQuNjUtMS42OC02LjA5bC0xMi45NS0xNC4xMmMtLjY0LS40NS0xLjE0LTEuMDgtMS40Mi0xLjgxbDE5LjA0LDUuMTgsMi41OSwuNzhjMi4wNCwuNzYsNC4zMywuMTQsNS43LTEuNTVsMTIuOTUtMTQuMzhzLjc4LTEuMDQsMS42OC0xLjE3Yy0xLjgxLDYuNi0yLjk4LDE0LjEyLTUuNDQsMjAuNDYtMS4wOCwyLjk2LS4wOCw2LjI4LDIuNDYsOC4xNiw0LjI3LDQuMTQsOC4yOSw4LjU1LDEyLjk1LDEyLjk1LDAsMCwxLjMsLjkxLDEuNDIsMi4wN2wtMTMuMzQtMy42M1oiLz48L3N2Zz4=)](https://github.com/keep-starknet-strange) + +
+ +## Overview + +Starknet Core Contract components in Cairo. + +## Build + +To build the project, run: + +```bash +scarb build +``` + +## Test + +To test the project, run: + +```bash +snforge test +``` diff --git a/Scarb.lock b/Scarb.lock new file mode 100644 index 0000000..51471f5 --- /dev/null +++ b/Scarb.lock @@ -0,0 +1,14 @@ +# Code generated by scarb DO NOT EDIT. +version = 1 + +[[package]] +name = "piltover" +version = "0.1.0" +dependencies = [ + "snforge_std", +] + +[[package]] +name = "snforge_std" +version = "0.16.0" +source = "git+https://github.com/foundry-rs/starknet-foundry?tag=v0.16.0#f58e0ab42b6095b7d0cb841ede595aecbc9cb45d" diff --git a/Scarb.toml b/Scarb.toml new file mode 100644 index 0000000..a4a5e93 --- /dev/null +++ b/Scarb.toml @@ -0,0 +1,11 @@ +[package] +name = "piltover" +version = "0.1.0" +edition = "2023_10" + +[dependencies] +snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry", tag = "v0.16.0" } +starknet = "2.4.4" + +[[target.starknet-contract]] +casm = true diff --git a/book/src/assets/piltover.png b/book/src/assets/piltover.png new file mode 100644 index 0000000000000000000000000000000000000000..5e1918ff7b42a4e8e8271544a2509bb4bc0362d3 GIT binary patch literal 33091 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 literal 0 HcmV?d00001 diff --git a/src/lib.cairo b/src/lib.cairo new file mode 100644 index 0000000..1f94d45 --- /dev/null +++ b/src/lib.cairo @@ -0,0 +1,25 @@ +#[starknet::interface] +trait IHelloStarknet { + fn increase_balance(ref self: TContractState, amount: felt252); + fn get_balance(self: @TContractState) -> felt252; +} + +#[starknet::contract] +mod HelloStarknet { + #[storage] + struct Storage { + balance: felt252, + } + + #[abi(embed_v0)] + impl HelloStarknetImpl of super::IHelloStarknet { + fn increase_balance(ref self: ContractState, amount: felt252) { + assert(amount != 0, 'Amount cannot be 0'); + self.balance.write(self.balance.read() + amount); + } + + fn get_balance(self: @ContractState) -> felt252 { + self.balance.read() + } + } +} diff --git a/tests/test_contract.cairo b/tests/test_contract.cairo new file mode 100644 index 0000000..e13999a --- /dev/null +++ b/tests/test_contract.cairo @@ -0,0 +1,45 @@ +use starknet::ContractAddress; + +use snforge_std::{declare, ContractClassTrait}; + +use piltover::IHelloStarknetSafeDispatcher; +use piltover::IHelloStarknetSafeDispatcherTrait; +use piltover::IHelloStarknetDispatcher; +use piltover::IHelloStarknetDispatcherTrait; + +fn deploy_contract(name: felt252) -> ContractAddress { + let contract = declare(name); + contract.deploy(@ArrayTrait::new()).unwrap() +} + +#[test] +fn test_increase_balance() { + let contract_address = deploy_contract('HelloStarknet'); + + let dispatcher = IHelloStarknetDispatcher { contract_address }; + + let balance_before = dispatcher.get_balance(); + assert(balance_before == 0, 'Invalid balance'); + + dispatcher.increase_balance(42); + + let balance_after = dispatcher.get_balance(); + assert(balance_after == 42, 'Invalid balance'); +} + +#[test] +fn test_cannot_increase_balance_with_zero_value() { + let contract_address = deploy_contract('HelloStarknet'); + + let safe_dispatcher = IHelloStarknetSafeDispatcher { contract_address }; + + let balance_before = safe_dispatcher.get_balance().unwrap(); + assert(balance_before == 0, 'Invalid balance'); + + match safe_dispatcher.increase_balance(0) { + Result::Ok(_) => panic_with_felt252('Should have panicked'), + Result::Err(panic_data) => { + assert(*panic_data.at(0) == 'Amount cannot be 0', *panic_data.at(0)); + } + }; +}