Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
sgc-code committed Jun 5, 2024
1 parent c670a40 commit 6c0056d
Show file tree
Hide file tree
Showing 60 changed files with 6,613 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
RPC_URL=http://127.0.0.1:5050
ADDRESS=0x000000000000000000000000000000000000000000000000000000000000000
PRIVATE_KEY=0x000000000000000000000000000000000000000000000000000000000000000
12 changes: 12 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"extends": ["plugin:@typescript-eslint/recommended"],
"env": {
"node": true
},
"ignorePatterns": ["dist", "cairo"]
}
26 changes: 26 additions & 0 deletions .github/workflows/cairo-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Cairo CI

on: push

jobs:
tests:
runs-on: ubuntu-latest
steps:
- name: Step 1 - Check out main branch
uses: actions/checkout@v3
- name: Step 2 - Getting scarb
uses: software-mansion/[email protected]
- name: Step 3 - Setting up snfoundry
uses: foundry-rs/setup-snfoundry@v3
- name: Step 4 - Running tests
run: scarb test

format:
runs-on: ubuntu-latest
steps:
- name: Step 1 - Check out main branch
uses: actions/checkout@v3
- name: Step 2 - Getting scarb
uses: software-mansion/[email protected]
- name: Step 3 - Checking format
run: scarb fmt --check
46 changes: 46 additions & 0 deletions .github/workflows/integration-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Integration CI

on: push

jobs:
integration-tests:
runs-on: ubuntu-latest
steps:
- name: Check out main branch
uses: actions/checkout@v3

- name: Setup Scarb
uses: software-mansion/[email protected]

- name: Install project
run: yarn install --frozen-lockfile

- name: Start devnet in background
run: scarb run start-devnet

- name: Run integration tests
run: scarb --release build && tsc && yarn mocha tests-integration/*.test.ts --forbid-only --forbid-pending

format:
runs-on: ubuntu-latest
steps:
- name: Step 1 - Check out main branch
uses: actions/checkout@v3

- name: Step 2 - Install project
run: yarn install --frozen-lockfile

- name: Step 3 - Check correct formatting
run: yarn prettier --check .

lint:
runs-on: ubuntu-latest
steps:
- name: Step 1 - Check out main branch
uses: actions/checkout@v3

- name: Step 2 - Install project
run: yarn install --frozen-lockfile

- name: Step 3 - Check correct linting
run: yarn eslint .
45 changes: 45 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Logs
logs
*.log
npm-debug.log*

# Runtime data
pids
*.pid
*.seed

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules
jspm_packages

# Optional npm cache directory
.npm

# Optional REPL history
.node_repl_history
.next

# Cairo
target
.snfoundry_cache/

.env
dist
7 changes: 7 additions & 0 deletions .mocharc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extensions": ["ts"],
"test": ["tests/**.ts"],
"node-option": ["loader=ts-node/esm"],
"slow": 5000,
"timeout": 300000
}
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
18
8 changes: 8 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
cairo
venv
target
deployments/artifacts
dist
.github
tests-integration/fixtures
starknet-devnet-rs
9 changes: 9 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"arrowParens": "always",
"useTabs": false,
"trailingComma": "all",
"singleQuote": false,
"semi": true,
"printWidth": 120,
"plugins": ["prettier-plugin-organize-imports"]
}
2 changes: 2 additions & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
scarb 2.6.3
starknet-foundry 0.24.0
8 changes: 8 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Use the base image
FROM shardlabs/starknet-devnet-rs:c4185522228f61ba04619151eb5706d4610fb00f

# Expose port 5050
EXPOSE 5050

# Set default command to run the container
CMD ["--gas-price", "36000000000", "--data-gas-price", "1", "--timeout", "320", "--seed", "0"]
53 changes: 53 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// TODO This is outdated

# Starknet Gifting

The protocol implemented in this repository can be used for gifting tokens to a recipient without giving custody of the tokens to a third party. But it can also be used to transfer tokens to a repicient identified by an email or a phone number. Both products are supported by the same smart-contract and depends solely on the client being built on top.

## High level Flow

- The sender creates a key pair `claim_key` locally and deposits the tokens to transfer to the escrow account together with a small amount of fee token (ETH or STRK) to cover the claim. He provides the public key `claim_key.pub` as an identifier for the transfer.
- The sender shares the private key `claim_key.priv` with the recipient over an external channel such as email or phone.
- The recipient claims the tokens by transferring them from the escrow to an account he controls using `claim_key.priv` to sign the transaction.

## Fee

Because the escrow is an account, it can pay for its own transactions and the recipient doesn't need to have funds to initiate the claim. This makes it great to onboard new users that can claim a gift to a newly created and undeployed account.

The Escrow contract can operate in 2 modes depending on the value of the `use_fee` flag.

When `use_fee = false` the sender doesn't need to cover the fee for the claim because the operator of the escrow sponsors the transfers by depositing sufficient ETH or STRK on the escrow contract.

When `use_fee = true` the fee of the claim must be covered by the sender, and he is required to deposit some ETH or STRK together with the token being gifted. The amount of fee token he provides must be sufficient to cover the claim. The recipient of the claim can use up to that value as specified in the max fee of the claim transaction.

If the max fee of the claim transaction is less than the max fee allocated to the claim, the difference is added to a counter and can be later retrieved by the operator of the escrow contract as a paiement for his operation of the protocol. However, the difference between the max fee of the claim transaction and the actual fee of the transaction cannot be acounted for in the contract and will be stuck. We can imagine using that dust later by setting `use_fee = true` and sponsoring gifts for a limited period.

## Canceling Gifts

Gifts can be canceled by the sender provided that they have not been claimed yet. If the gift covers the claim fee the sender can recover both the gift and the claim fee he provided.

In the unlikely event that the recipient tried to claim a gift but the transaction failed in execution, some of the claim fee will have been used. The gift can no longer be claimed but can be canceled by the sender. Canceling the gift will only recover the gift but not the remaining claim fee.

## Development

### asdf

Install asdf following [instructions](https://asdf-vm.com/guide/getting-started.html) and run this

```
asdf plugin add scarb
asdf plugin add starknet-foundry
asdf install
```

### Setup scarb and foundry

Thanks to the [.tool-versions file](./.tool-versions), you don't need to install a specific scarb or starknet foundry version. The correct one will be automatically downloaded and installed.

### Build the contracts

`scarb build`

### Test the contracts

`snforge test`
54 changes: 54 additions & 0 deletions Scarb.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Code generated by scarb DO NOT EDIT.
version = 1

[[package]]
name = "alexandria_data_structures"
version = "0.2.0"
source = "git+https://github.com/keep-starknet-strange/alexandria.git?rev=cairo-v2.6.0#946e6e2f9d390ad9f345882a352c0dd6f02ef3ad"
dependencies = [
"alexandria_encoding",
]

[[package]]
name = "alexandria_encoding"
version = "0.1.0"
source = "git+https://github.com/keep-starknet-strange/alexandria.git?rev=cairo-v2.6.0#946e6e2f9d390ad9f345882a352c0dd6f02ef3ad"
dependencies = [
"alexandria_math",
"alexandria_numeric",
]

[[package]]
name = "alexandria_math"
version = "0.2.0"
source = "git+https://github.com/keep-starknet-strange/alexandria.git?rev=cairo-v2.6.0#946e6e2f9d390ad9f345882a352c0dd6f02ef3ad"
dependencies = [
"alexandria_data_structures",
]

[[package]]
name = "alexandria_numeric"
version = "0.1.0"
source = "git+https://github.com/keep-starknet-strange/alexandria.git?rev=cairo-v2.6.0#946e6e2f9d390ad9f345882a352c0dd6f02ef3ad"
dependencies = [
"alexandria_math",
]

[[package]]
name = "openzeppelin"
version = "0.13.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.13.0#978b4e75209da355667d8954d2450e32bd71fe49"

[[package]]
name = "snforge_std"
version = "0.24.0"
source = "git+https://github.com/foundry-rs/starknet-foundry?tag=v0.24.0#95e9fb09cb91b3c05295915179ee1b55bf923653"

[[package]]
name = "starknet_gifting"
version = "0.1.0"
dependencies = [
"alexandria_math",
"openzeppelin",
"snforge_std",
]
27 changes: 27 additions & 0 deletions Scarb.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[package]
name = "starknet_gifting"
version = "0.1.0"
edition = "2023_10"


[dependencies]
starknet = "2.6.3"
snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry", tag = "v0.24.0" }
openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", tag = "v0.13.0" }
alexandria_math = { git = "https://github.com/keep-starknet-strange/alexandria.git", rev = "cairo-v2.6.0" }

[[target.starknet-contract]]
sierra = true
casm = true

[tool.fmt]
max-line-length = 120
sort-module-level-items = true

[scripts]
test = "snforge test"
start-devnet = "docker build -t devnet . && docker run -d -p 127.0.0.1:5050:5050 devnet"
kill-devnet = "docker ps -q --filter 'ancestor=devnet' | xargs docker stop"
test-ts = "scarb --profile release build && yarn tsc && yarn mocha tests-integration/*.test.ts"
profile = "scarb --profile release build && node --loader ts-node/esm scripts/profile.ts"
format = "scarb fmt && yarn prettier --write ."
4 changes: 4 additions & 0 deletions deployments.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
## Sepolia

classhash: 0x5908a9e0785fe551d52413f2289c5c1436a8a7086d569829d0ff10443bf790
Escrow: 0x1748e6a718e66dd6602be9424fc206988cf8ff807d0a5922bbc2ad4253a2a2f
18 changes: 18 additions & 0 deletions gas-report.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Summary:
┌───────────────────────┬─────────────────────┬─────────┬────────────────┬────────────────┬─────────────────┬───────────┬──────────────┬──────────────────────────────┬───────────────┬────────┬─────────┐
│ (index) │ Actual fee │ Fee usd │ Fee without DA │ Gas without DA │ Computation gas │ Event gas │ Calldata gas │ Max computation per Category │ Storage diffs │ DA fee │ DA mode │
├───────────────────────┼─────────────────────┼─────────┼────────────────┼────────────────┼─────────────────┼───────────┼──────────────┼──────────────────────────────┼───────────────┼────────┼─────────┤
│ Deposit (txV3: false) │ '1.152.000.000.352' │ 0.0046 │ 1152000000000 │ 32 │ 31 │ 4 │ 1 │ 'steps' │ 4 │ 352 │ 'BLOB' │
│ Claim (txV3: false) │ '1.260.000.000.192' │ 0.005 │ 1260000000000 │ 35 │ 34 │ 2 │ 1 │ 'steps' │ 3 │ 192 │ 'BLOB' │
│ Deposit (txV3: true) │ '1.152.000.000.480' │ 0.0046 │ 1152000000000 │ 32 │ 31 │ 4 │ 1 │ 'steps' │ 5 │ 480 │ 'BLOB' │
│ Claim (txV3: true) │ '1.260.000.000.192' │ 0 │ 1260000000000 │ 35 │ 34 │ 2 │ 1 │ 'steps' │ 3 │ 192 │ 'BLOB' │
└───────────────────────┴─────────────────────┴─────────┴────────────────┴────────────────┴─────────────────┴───────────┴──────────────┴──────────────────────────────┴───────────────┴────────┴─────────┘
Resources:
┌───────────────────────┬─────────┬───────┬───────┬────────┬──────────┬──────────┬─────────────┬───────┐
│ (index) │ bitwise │ ec_op │ ecdsa │ keccak │ pedersen │ poseidon │ range_check │ steps │
├───────────────────────┼─────────┼───────┼───────┼────────┼──────────┼──────────┼─────────────┼───────┤
│ Deposit (txV3: false) │ 0 │ 3 │ 0 │ 0 │ 38 │ 0 │ 277 │ 12098 │
│ Claim (txV3: false) │ 0 │ 3 │ 0 │ 0 │ 71 │ 0 │ 456 │ 13231 │
│ Deposit (txV3: true) │ 0 │ 3 │ 0 │ 0 │ 38 │ 0 │ 277 │ 12099 │
│ Claim (txV3: true) │ 0 │ 3 │ 0 │ 0 │ 71 │ 0 │ 490 │ 13429 │
└───────────────────────┴─────────┴───────┴───────┴────────┴──────────┴──────────┴─────────────┴───────┘
Loading

0 comments on commit 6c0056d

Please sign in to comment.