-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
1.0.2: USN contract released on the NEAR mainnet.
- Loading branch information
Usn Zorro
committed
Apr 25, 2022
0 parents
commit 5b660dc
Showing
39 changed files
with
5,015 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
[build] | ||
rustflags = ["-C", "link-args=-s"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
name: Publish release | ||
|
||
on: | ||
create: | ||
tags: | ||
- v* | ||
|
||
jobs: | ||
test: | ||
uses: ./.github/workflows/test.yaml | ||
|
||
release: | ||
needs: test | ||
|
||
runs-on: ubuntu-latest | ||
|
||
container: | ||
image: nearprotocol/contract-builder | ||
options: --cap-add=SYS_PTRACE --security-opt seccomp=unconfined | ||
env: | ||
RUSTFLAGS: -C link-arg=-s | ||
|
||
steps: | ||
- uses: actions/checkout@v2 | ||
- name: Build | ||
run: | | ||
rustup toolchain install stable | ||
rustup default stable | ||
rustup target add wasm32-unknown-unknown | ||
cargo build --target wasm32-unknown-unknown --profile testnet --features testnet | ||
cargo build --target wasm32-unknown-unknown --profile mainnet --features mainnet | ||
mv target/wasm32-unknown-unknown/mainnet/usn.wasm target/usn.mainnet.wasm | ||
mv target/wasm32-unknown-unknown/testnet/usn.wasm target/usn.testnet.wasm | ||
- name: Publish | ||
uses: ncipollo/release-action@v1 | ||
with: | ||
artifacts: "target/usn.*.wasm" | ||
token: ${{ secrets.GITHUB_TOKEN }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
name: Run tests | ||
|
||
on: | ||
workflow_call: | ||
|
||
push: | ||
branches: | ||
- main | ||
|
||
pull_request: | ||
branches: | ||
- main | ||
|
||
jobs: | ||
test: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- name: Run Rustfmt | ||
run: cargo fmt -- --check | ||
- name: Run unit tests | ||
run: cargo test --verbose | ||
- name: Install NPM dependencies | ||
run: npm install | ||
- name: Build USN | ||
run: npm run build | ||
- name: Run integration tests on sandbox | ||
run: npm run test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
target/* | ||
node_modules/* | ||
package-lock.json | ||
*.lock | ||
*.iml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
[package] | ||
edition = "2018" | ||
name = "usn" | ||
version = "1.0.2" | ||
|
||
[lib] | ||
crate-type = ["cdylib", "rlib"] | ||
|
||
[dependencies] | ||
near-contract-standards = "=4.0.0-pre.7" | ||
near-sdk = { version = "=4.0.0-pre.7", features = ["unstable"] } | ||
uint = { version = "=0.9.0", default-features = false } | ||
partial-min-max = "0.4.0" | ||
easy-ml = "1.8.1" | ||
|
||
[profile.release] | ||
codegen-units = 1 | ||
debug = false | ||
lto = true | ||
opt-level = "s" | ||
overflow-checks = true | ||
panic = "abort" | ||
|
||
[profile.sandbox] | ||
inherits = "release" | ||
|
||
[profile.testnet] | ||
inherits = "release" | ||
|
||
[profile.mainnet] | ||
inherits = "release" | ||
|
||
[features] | ||
# Enables testnet configuration if expicitly stated. | ||
# It makes the USN contract use a testnet oracle. | ||
testnet = [] | ||
|
||
# Enables mainnet configuration if expicitly stated. | ||
# It makes the USN contract use a main oracle. | ||
mainnet = [] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,230 @@ | ||
[![USN](https://github.com/binary-star-near/usn/actions/workflows/test.yaml/badge.svg?event=push)](https://github.com/binary-star-near/usn) | ||
|
||
# USN | ||
|
||
USN is a NEAR-native USD stable coin. | ||
|
||
The contract implements fungible token API according to the following standards: | ||
|
||
1. [NEP-141](https://nomicon.io/Standards/FungibleToken/Core) (ERC-20 fashioned) | ||
2. [NEP-148](https://nomicon.io/Standards/FungibleToken/Metadata) | ||
3. [Fungible Token Event](https://nomicon.io/Standards/FungibleToken/Event) | ||
|
||
The specific part of the USN contract is `buy`/`sell` methods of NEAR/USD exchange with rates taken from the oracle ([priceoracle](https://github.com/NearDeFi/price-oracle/)). | ||
|
||
# Contract Address | ||
|
||
| Mainnet | Testnet | | ||
| ------- | ------------ | | ||
| usn | usdn.testnet | | ||
|
||
# How It Works | ||
|
||
## Buy USN for NEAR | ||
|
||
_Method:_ `buy` | ||
|
||
<img alt="Buy USN" src="images/buy.svg" /> | ||
|
||
## Sell USN for NEAR with `sell` API | ||
|
||
_Method:_ `sell` | ||
|
||
<img alt="Sell USN" src="images/sell.svg" /> | ||
|
||
## Slippage | ||
|
||
Methods `buy` and `sell` requires the _expected_ exchange rate to avoid slippage. If the price suddenly changes (slips) out of the expected deviation the USN contract aborts the transaction. | ||
|
||
# Build | ||
|
||
First, install prerequisites: | ||
|
||
```bash | ||
npm install | ||
``` | ||
|
||
Then, build. | ||
|
||
For local sandbox: | ||
|
||
```bash | ||
npm run build | ||
``` | ||
|
||
For testnet: | ||
|
||
```bash | ||
npm run build:testnet | ||
``` | ||
|
||
For mainnet: | ||
|
||
```bash | ||
npm run build:mainnet | ||
``` | ||
|
||
**WARNING**: There is a difference in each target. The crucial difference is that they communicate with different oracle addresses: | ||
|
||
- Mainnet: `priceoracle.near` | ||
- Testnet: `priceoracle.testnet` | ||
- Sandbox: `priceoracle.test.near` | ||
|
||
And all these oracle contracts report prices with different asset names. | ||
|
||
# Test | ||
|
||
## Run unit tests | ||
|
||
```bash | ||
cargo test | ||
``` | ||
|
||
## Run integration tests | ||
|
||
```bash | ||
npm run build | ||
npm run deploy | ||
npm run test | ||
``` | ||
|
||
## Manual testing on the Testnet | ||
|
||
Build | ||
|
||
```bash | ||
npm run build:testnet | ||
``` | ||
|
||
Deploy | ||
|
||
```bash | ||
near deploy --force --wasmFile target/wasm32-unknown-unknown/testnet/usn.wasm --accountId=usdn.testnet --masterAccount=usdn.testnet | ||
``` | ||
|
||
Init once | ||
|
||
```bash | ||
near call usdn.testnet new --args '{"owner_id": "usdn.testnet"}' --accountId=usdn.testnet | ||
``` | ||
|
||
Add a guardian | ||
|
||
```bash | ||
near call usdn.testnet extend_guardians --accountId usdn.testnet --args '{"guardians": ["alice.testnet"]}' | ||
``` | ||
|
||
Buy and sell | ||
|
||
```bash | ||
# Send NEAR, buy USN. | ||
near call usdn.testnet buy --accountId alice.testnet --amount 1 --gas 50000000000000 | ||
|
||
# Check USN balance. | ||
near call usdn.testnet ft_balance_of --accountId alice.testnet --args '{"account_id": "alice.testnet"}' | ||
|
||
# Sell USN, receive NEAR. | ||
near call usdn.testnet sell --accountId alice.testnet --args '{"amount": "118800"}' --amount 0.000000000000000000000001 --gas 50000000000000 | ||
|
||
# Buy USN with slippage control | ||
near call usdn.testnet buy --args '{"expected": {"multiplier": "111439", "slippage": "10", "decimals": "28" }}' --accountId alice.testnet --amount 1 --gas 50000000000000 | ||
|
||
# Buy USN and transfer to someone. | ||
near call usdn.testnet buy --args '{"to": "bob.testnet"}' --accountId alice.testnet --amount 1 --gas 50000000000000 | ||
``` | ||
|
||
# DAO | ||
|
||
## Upgrade the contract via Upgrade Proposal | ||
|
||
1. Download `usn.mainnet.wasm` from https://github.com/binary-star-near/usn/releases | ||
2. Create an upgrade proposal: | ||
```bash | ||
sputnikdao proposal upgrade usn.mainnet.wasm usn --daoAcc usn --accountId alice.near --network mainnet | ||
``` | ||
|
||
# API | ||
|
||
## Buy/sell USN | ||
|
||
Send NEAR, receive USN. | ||
|
||
```rust | ||
pub fn buy(&mut self, expected: Option<ExpectedRate>, to: Option<AccountId>); | ||
``` | ||
|
||
Send USN, receive NEAR. | ||
|
||
```rust | ||
pub fn sell(&mut self, amount: U128, expected: Option<ExpectedRate>) -> Promise; | ||
``` | ||
|
||
## View methods | ||
|
||
```rust | ||
pub fn contract_status(&self) -> ContractStatus; | ||
pub fn name(&self) -> String; | ||
pub fn symbol(&self) -> String; | ||
pub fn decimals(&self) -> u8; | ||
pub fn spread(&self, amount: Option<U128>) -> U128; | ||
pub fn version(&self) -> String; | ||
pub fn blacklist_status(&self, account_id: &AccountId) -> BlackListStatus; | ||
pub fn owner(&self); | ||
``` | ||
|
||
## NEP-141 (ERC-20) | ||
|
||
```rust | ||
pub fn ft_transfer(&mut self, receiver_id: AccountId, amount: U128, memo: Option<String>); | ||
pub fn ft_transfer_call( | ||
&mut self, | ||
receiver_id: AccountId, | ||
amount: U128, | ||
memo: Option<String>, | ||
msg: String, | ||
) -> PromiseOrValue<U128>; | ||
pub fn ft_total_supply(&self) -> U128; | ||
pub fn ft_balance_of(&self, account_id: AccountId) -> U128; | ||
pub fn ft_metadata(&self) -> FungibleTokenMetadata; | ||
``` | ||
|
||
## NEP-145: partial storage API | ||
|
||
Always returns 125 milliNEAR indicating that user doesn't need to be registered | ||
with `storage_deposit`. | ||
|
||
```rust | ||
pub fn storage_balance_of(&self, account_id: AccountId) -> Option<StorageBalance>; | ||
``` | ||
|
||
## Constructor | ||
|
||
```rust | ||
pub fn new(owner_id: AccountId) -> Self; | ||
``` | ||
|
||
## Private setters | ||
|
||
For owner only. | ||
|
||
```rust | ||
pub fn upgrade_name_symbol(&mut self, name: String, symbol: String); | ||
pub fn upgrade_icon(&mut self, data: String); | ||
pub fn add_to_blacklist(&mut self, account_id: &AccountId); | ||
pub fn remove_from_blacklist(&mut self, account_id: &AccountId); | ||
pub fn destroy_black_funds(&mut self, account_id: &AccountId); | ||
pub fn pause(&mut self); | ||
pub fn resume(&mut self); | ||
pub fn set_fixed_spread(&mut self, spread: U128) { | ||
pub fn set_adaptive_spread(&mut self, params: Option<ExponentialSpreadParams>); | ||
pub fn set_owner(&mut self, owner_id: AccountId); | ||
pub fn extend_guardians(&mut self, guardians: Vec<AccountId>); | ||
pub fn remove_guardians(&mut self, guardians: Vec<AccountId>); | ||
``` | ||
|
||
## Upgradability | ||
|
||
```rust | ||
pub fn upgrade(); | ||
pub fn migrate() -> Self; | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
@startuml | ||
|
||
title Buy USN | ||
|
||
alice -> usn: send NEAR\n+ expected rate\n+ slippage\n+ transfer to | ||
|
||
usn -> priceoracle: ""get_price_data"" | ||
activate priceoracle | ||
usn <- priceoracle: NEAR/USDT rate | ||
deactivate priceoracle | ||
usn -> usn: verify timestamp | ||
|
||
alt if expected rate and slippage is passed | ||
usn -> usn: assert slippage | ||
end | ||
|
||
usn -> usn: mint USN | ||
|
||
alice <-- usn: USN amount | ||
alt If "transfer to" is defined | ||
bob <-- usn: USN amount | ||
end | ||
@enduml |
Oops, something went wrong.