Skip to content

Commit 693be74

Browse files
committed
refactor code & add cw20-ics20-msg package
1 parent fd9c9b6 commit 693be74

File tree

12 files changed

+142
-25
lines changed

12 files changed

+142
-25
lines changed

Cargo.lock

+13
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

contracts/cw-ics20-latest/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ cosmwasm-schema = { version = "1.1.0" }
2222
cw-utils = "0.16.0"
2323
cw2 = { path = "../../packages/cw2", version = "0.16.0" }
2424
cw20 = { path = "../../packages/cw20", version = "0.16.0" }
25+
cw20-ics20-msg = { path = "../../packages/cw20-ics20-msg", version = "0.0.1" }
2526
cosmwasm-std = { version = "1.1.0", features = ["stargate"] }
2627
cw-storage-plus = "0.16.0"
2728
cw-controllers = { path = "../../packages/controllers", version = "0.16.0" }

contracts/cw-ics20-latest/src/contract.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use cw2::{get_contract_version, set_contract_version};
1010
use cw20::{Cw20Coin, Cw20ReceiveMsg};
1111
use cw_storage_plus::Bound;
1212

13-
use crate::amount::Amount;
1413
use crate::error::ContractError;
1514
use crate::ibc::Ics20Packet;
1615
use crate::migrations::{v1, v2};
@@ -25,6 +24,7 @@ use crate::state::{
2524
Cw20MappingMetadata, ADMIN, ALLOW_LIST, CHANNEL_INFO, CHANNEL_STATE, CONFIG, CW20_ISC20_DENOM,
2625
NATIVE_ALLOW_LIST,
2726
};
27+
use cw20_ics20_msg::amount::Amount;
2828
use cw_utils::{maybe_addr, nonpayable, one_coin};
2929

3030
// version info for migration info
@@ -481,7 +481,7 @@ pub fn query_channel(deps: Deps, id: String) -> StdResult<ChannelResponse> {
481481
})
482482
.collect::<StdResult<Vec<_>>>()?;
483483
// we want (Vec<outstanding>, Vec<total>)
484-
let (balances, total_sent) = state.into_iter().unzip();
484+
let (balances, total_sent): (Vec<Amount>, Vec<Amount>) = state.into_iter().unzip();
485485

486486
Ok(ChannelResponse {
487487
info,

contracts/cw-ics20-latest/src/ibc.rs

+20-16
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,23 @@
1-
use std::ops::Div;
2-
1+
use cw20_ics20_msg::DelegateCw20Msg;
32
use schemars::JsonSchema;
43
use serde::{Deserialize, Serialize};
54

65
use cosmwasm_schema::cw_serde;
76
use cosmwasm_std::{
8-
attr, entry_point, from_binary, to_binary, Addr, BankMsg, Binary, CosmosMsg, Decimal, Deps,
9-
DepsMut, Env, IbcBasicResponse, IbcChannel, IbcChannelCloseMsg, IbcChannelConnectMsg,
10-
IbcChannelOpenMsg, IbcEndpoint, IbcOrder, IbcPacket, IbcPacketAckMsg, IbcPacketReceiveMsg,
11-
IbcPacketTimeoutMsg, IbcReceiveResponse, Reply, Response, Storage, SubMsg, SubMsgResult,
12-
Uint128, WasmMsg,
7+
attr, entry_point, from_binary, to_binary, Addr, BankMsg, Binary, CosmosMsg, Deps, DepsMut,
8+
Env, IbcBasicResponse, IbcChannel, IbcChannelCloseMsg, IbcChannelConnectMsg, IbcChannelOpenMsg,
9+
IbcEndpoint, IbcOrder, IbcPacket, IbcPacketAckMsg, IbcPacketReceiveMsg, IbcPacketTimeoutMsg,
10+
IbcReceiveResponse, Reply, Response, Storage, SubMsg, SubMsgResult, Uint128, WasmMsg,
1311
};
1412

15-
use crate::amount::Amount;
1613
use crate::error::{ContractError, Never};
1714
use crate::state::{
1815
get_key_ics20_ibc_denom, increase_channel_balance, reduce_channel_balance,
1916
undo_reduce_channel_balance, ChannelInfo, ReplyArgs, ALLOW_LIST, CHANNEL_INFO, CONFIG,
2017
CW20_ISC20_DENOM, NATIVE_ALLOW_LIST, REPLY_ARGS,
2118
};
2219
use cw20::Cw20ExecuteMsg;
20+
use cw20_ics20_msg::amount::Amount;
2321

2422
pub const ICS20_VERSION: &str = "ics20-1";
2523
pub const ICS20_ORDERING: IbcOrder = IbcOrder::Unordered;
@@ -325,14 +323,20 @@ fn handle_ibc_packet_receive_native_remote_chain(
325323
return Err(ContractError::CustomContractRevoked {});
326324
}
327325

328-
let to_send = Amount::from_parts(
329-
cw20_mapping.cw20_denom,
330-
msg.amount.div(Uint128::from(
331-
10u64.pow((cw20_mapping.remote_decimals - 6) as u32), // TODO: get cw20 decimal instead of hardcode. Also, need to check safe sub to prevent negative
332-
)),
333-
);
334-
335-
let cosmos_msg = send_amount(to_send, msg.receiver.clone(), Some(packet.data.clone()));
326+
let to_send = Amount::from_parts(cw20_mapping.cw20_denom, msg.amount);
327+
328+
// send token to the custom contract for further handling
329+
let cosmos_msg: CosmosMsg = WasmMsg::Execute {
330+
contract_addr: msg.receiver.clone(),
331+
msg: to_binary(&DelegateCw20Msg {
332+
token: to_send,
333+
from_decimals: cw20_mapping.remote_decimals,
334+
data: packet.data.clone(),
335+
})
336+
.unwrap(),
337+
funds: vec![],
338+
}
339+
.into();
336340
let sub_msg = SubMsg::new(cosmos_msg);
337341

338342
let res = IbcReceiveResponse::new()

contracts/cw-ics20-latest/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ For more information on this contract, please check out the
1111
[README](https://github.com/CosmWasm/cw-plus/blob/main/contracts/cw20-ics20/README.md).
1212
*/
1313

14-
pub mod amount;
1514
pub mod contract;
1615
mod error;
1716
pub mod ibc;

contracts/cw-ics20-latest/src/migrations.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ pub mod v1 {
1616

1717
// v2 format is anything older than 0.13.1 when we only updated the internal balances on success ack
1818
pub mod v2 {
19-
use crate::amount::Amount;
2019
use crate::state::{ChannelState, CHANNEL_INFO, CHANNEL_STATE};
2120
use crate::ContractError;
2221
use cosmwasm_std::{to_binary, Addr, DepsMut, Env, Order, StdResult, WasmQuery};
2322
use cw20::{BalanceResponse, Cw20QueryMsg};
23+
use cw20_ics20_msg::amount::Amount;
2424

2525
pub fn update_balances(mut deps: DepsMut, env: &Env) -> Result<(), ContractError> {
2626
let channels = CHANNEL_INFO

contracts/cw-ics20-latest/src/msg.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ use cosmwasm_schema::{cw_serde, QueryResponses};
22
use cosmwasm_std::{Addr, Binary, IbcEndpoint};
33
use cw20::Cw20ReceiveMsg;
44

5-
use crate::amount::Amount;
65
use crate::state::{ChannelInfo, Cw20MappingMetadata};
6+
use cw20_ics20_msg::amount::Amount;
77

88
#[cw_serde]
99
pub struct InitMsg {

packages/cw20-ics20-msg/.cargo/config

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[alias]
2+
wasm = "build --release --target wasm32-unknown-unknown"
3+
wasm-debug = "build --target wasm32-unknown-unknown"

packages/cw20-ics20-msg/Cargo.toml

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[package]
2+
name = "cw20-ics20-msg"
3+
version = "0.0.1"
4+
authors = ["Oraichain Labs"]
5+
edition = "2021"
6+
description = "Definition and types for the cw20-ics20-msg interface"
7+
license = "Apache-2.0"
8+
repository = "https://github.com/Oraichain/ibc-bridge-wasm"
9+
homepage = "https://orai.io"
10+
11+
[dependencies]
12+
cosmwasm-schema = "1.0.0"
13+
cosmwasm-std = { version = "1.0.0", default-features = false }
14+
cw-storage-plus = "0.16.0"
15+
cw20 = { path = "../cw20", version = "0.16.0" }
16+
schemars = "0.8.1"
17+
serde = { version = "1.0.103", default-features = false, features = ["derive"] }

packages/cw20-ics20-msg/README.md

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# CW2 Spec: Contract Info
2+
3+
Most of the CW* specs are focused on the *public interfaces*
4+
of the contract. The APIs used for `ExecuteMsg` or `QueryMsg`.
5+
However, when we wish to migrate or inspect smart contract info,
6+
we need some form of smart contract information embedded on state.
7+
8+
This is where CW2 comes in. It specifies a special Item to
9+
be stored on disk by all contracts on `instantiate`.
10+
11+
`ContractInfo` must be stored under the `"contract_info"` key which translates
12+
to `"636F6E74726163745F696E666F"` in hex format.
13+
Since the state is well defined, we do not need to support any "smart queries".
14+
We do provide a helper to construct a "raw query" to read the ContractInfo
15+
of any CW2-compliant contract.
16+
17+
You can query using:
18+
```shell
19+
wasmd query wasm contract-state raw [contract_addr] 636F6E74726163745F696E666F --node $RPC
20+
```
21+
22+
When the `migrate` function is called, then the new contract
23+
can read that data andsee if this is an expected contract we can
24+
migrate from. And also contain extra version information if we
25+
support multiple migrate paths.
26+
27+
### Data structures
28+
29+
**Required**
30+
31+
All CW2-compliant contracts must store the following data:
32+
33+
* key: `contract_info`
34+
* data: Json-serialized `ContractVersion`
35+
36+
```rust
37+
pub struct ContractVersion {
38+
/// contract is a globally unique identifier for the contract.
39+
/// it should build off standard namespacing for whichever language it is in,
40+
/// and prefix it with the registry we use.
41+
/// For rust we prefix with `crates.io:`, to give us eg. `crates.io:cw20-base`
42+
pub contract: String,
43+
/// version is any string that this implementation knows. It may be simple counter "1", "2".
44+
/// or semantic version on release tags "v0.7.0", or some custom feature flag list.
45+
/// the only code that needs to understand the version parsing is code that knows how to
46+
/// migrate from the given contract (and is tied to it's implementation somehow)
47+
pub version: String,
48+
}
49+
```
50+
51+
Thus, an serialized example may looks like:
52+
53+
```json
54+
{
55+
"contract": "crates.io:cw20-base",
56+
"version": "v0.1.0"
57+
}
58+
```

contracts/cw-ics20-latest/src/amount.rs renamed to packages/cw20-ics20-msg/src/amount.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
use crate::error::ContractError;
21
use cosmwasm_schema::cw_serde;
3-
use cosmwasm_std::{Coin, Uint128};
2+
use cosmwasm_std::{Coin, StdError, Uint128};
43
use cw20::Cw20Coin;
54
use std::convert::TryInto;
65

@@ -53,8 +52,12 @@ impl Amount {
5352
}
5453

5554
/// convert the amount into u64
56-
pub fn u64_amount(&self) -> Result<u64, ContractError> {
57-
Ok(self.amount().u128().try_into()?)
55+
pub fn u64_amount(&self) -> Result<u64, StdError> {
56+
Ok(self
57+
.amount()
58+
.u128()
59+
.try_into()
60+
.map_err(|_| StdError::generic_err("error casting to u64 from u128".to_string()))?)
5861
}
5962

6063
pub fn is_empty(&self) -> bool {

packages/cw20-ics20-msg/src/lib.rs

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*!
2+
Shared msgs for the cw20-ics20 and other contracts that interact with it
3+
*/
4+
5+
pub mod amount;
6+
7+
use amount::Amount;
8+
use cosmwasm_schema::cw_serde;
9+
use cosmwasm_std::Binary;
10+
11+
#[cw_serde]
12+
pub struct DelegateCw20Msg {
13+
/// token from the remote chain
14+
pub token: Amount,
15+
/// the decimals of the native token, popular is 18 or 6
16+
pub from_decimals: u8,
17+
/// additional data from the memo of the IBC transfer packet
18+
pub data: Binary,
19+
}

0 commit comments

Comments
 (0)