scrtlabs / snip20-reference-impl Goto Github PK
View Code? Open in Web Editor NEWThis is a reference implementation of the SNIP-20 standard.
License: Apache License 2.0
This is a reference implementation of the SNIP-20 standard.
License: Apache License 2.0
Is there any particular reason why the queries and query responses are not padded? It seems like a security risk if validators could see how many digits are in your token balance for example. If this is a genuine issue I'd be happy to submit a PR for this.
Adding the block timestamp to transaction history is very useful for accounting, tax reporting, etc.
Adding this should be simple, and will be useful for coins deployed in the future.
When I update the Cargo.toml
file to use secret cosmwasm v.1.1.9-secret and secret-toolkit v.0.8.0, at compilation I get the following error about incompatible versions of the zeroize
package:
error: failed to select a version for `zeroize`.
... required by package `elliptic-curve v0.12.0`
... which satisfies dependency `elliptic-curve = "^0.12"` of package `k256 v0.11.1`
... which satisfies dependency `k256 = "^0.11.1"` of package `cosmwasm-crypto v1.1.9 (https://github.com/scrtlabs/cosmwasm?tag=v1.1.9-secret#e40a15f0)`
... which satisfies git dependency `cosmwasm-crypto` of package `cosmwasm-std v1.1.9 (https://github.com/scrtlabs/cosmwasm?tag=v1.1.9-secret#e40a15f0)`
... which satisfies git dependency `cosmwasm-std` of package `cosmwasm-storage v1.1.9 (https://github.com/scrtlabs/cosmwasm?tag=v1.1.9-secret#e40a15f0)`
... which satisfies git dependency `cosmwasm-storage` of package `secret-toolkit-storage v0.8.0 (https://github.com/scrtlabs/secret-toolkit?tag=v0.8.0#dfbcc26e)`
... which satisfies git dependency `secret-toolkit-storage` of package `secret-toolkit v0.8.0 (https://github.com/scrtlabs/secret-toolkit?tag=v0.8.0#dfbcc26e)`
... which satisfies git dependency `secret-toolkit` of package `snip20-reference-impl v1.0.0 (/home/ben/secret-network-dev/snip20-reference-impl)`
versions that meet the requirements `^1.5` are: 1.5.7, 1.5.6, 1.5.5, 1.5.4, 1.5.3
all possible versions conflict with previously selected packages.
previously selected package `zeroize v1.3.0`
... which satisfies dependency `zeroize = ">=1, <1.4"` (locked to 1.3.0) of package `curve25519-dalek v3.2.1`
... which satisfies dependency `curve25519-dalek = "^3"` (locked to 3.2.1) of package `ed25519-zebra v3.1.0`
... which satisfies dependency `ed25519-zebra = "^3"` (locked to 3.1.0) of package `cosmwasm-crypto v1.1.9 (https://github.com/scrtlabs/cosmwasm?tag=v1.1.9-secret#e40a15f0)`
... which satisfies git dependency `cosmwasm-crypto` of package `cosmwasm-std v1.1.9 (https://github.com/scrtlabs/cosmwasm?tag=v1.1.9-secret#e40a15f0)`
... which satisfies git dependency `cosmwasm-std` of package `cosmwasm-storage v1.1.9 (https://github.com/scrtlabs/cosmwasm?tag=v1.1.9-secret#e40a15f0)`
... which satisfies git dependency `cosmwasm-storage` of package `secret-toolkit-storage v0.8.0 (https://github.com/scrtlabs/secret-toolkit?tag=v0.8.0#dfbcc26e)`
... which satisfies git dependency `secret-toolkit-storage` of package `secret-toolkit v0.8.0 (https://github.com/scrtlabs/secret-toolkit?tag=v0.8.0#dfbcc26e)`
... which satisfies git dependency `secret-toolkit` of package `snip20-reference-impl v1.0.0 (/home/ben/secret-network-dev/snip20-reference-impl)`
failed to select a version for `zeroize` which could resolve this conflict
It seems to indicate that the ed25519-zebra
and k256
dependencies in the cosmwasm crypto package are incompatible: https://github.com/scrtlabs/cosmwasm/blob/e40a15f04dae80680dbe22aef760e5eaab6b0a19/packages/crypto/Cargo.toml#L25
For reference, the only change I made was to update Cargo.toml
file in the snip20-reference-impl
to look like this:
cosmwasm-std = { git = "https://github.com/scrtlabs/cosmwasm", tag = "v1.1.9-secret" }
secret-toolkit = { git = "https://github.com/scrtlabs/secret-toolkit", tag = "v0.8.0", features = [
"permit",
"viewing-key",
] }
secret-toolkit-crypto = { git = "https://github.com/scrtlabs/secret-toolkit", tag = "v0.8.0", features = ["hash", "rand",] }
This issue represents a feature request to add two new queries to the upcoming SNIP-25.
This feature introduces the ability to query for all allowances given and received. The idea has been discussed several times before but was met with hesitation due to the lack of an efficient implementation.
We've begun implementing this feature and done so in a manner that avoids any of the storage drawbacks brought up in prior discussion, which largely stems from how the allowances were being stored. In order for pre-existing SNIPs to upgrade, a CosmWasm migrate
handler must be used since the allowances data struct is changed to overcome the aforementioned limitation.
Adds the ability for an owner to query for all allowances they have given out, as well as for a spender to query for all allowances they have received.
This query MUST be authenticated.
Returns the list of allowances given out by the current account as an owner, as well as the total count of allowances given out.
Results SHOULD be paginated. Results MUST be sorted in reverse chronological order by the datetime at which the allowance was first created (i.e., order is not determined by expiration, nor by last modified).
Name | Type | Description | optional |
---|---|---|---|
[with_permit].query.allowances_given.owner | string | Account from which tokens are allowed to be taken | no |
[with_permit].query.allowances_given.page_size | number | Number of allowances to return, starting from the latest. i.e. n=1 will return only the latest allowance | no |
[with_permit].query.allowances_given.page | number | Defaults to 0. Specifying a positive number will skip page * page_size txs from the start. | yes |
{
"allowances_given": {
"owner": "<address>",
"allowances": [
{
"spender": "<address>",
"allowance": "Uint128",
"expiration": 1234,
},
{ "...": "..." }
],
"count": 200
}
}
This query MUST be authenticated.
Returns the list of allowances given to the current account as a spender, as well as the total count of allowances received.
Results SHOULD be paginated. Results MUST be sorted in reverse chronological order by the datetime at which the allowance was first created (i.e., order is not determined by expiration).
Name | Type | Description | optional |
---|---|---|---|
[with_permit.]query.allowances_received.spender | string | Account which is allowed to spend tokens on behalf of the owner | no |
[with_permit.]query.allowances_received.page_size | number | Number of allowances to return, starting from the latest. i.e. n=1 will return only the latest allowance | no |
[with_permit.]query.allowances_received.page | number | Defaults to 0. Specifying a positive number will skip page * page_size txs from the start. | yes |
{
"allowances_received": {
"spender": "<address>",
"allowances": [
{
"owner": "<address>",
"allowance": "Uint128",
"expiration": 1234,
},
{ "...": "..." }
],
"count": 200
}
}
Hi everyone,
Currently I'm in the works of running this contract and am having an issue instantiating the contract.
I ran the following commands:
make
and next optimize the contract using:
docker run --rm -v "$(pwd)":/contract \ --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ enigmampc/secret-contract-optimizer
Having done this, I start the local testnet:
docker run -it --rm \ -p 26657:26657 -p 26656:26656 -p 1337:1337 \ -v $(pwd):/root/code \ --name localsecret ghcr.io/scrtlabs/localsecret
Then, inside the docker (docker exec -it localsecret /bin/bash
and run cd code
after), I store the contract:
secretd tx compute store contract.wasm.gz --from a --gas 1000000 -y --keyring-backend test
Running secretd query compute list-code
, no output is obtained. So maybe something goes wrong here.
Nonetheless, trying to instantiate the contract, I run the following command:
secretd tx compute instantiate 1 '{"name": "test", "symbol":"TTT", "decimals":10, "prng_seed":"VGVzdA=="}' --label test --from a
This returns the following error:
Error: unexpected end of JSON input
Do you know how to resolve this error?
The new AllowancesGiven
and AllowancesReceived
queries added in #77 make it possible for anyone to successfully pass authentication with a permit to view other addresses allowances. I've made a demo using secretjs
to better illustrate this.
Here we have secret1v6xp4qnlt79grjnf9rhrx9nke34k4pq04lcglm
send a 200000000
allowance to secret1f2mf5xusm28a2pvzu5ztu58c5w89kdqjcy4sfw
. With each run of the script we generate a random address and sign a permit with it but we are able to view their allowances just the same. I built and uploaded the contract using the latest commit on master
- 81ad971
import { Wallet, SecretNetworkClient } from 'secretjs'
async function permit_test() {
const code_id = 20597
const contract_address = 'secret1stn58qtmk64jvuk8u33fqdngad90djx7ycs82s'
const code_hash = '4e53e1d9d87241e58d16137b7056b14fe361b37a39ab074120912f6361184f02'
const wallet = new Wallet()
const client = new SecretNetworkClient({
wallet,
walletAddress: wallet.address,
chainId: 'pulsar-2',
url: 'https://api.pulsar.scrttestnet.com'
})
const permit = await client.utils.accessControl.permit.sign(
wallet.address,
'pulsar-2',
'allowance test',
[contract_address],
['allowance'],
false
)
let resp = await client.query.compute.queryContract({
contract_address,
code_hash,
query: { with_permit: {
permit,
query: { allowances_given: {
owner: 'secret1v6xp4qnlt79grjnf9rhrx9nke34k4pq04lcglm',
page_size: 10
} }
} }
})
console.log(JSON.stringify(resp, null, 2))
resp = await client.query.compute.queryContract({
contract_address,
code_hash,
query: { with_permit: {
permit,
query: { allowances_received: {
spender: 'secret1f2mf5xusm28a2pvzu5ztu58c5w89kdqjcy4sfw',
page_size: 10
} }
} }
})
console.log(JSON.stringify(resp, null, 2))
}
permit_test().catch(console.log)
The fix should be to simply check whether the validated address from the permit is the owner
or spender
field respectively?
But in that case those fields become redundant so they should be removed.
Also there is this comment which from what I can gather says that we should avoid canonicalizing or validating the address using api.deps
so it should not have any bearing on the issue, correct?
snip20-reference-impl/src/contract.rs
Lines 964 to 967 in 81ad971
Maybe @darwinzer0 can provide more insight into this?
Currently this branch has the updated code that ports the implementation to cosmwasm 1.0, however the changes made seem to be wrong. Cosmwasm docs state:
The new type Addr was created to hold validated addresses. Those can be created via Addr::unchecked, Api::addr_validate, Api::addr_humanize and JSON deserialization. In order to maintain type safety, deserialization into Addr must only be done from trusted sources like a contract's state or a query response. User inputs must be deserialized into String.
Addr
must not be used in messages sent by the user because this would result in unvalidated instances.
User inputs such as
TransferFrom {
owner: Addr,
recipient: Addr,
amount: Uint128,
memo: Option<String>,
padding: Option<String>,
}
Should deserialize into strings instead of Addr and then validated using addr_validate
. Please refer to the original cw20 implementation here
TransferFrom {
owner: String,
recipient: String,
amount: Uint128,
},
This issue represents a feature request to add support for a new optional field in every message for the upcoming SNIP-25.
This feature is similar to the padding
field in that it allows clients to tune their message in order to reduce data leaked through the publicly viewable metadata of executions. While padding
is used to fill message length, users are still exposed to data leaking through the gas_used
field of transaction results.
We've implemented a proof-of-concept using storage writes, but are experimenting with other operations as well.
It's important to note that even if the cost of the underlying operation were to change, this approach remains flexible enough to compensate since the client determines the multiplier.
The public gas_used
result of a contract execution leaks data about the code path taken.
In its simplest form, attackers can use this information to distinguish between the following execution methods with high confidence: create_viewing_key, set_viewing_key, increase_allowance/decrease_allowance, send/transfer, revoke_permit, and so on.
In some situations, an attacker might even be able to narrow or deduce the values of certain private variables.
While more precise solutions would involve modifications to the compute module, we propose an approach that can be deployed with contracts as-is and in a manner that is guaranteed to take place within the enclave.
We introduce the concept of "evaporation", by which extra gas is deliberately and deterministically consumed during execution in order to pad the gas_used
.
Users may include an optional evaporate
field in every message. The value of the field should be an integer that specifies an arbitrary multiplier for some fixed-cost operation.
Using evaporation, wallets can compute a precise multiplier to provide as input during execution in order to produce a gas_used
value that effectively obscures the nature of the transaction.
Name | Type | Description | optional |
---|---|---|---|
evaporate | number | Number of times to perform the predefined fixed-cost operation in order to consume extra gas. | yes |
{
"transfer": {
"recipient": "<address>",
"amount": "100",
"padding": "-------",
"evaporate": 620,
},
}
Not having this makes creating paging views for SNIP-20 tokens challenging. You can't know how many pages there are in the tx history without paging through all of it first. By adding the total amount of items to the response object, UIs will be able to know how many more pages can be expected.
As specified in the documentation, we should run enigmampc/secret-contract-optimizer
before storing the contract.
On the branch cosmwasm-v1
it currently fails with
error[E0407]: method `provide` is not a member of trait `std::error::Error`
Error: --> /home/runner/.cargo/git/checkouts/cosmwasm-4588eb921f8fdfe2/f7e2b1d/packages/std/src/errors/recover_pubkey_error.rs:8:10
|
8 | #[derive(Error, Debug)]
| ^^^^^ not a member of trait `std::error::Error`
|
= note: this error originates in the derive macro `Error` (in Nightly builds, run with -Z macro-backtrace for more info)
Error: --> /home/runner/.cargo/git/checkouts/cosmwasm-4588eb921f8fdfe2/f7e2b1d/packages/std/src/errors/verification_error.rs:9:10
|
9 | #[derive(Error, Debug)]
| ^^^^^ not a member of trait `std::error::Error`
|
= note: this error originates in the derive macro `Error` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0412]: cannot find type `Demand` in module `std::any`
[...]
Should we stick to the optimisation in the Makefile?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.