Skip to content

Commit

Permalink
Add technical documentation (#22)
Browse files Browse the repository at this point in the history
* Add project structure docs

* Add architecture documentation and quickstart guide

* Rearrange documentation

* Change project structure doc
  • Loading branch information
vasyafromrussia authored Sep 20, 2023
1 parent d8c7ae4 commit a97e4b8
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 117 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ package-lock.json
/contract/target

# misc
dev.env
.DS_Store
.env.local
.env.development.local
Expand Down
118 changes: 39 additions & 79 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,100 +1,60 @@
near-blank-project
==================
# SWEAT DeFi Jar

This app was initialized with [create-near-app]
$SWEAT staking smart contract.

---

Quick Start
===========
## 1. Exploring the project

If you haven't installed dependencies during setup:
Read the [**Project documentation**](docs/requirements.md) page.

npm install
## 2. Quickstart

1. Make sure you have installed [rust](https://rust.org/).
2. Install the [`NEAR CLI`](https://github.com/near/near-cli#setup)

Build and deploy your contract to TestNet with a temporary dev account:
If you already have `rustup` installed, you can ensure that the correct version of the compiler and the NEAR CLI is installed as well:

npm run deploy
```shell
make install
```

Test your contract:
### 2.1. General information

npm test
To learn how to build the project, deploy it, and run tests run the following command:

If you have a frontend, run `npm start`. This will run a dev server.
```shell
make help
```

### 2.2. Build and Deploy the Contract
First build the contract using provided `make` command:

Exploring The Code
==================
```bash
make build
```

1. The smart-contract code lives in the `/contract` folder. See the README there for
more info. In blockchain apps the smart contract is the "backend" of your app.
2. The frontend code lives in the `/frontend` folder. `/frontend/index.html` is a great
place to start exploring. Note that it loads in `/frontend/index.js`,
this is your entrypoint to learn how the frontend connects to the NEAR blockchain.
3. Test your contract: `npm test`, this will run the tests in `integration-tests` directory.
Then deploy and initialize it. Rename `dev.env.example` to `dev.env` and define variable values there. To deploy the contract to dev-account on Testnet use the following command:

```bash
make deploy
```

Deploy
======
Once finished, check the `neardev/dev-account` file to find the address in which the contract was deployed:

Every smart contract in NEAR has its [own associated account][NEAR accounts].
When you run `npm run deploy`, your smart contract gets deployed to the live NEAR TestNet with a temporary dev account.
When you're ready to make it permanent, here's how:
```bash
cat ./neardev/dev-account
# e.g. dev-1659899566943-21539992274727
```

### 2.3. Reproducible build

Step 0: Install near-cli (optional)
-------------------------------------
If you build your contract on two different machines, it's highly likely that you'll obtain two binaries that are
similar but not exactly identical. Your build outcome can be influenced by various factors in your build environment,
such as the locale, timezone, build path, and numerous other variables.

[near-cli] is a command line interface (CLI) for interacting with the NEAR blockchain. It was installed to the local `node_modules` folder when you ran `npm install`, but for best ergonomics you may want to install it globally:
To obtain an identical build artifact on any machine, matching the one deployed on NEAR, you can build it using Docker:

npm install --global near-cli

Or, if you'd rather use the locally-installed version, you can prefix all `near` commands with `npx`

Ensure that it's installed with `near --version` (or `npx near --version`)


Step 1: Create an account for the contract
------------------------------------------

Each account on NEAR can have at most one contract deployed to it. If you've already created an account such as `your-name.testnet`, you can deploy your contract to `near-blank-project.your-name.testnet`. Assuming you've already created an account on [NEAR Wallet], here's how to create `near-blank-project.your-name.testnet`:

1. Authorize NEAR CLI, following the commands it gives you:

near login

2. Create a subaccount (replace `YOUR-NAME` below with your actual account name):

near create-account near-blank-project.YOUR-NAME.testnet --masterAccount YOUR-NAME.testnet

Step 2: deploy the contract
---------------------------

Use the CLI to deploy the contract to TestNet with your account ID.
Replace `PATH_TO_WASM_FILE` with the `wasm` that was generated in `contract` build directory.

near deploy --accountId near-blank-project.YOUR-NAME.testnet --wasmFile PATH_TO_WASM_FILE


Step 3: set contract name in your frontend code
-----------------------------------------------

Modify the line in `src/config.js` that sets the account name of the contract. Set it to the account id you used above.

const CONTRACT_NAME = process.env.CONTRACT_NAME || 'near-blank-project.YOUR-NAME.testnet'



Troubleshooting
===============

On Windows, if you're seeing an error containing `EPERM` it may be related to spaces in your path. Please see [this issue](https://github.com/zkat/npx/issues/209) for more details.


[create-near-app]: https://github.com/near/create-near-app
[Node.js]: https://nodejs.org/en/download/package-manager/
[jest]: https://jestjs.io/
[NEAR accounts]: https://docs.near.org/concepts/basics/account
[NEAR Wallet]: https://wallet.testnet.near.org/
[near-cli]: https://github.com/near/near-cli
[gh-pages]: https://github.com/tschaub/gh-pages
```shell
make build-in-docker
```
34 changes: 0 additions & 34 deletions contract/README.md

This file was deleted.

3 changes: 3 additions & 0 deletions dev.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
TOKEN_ACCOUNT_ID=
ADMIN_ACCOUNT_ID=
FEE_ACCOUNT_ID=
110 changes: 109 additions & 1 deletion docs/requirements.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ The contract allows users to perform the following actions:
- **Restake:** This refers to the act of re-enacting a previous “stake” action under the same terms.
- **Claim:** This is the act of a user requesting the smart contract to release the accrued earnings from applied ERs on all or selected Jars containing funds.

## 1. Functional Requirements
## 1. 🧑‍💼 Functional Requirements

### 1.1. 👤 Roles

Expand Down Expand Up @@ -70,3 +70,111 @@ The DeFi Jars contract provides the following features:
16. User can withdraw any amount of $SWEAT from the principal of a Flexible Jar at any moment. If a Product involves a withdrawal fee, the User pays this fee from the withdrawn principal amount.
17. User can top up the principal of a Flexible Jar or Fixed Jar if the related Fixed Product allows top-ups.
18. User can restake a Fixed Jar after its maturity. On restake, a new Jar is created, and the principal of the original Jar is transferred to the new one.

## 2. 🤖 Technical requirements

DeFi Jar contract is a smart contract for NEAR network. It has been developed with Rust language using
[near-sdk-rs](https://github.com/near/near-sdk-rs).

Integration tests are NEAR Workspaces ([workspaces-rs](https://github.com/near/near-workspaces-rs)) sandbox tests.

The smart contract uses [ed25519-dalek](https://github.com/dalek-cryptography/curve25519-dalek/tree/main/ed25519-dalek) to verify signatures for Premium Products.

### 2.1. 🧬 Project structure

Here is an overview of the project structure:

```bash
.
├── Cargo.toml
├── Makefile
├── README.md
├── contract
├── docs
├── integration-tests
└── scripts
```

`cargo` and `integration-tests` are regular cargo projects with their respective layouts.

Start by reading `README.md` to access comprehensive information about building, testing, and deploying a smart contract.

#### 2.1.1. 🛠️ Tooling

The `Makefile` contains useful commands for building, testing, and deploying the contract.
These commands either operate on `cargo` or run scripts found in the `scripts` directory.
To view all the available commands for `make`, use the following command:

```shell
make help
```

#### 2.1.2. 📦 Artifacts

The `res` directory contains WASM binaries:

- **sweat.wasm**: Assembled FT token contract for testing purposes.
- **sweat_jar.wasm**: The actual version of the DeFi Jar contract.

#### 2.1.2. 💿 Codebase

Under the `./contract` directory, you can locate the smart contract module. Project configuration and dependencies are
found in the `Cargo.toml` file. The lib.rs file contains the contract data structure and initialization code.
Each of the _claim, jar, penalty, product, and withdraw_ modules contains feature-specific code.
These modules consist of the following parts:

- **api.rs** – Describes public methods for the feature.
- **model.rs** – Contains data structures for internal use within the contract.
- **view.rs** – Contains data structures to receive from a client or return to them. These structures reflect structs from model.rs, hiding redundant data and providing more readable or easily parsable types.

Structures and API traits in these files are documented, so you can refer to this documentation.

The `ft_interface.rs` file contains helpers to facilitate interaction with the related FT contract.

The code in `ft_receiver.rs` handles incoming Token transfers. This mechanism is used for Jar creation, top-ups, and migration.

#### 2.1.3. 🧪 Integration tests

The `./integration-tests` directory contains integration tests for the smart contract.
These tests work with both FT and DeFi Jars contracts, covering the following scenarios:

- **happy_flow.rs:** This scenario represents the successful registration of a product, the creation of a Jar, and the accrual of interest.
- **migration.rs:** These tests focus on the batched migration of CeFi $SWEAT Jars to the contract.
- **withdraw_fee.rs:** These tests deal with withdrawing Jars with fees, checking for the correct transfer of principal to a user account and fees account.

In addition to these files, it also contains utilities and testing data, with the most significant being:

- **context.rs:** This provides context for a test suite, loading artifacts, granting access to smart contract interfaces, and enabling time travel.
- **ft_contract_interface.rs:** This offers an interface for the FT Contract API.
- **jar_contract_interface.rs:** This provides an interface for the DeFi Jar Contract API.

## 2.2. 📐 Architecture overview

### 2.2.1. 🎭 Actors

The contract involves the participation of the following entities:

- **DeFi Jar Contract:** This contract handles $SWEAT deposits (Jars) and manages their operations.
- **NEP-141 Fungible Token Contract** ($SWEAT Token contract): This contract facilitates token transfers and is responsible for triggering the execution of the DeFi Jar Contract's logic when it receives tokens.
- **Oracle**: This third-party entity possesses additional information about Contract users. In the context of the Contract, the Oracle's role is to validate that users have the authorization to create Jars, and to generate Signatures for them.
- **Consumer** (NEAR Indexer): The Consumer observes events emitted by the **DeFi Jar Contract**. It maintains a connection between users' on-chain data and their data in third-party services.

Refer to the following chart for a detailed overview of the entities involved within the system during the Staking process.

![staking architecture](staking_architecture.png)

### 2.2.2. 🔐 Security

To prevent data tampering and unauthorized access to Products, an [Ed25519 signature system](https://ed25519.cr.yp.to/)
is utilized. When authorization checks are necessary to create Jars for a Product, the Product must include
a verifying (public) key. In this scenario:

- An Oracle generates a keypair and securely stores the private key.
- Subsequently, the Oracle provides the public key to an Admin, who then uses this public key to create a Product.
- In case the private key is compromised, the Oracle has the ability to generate a new keypair, and the Admin can update the public key associated with a Product.

To perform a sensitive operation (currently limited to Jar creation), a User must obtain a signature from the Oracle.
This signature must be included along with other required arguments. The Contract then composes a message identical
to the one signed by the Oracle, incorporating the provided arguments and contextual data.
Subsequently, the Contract verifies this message against the Signature, using the Product's public key, to ensure
the prevention of tampering.
Binary file added docs/staking_architecture.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 4 additions & 3 deletions scripts/deploy.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#!/bin/sh

./build.sh
source dev.env

make build

if [ $? -ne 0 ]; then
echo ">> Error building contract"
Expand All @@ -9,5 +11,4 @@ fi

echo ">> Deploying contract"

# https://docs.near.org/tools/near-cli#near-dev-deploy
near dev-deploy --wasmFile ./target/wasm32-unknown-unknown/release/sweat_jar.wasm
near dev-deploy --wasmFile "res/sweat_jar.wasm" --initFunction "init" --initArgs "{\"token_account_id\": \"$TOKEN_ACCOUNT_ID\", \"manager\": \"$ADMIN_ACCOUNT_ID\", \"fee_account_id\": \"$FEE_ACCOUNT_ID\"}"

0 comments on commit a97e4b8

Please sign in to comment.