Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
xJonathanLEI committed Mar 7, 2024
1 parent cfc7628 commit d5bbb2b
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/build/
/cache/
/out/
65 changes: 64 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,74 @@

**ZEND token implementation**

## L1 token

The [L1 token contract](./l1/ZendToken.sol) is a simple child contract of the OpenZeppelin reference ERC20 implementation.

### Prerequisites

Install [Foundry](https://github.com/foundry-rs/foundry) for Solidity compilation. Check your Foundry installation with:

```console
forge --version
```

### Building

To build the contract simply run:

```console
forge build
```

Built artifacts will be available in the `./out` folder.

## L2 token

The L2 token contract is _not_ manually deployed. Instead, it's automatically deployed by the [L2 token bridge contract](https://github.com/starknet-io/starkgate-contracts/blob/d62a255307d2f3de65665f18316766a2c69ead78/src/cairo/token_bridge.cairo) when a [permissionless token enrollment](https://docs.starknet.io/documentation/tools/starkgate-adding_a_token/) is triggered on the [L1 token bridge manager contract](https://github.com/starknet-io/starkgate-contracts/blob/d62a255307d2f3de65665f18316766a2c69ead78/src/solidity/StarkgateManager.sol). Therefore, the L2 token contract code to be deployed is completely up to the official StarkGate configuration. Any L2 token contract instance deployed this way is mintable only from the bridge contract.

> [!NOTE]
>
> As of this writing, the L2 token _class hash_ deployed by StarkGate is [`0x05ffbcfeb50d200a0677c48a129a11245a3fc519d1d98d76882d1c9a1b19c6ed`](https://starkscan.co/class/0x05ffbcfeb50d200a0677c48a129a11245a3fc519d1d98d76882d1c9a1b19c6ed).
Despite our lack of control over the implementation, the token contract is still [reproduced here](./l2/openzeppelin/token/erc20_v070/erc20.cairo) (along with dependencies) from its [upstream source](https://github.com/starknet-io/starkgate-contracts/blob/d62a255307d2f3de65665f18316766a2c69ead78/src/openzeppelin/token/erc20_v070/erc20.cairo) for reference.

Additionally, due to the fact that none of the major Starknet block explorers offer Cairo 1 contract verification as of this writing, this repo provides tools for [deterministic compilation](#deterministic-compilation-with-docker) as a means of [verification](#verifying-class-hash).

### Building directly

With the `starknet-compile` command from [starkware-libs/cairo](https://github.com/starkware-libs/cairo) installed, run:

```console
mkdir -p ./build
starknet-compile . -c openzeppelin::token::erc20_v070::erc20::ERC20 ./build/ERC20.json
```

> [!TIP]
>
> You must install versions newer than `v2.3.0` for `starknet-compile` to be able to compile successfully.
The compiled contract is available at `./build/ERC20.json`.

### Deterministic compilation with Docker

To ensure deterministic compilation output, a [script](./scripts/compile_l2_with_docker.sh) is provided that generates the exact same class as the one used in production:

```console
./scripts/compile_l2_with_docker.sh
```

The compiled contract is available at `./build/ERC20.json`.

### Verifying class hash

Either [built directly](#building-directly) or [with Docker](#deterministic-compilation-with-docker), you may verify that the class hash of the compiled contract artifact with the `starkli class-hash` command from [Starkli](https://github.com/xJonathanLEI/starkli).

## License

Licensed under either of

- Apache License, Version 2.0 ([LICENSE-APACHE](./LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0>)
- MIT license ([LICENSE-MIT](./LICENSE-MIT) or <http://opensource.org/licenses/MIT>)

at your option.
at your option, except the content in [`./l2/`](./l2/), which is licensed with its upstream source.
3 changes: 3 additions & 0 deletions cairo_project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[crate_roots]
src = "l2/src"
openzeppelin = "l2/openzeppelin"
29 changes: 29 additions & 0 deletions scripts/compile_l2.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/bin/sh

set -e

SCRIPT_DIR=$( cd -- "$( dirname "$0" )" &> /dev/null && pwd )
REPO_ROOT=$( cd -- "$( dirname $( dirname "$0" ) )" &> /dev/null && pwd )

compile () {
MODULE="$1"
NAME="$2"
OUTPUT="$REPO_ROOT/build/$NAME.json"

echo "Compiling $MODULE::$NAME"

# This is better than using the output option, which does not emit EOL at the end.
starknet-compile -c "$MODULE::$NAME" $REPO_ROOT > $OUTPUT

if [ -n "$USER_ID" ] && [ -n "$GROUP_ID" ]; then
chown $USER_ID:$GROUP_ID $OUTPUT
fi
}

mkdir -p "$REPO_ROOT/build"

compile openzeppelin::token::erc20_v070::erc20 ERC20

if [ -n "$USER_ID" ] && [ -n "$GROUP_ID" ]; then
chown -R $USER_ID:$GROUP_ID "$REPO_ROOT/build"
fi
15 changes: 15 additions & 0 deletions scripts/compile_l2_with_docker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/sh

set -e

SCRIPT_DIR=$( cd -- "$( dirname "$0" )" &> /dev/null && pwd )
REPO_ROOT=$( cd -- "$( dirname $( dirname "$0" ) )" &> /dev/null && pwd )

# Deterministically generate contract artifacts
docker run --rm \
-v "$REPO_ROOT:/work" \
--env "USER_ID=$(id -u)" \
--env "GROUP_ID=$(id -g)" \
--entrypoint sh \
starknet/cairo:2.3.0 \
-c "cd /work && ./scripts/compile_l2.sh"

0 comments on commit d5bbb2b

Please sign in to comment.