Skip to content

Commit

Permalink
Merge pull request #24 from CosmWasm/subkeys
Browse files Browse the repository at this point in the history
Implement subkeys as a cw1 contract
  • Loading branch information
ethanfrey authored Aug 7, 2020
2 parents 8be5305 + 41e61dc commit 3932fd9
Show file tree
Hide file tree
Showing 18 changed files with 1,786 additions and 27 deletions.
42 changes: 42 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ workflows:
version: 2
test:
jobs:
- contract_cw1_subkeys
- contract_cw1_whitelist
- contract_cw20_base
- contract_cw20_escrow
Expand All @@ -11,6 +12,47 @@ workflows:
- lint

jobs:
contract_cw1_subkeys:
docker:
- image: rust:1.44.1
working_directory: ~/project/contracts/cw1-subkeys
steps:
- checkout:
path: ~/project
- run:
name: Version information
command: rustc --version; cargo --version; rustup --version
- restore_cache:
keys:
- cargocache-cw1-subkeys-rust:1.44.1-{{ checksum "~/project/Cargo.lock" }}
- run:
name: Add wasm32 target
command: rustup target add wasm32-unknown-unknown
- run:
name: Unit Tests
env: RUST_BACKTRACE=1
command: cargo unit-test --locked
- run:
name: Build Wasm
command: cargo wasm-debug --locked
- run:
name: Build and run schema generator
command: cargo schema --locked
- run:
name: Ensure checked-in schemas are up-to-date
command: |
CHANGES_IN_REPO=$(git status --porcelain)
if [[ -n "$CHANGES_IN_REPO" ]]; then
echo "Repository is dirty. Showing 'git status' and 'git --no-pager diff' for debugging now:"
git status && git --no-pager diff
exit 1
fi
- save_cache:
paths:
- /usr/local/cargo/registry
- target
key: cargocache-cw1-subkeys-rust:1.44.1-{{ checksum "~/project/Cargo.lock" }}

contract_cw1_whitelist:
docker:
- image: rust:1.44.1
Expand Down
66 changes: 40 additions & 26 deletions Cargo.lock

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

6 changes: 6 additions & 0 deletions contracts/cw1-subkeys/.cargo/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[alias]
wasm = "build --release --target wasm32-unknown-unknown"
wasm-debug = "build --target wasm32-unknown-unknown"
unit-test = "test --lib --features backtraces"
integration-test = "test --test integration"
schema = "run --example schema"
25 changes: 25 additions & 0 deletions contracts/cw1-subkeys/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[package]
name = "cw1-subkeys"
version = "0.1.0"
authors = ["Ethan Frey <ethanfrey@users.noreply.github.com>"]
edition = "2018"
description = "Implement subkeys for authorizing native tokens as a cw1 proxy contract"
license = "AGPL-3.0"

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

[features]
backtraces = ["cosmwasm-std/backtraces"]

[dependencies]
cosmwasm-std = { version = "0.10.0", features = ["iterator"] }
cosmwasm-storage = { version = "0.10.0", features = ["iterator"] }
cw20 = { path = "../../packages/cw20", version = "0.1.0" }
cw1-whitelist = { path = "../cw1-whitelist", version = "0.1.0" }
schemars = "0.7"
serde = { version = "1.0.103", default-features = false, features = ["derive"] }
snafu = { version = "0.6.3" }

[dev-dependencies]
cosmwasm-schema = { version = "0.10.0" }
15 changes: 15 additions & 0 deletions contracts/cw1-subkeys/NOTICE
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
CosmWasm-Plus: A collection of production-quality CosmWasm contracts
Copyright (C) 2020 Confio OÜ

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
84 changes: 84 additions & 0 deletions contracts/cw1-subkeys/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# CW1 Subkeys

This builds on `cw1-whitelist` to provide the first non-trivial solution.
It still works like `cw1-whitelist` with a set of admins (typically 1)
which have full control of the account. However, you can then grant
a number of accounts allowances to send native tokens from this account.

This was proposed in Summer 2019 for the Cosmos Hub and resembles the
functionality of ERC20 (allowances and transfer from).

## Details

Basically, any admin can add an allowance for a `(spender, denom)` pair
(similar to cw20 `IncreaseAllowance` / `DecreaseAllowance`). Any non-admin
account can try to execute a `CosmosMsg::Bank(BankMsg::Send{})` from this
contract and if they have the required allowances, their allowance will be
reduced and the send message relayed. If they don't have sufficient authorization,
or if they try to proxy any other message type, then the attempt will be rejected.

### Messages

This adds 2 messages beyond the `cw1` spec:

```rust
enum HandleMsg {
IncreaseAllowance {
spender: HumanAddr,
denom: String,
amount: Uint128,
expires: Option<Expiration>,
},
DecreaseAllowance {
spender: HumanAddr,
denom: String,
amount: Uint128,
expires: Option<Expiration>,
}
}
```

### Queries

It also adds one more query type:

```rust
enum QueryMsg {
Allowance {
spender: HumanAddr,
}
}

pub struct AllowanceResponse {
pub allowance: Vec<Coin>,
pub expires: Expiration,
}
```

## Running this contract

You will need Rust 1.44.1+ with `wasm32-unknown-unknown` target installed.

You can run unit tests on this via:

`cargo test`

Once you are happy with the content, you can compile it to wasm via:

```
RUSTFLAGS='-C link-arg=-s' cargo wasm
cp ../../target/wasm32-unknown-unknown/release/cw1_subkeys.wasm .
ls -l cw1_subkeys.wasm
sha256sum cw1_subkeys.wasm
```

Or for a production-ready (compressed) build, run the following from the
repository root (not currently working with this monorepo...)

```
docker run --rm -v "$(pwd)":/code \
--mount type=volume,source="cosmwasm_plus_cache",target=/code/target \
--mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \
cosmwasm/rust-optimizer:0.9.0 ./contracts/cw1-subkeys
mv contract.wasm cw1_subkeys.wasm
```
21 changes: 21 additions & 0 deletions contracts/cw1-subkeys/examples/schema.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use std::env::current_dir;
use std::fs::create_dir_all;

use cosmwasm_schema::{export_schema, remove_schemas, schema_for};

use cw1_subkeys::msg::{HandleMsg, QueryMsg};
use cw1_subkeys::state::Allowance;
use cw1_whitelist::msg::{ConfigResponse, InitMsg};

fn main() {
let mut out_dir = current_dir().unwrap();
out_dir.push("schema");
create_dir_all(&out_dir).unwrap();
remove_schemas(&out_dir).unwrap();

export_schema(&schema_for!(InitMsg), &out_dir);
export_schema(&schema_for!(HandleMsg), &out_dir);
export_schema(&schema_for!(QueryMsg), &out_dir);
export_schema(&schema_for!(Allowance), &out_dir);
export_schema(&schema_for!(ConfigResponse), &out_dir);
}
Loading

0 comments on commit 3932fd9

Please sign in to comment.