Skip to content

Commit

Permalink
Adding exchange deposit receiver
Browse files Browse the repository at this point in the history
  • Loading branch information
Evgeny Kuzyakov committed Aug 20, 2020
1 parent b0b851c commit 322587d
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 1 deletion.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- [Whitelist Contract](./whitelist/)
- [Staking Pool Factory](./staking-pool-factory/)
- [Multisig contract](./multisig/)
- [Exchange Deposit Receiver](./exchange-deposit-receiver)

**Note**: observe the usage of the file `rust-toolchain` in the project root. This file contains toolchain information for nightly, while the `build.sh` scripts in respective contract subdirectories may override this with `cargo +stable`. Refer to the documentation on [the toolchain file and override precedence](https://github.com/rust-lang/rustup#the-toolchain-file). Keep in mind that the build scripts may use `stable` while `cargo test` may use nightly.

Expand Down Expand Up @@ -65,7 +66,7 @@ const result = account.signAndSendTransaction(
contractName,
[
nearAPI.transactions.createAccount(),
nearAPI.transactions.transfer("100000000000000000000000000"),
nearAPI.transactions.transfer("100000000000000000000000000"),
nearAPI.transactions.deployContract(fs.readFileSync("res/lockup_contract.wasm")),
nearAPI.transactions.functionCall("new", Buffer.from(JSON.stringify(newArgs)), 100000000000000, "0"),
]);
Expand Down
5 changes: 5 additions & 0 deletions exchange-deposit-receiver/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions exchange-deposit-receiver/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "exchange-deposit-receiver"
version = "0.1.0"
authors = ["Near Inc <hello@near.org>"]
edition = "2018"
publish = false

[lib]
crate-type = ["cdylib", "rlib"]

[profile.release]
codegen-units = 1
# Tell `rustc` to optimize for small code size.
opt-level = "s"
lto = true
debug = false
panic = "abort"
54 changes: 54 additions & 0 deletions exchange-deposit-receiver/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Exchange deposit receiver

## Background

Exchanges usually creates an new account for a user to deposit their tokens. On NEAR, the account can't be created
without a deposit to cover the occupied storage. It cost tokens on exchange side to create such account before the user
can deposit tokens. So if the user doesn't deposit tokens to the account, the exchange spent tokens on the creation of
the account.

To avoid creating the account before any tokens from the user are received, the exchanges can also receive tokens
directly into their hot wallet, but every deposit has to be marked to be able to properly attribute it to the owner.
It's usually done with an additional `memo` field in the transaction. NEAR doesn't support comments on the transfers.
But NEAR does have function calls and the ability to attach tokens with the function call.

## Overview

The goal of this contract is to provide a contract endpoint to be able to deposit tokens with a memo.

### The process is the following:
- An exchange deploys this contract on their hot wallet account. The exchange also maintains the full access to this account by
having a full access key on this account. It allows exchange to withdraw tokens from this account.
- When a user wants to deposit tokens to their account on the exchange, the exchange generates a unique `<MEMO>` message for
a user.
- The user sends a specific transaction to the exchange's hot wallet account with a single action.
This action should be supported by the wallets and the lockup contract.
```rust
FunctionCall {
method_name: "exchange_deposit",
args: b"<MEMO>",
gas: ...,
deposit: <DEPOSIT_AMOUNT>,
}
```
- The transaction gets executed and the exchange's hot wallet account receives the `<DEPOSIT_AMOUNT>`.
- Exchange monitors incoming transactions and sees that this deposit has been associated with the `<MEMO>`.
- The exchange can now attribute `<DEPOSIT_AMOUNT>` for the user's account by mapping it with the received `<MEMO>`.

## Interface

```rust
pub fn exchange_deposit();
```

## API examples

Send `10` NEAR tokens to the exchange account `coin_exchange` with memo `USER_123` from user `token_owner`.

Command:

```bash
near call coin_exchange exchange_deposit 'USER_123' --accountId=token_owner --amount=10
```

NOTE: This command temporarily doesn't work due to near-cli assumption about JSON input format. See https://github.com/near/near-cli/issues/503
5 changes: 5 additions & 0 deletions exchange-deposit-receiver/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash
set -e

RUSTFLAGS='-C link-arg=-s' cargo +nightly build --target wasm32-unknown-unknown --release
cp target/wasm32-unknown-unknown/release/exchange_deposit_receiver.wasm ./res/
Binary file not shown.
14 changes: 14 additions & 0 deletions exchange-deposit-receiver/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#![no_std]
#![feature(core_intrinsics)]
#![allow(non_snake_case)]

#[panic_handler]
#[no_mangle]
pub fn on_panic(_info: &::core::panic::PanicInfo) -> ! {
unsafe {
::core::intrinsics::abort();
}
}

#[no_mangle]
pub fn exchange_deposit() {}

0 comments on commit 322587d

Please sign in to comment.