cw20_icg_pkg/
lib.rs

1use cosmwasm_schema::{cw_serde, QueryResponses};
2use cosmwasm_std::{Addr, Binary, StdError, StdResult, Uint128};
3use cw20::{Cw20Coin, Expiration, Logo, MinterResponse};
4use gate_pkg::GateMsg;
5
6#[cw_serde]
7pub enum Cw20GateMsgType {
8    Bridge {
9        sender: String,
10        receiver: String,
11        amount: Uint128,
12    },
13
14    BridgeAndExecute {
15        sender: String,
16        receiver: String,
17        amount: Uint128,
18        to_contract: String,
19        msg: Binary,
20    },
21}
22
23#[cw_serde]
24pub enum ExecuteMsg {
25    Transfer {
26        recipient: String,
27        amount: Uint128,
28    },
29    Burn {
30        amount: Uint128,
31    },
32    Send {
33        contract: String,
34        amount: Uint128,
35        msg: Binary,
36    },
37    IncreaseAllowance {
38        spender: String,
39        amount: Uint128,
40        expires: Option<Expiration>,
41    },
42    DecreaseAllowance {
43        spender: String,
44        amount: Uint128,
45        expires: Option<Expiration>,
46    },
47    TransferFrom {
48        owner: String,
49        recipient: String,
50        amount: Uint128,
51    },
52    SendFrom {
53        owner: String,
54        contract: String,
55        amount: Uint128,
56        msg: Binary,
57    },
58    BurnFrom {
59        owner: String,
60        amount: Uint128,
61    },
62    Mint {
63        recipient: String,
64        amount: Uint128,
65    },
66    UpdateMinter {
67        new_minter: Option<String>,
68    },
69    UpdateMarketing {
70        project: Option<String>,
71        description: Option<String>,
72        marketing: Option<String>,
73    },
74    UploadLogo(Logo),
75    // NEW
76    RegisterGate {
77        contract: Addr,
78    },
79    GateSetPermission {
80        contract: String,
81        chain: String,
82    },
83    GateBridge {
84        chain: String,
85        remote_receiver: String,
86        amount: Uint128,
87    },
88    GateBridgeAndExecute {
89        chain: String,
90        remote_receiver: String,
91        amount: Uint128,
92        remote_contract: String,
93        msg: Binary,
94    },
95    // Gate msg receive implementation
96    ReceiveGateMsg(GateMsg),
97}
98
99#[cw_serde]
100#[derive(QueryResponses)]
101pub enum QueryMsg {
102    /// Returns the current balance of the given address, 0 if unset.
103    #[returns(cw20::BalanceResponse)]
104    Balance { address: String },
105    /// Returns metadata on the contract - name, decimals, supply, etc.
106    #[returns(cw20::TokenInfoResponse)]
107    TokenInfo {},
108    /// Only with "mintable" extension.
109    /// Returns who can mint and the hard cap on maximum tokens after minting.
110    #[returns(cw20::MinterResponse)]
111    Minter {},
112    /// Only with "allowance" extension.
113    /// Returns how much spender can use from owner account, 0 if unset.
114    #[returns(cw20::AllowanceResponse)]
115    Allowance { owner: String, spender: String },
116    /// Only with "enumerable" extension (and "allowances")
117    /// Returns all allowances this owner has approved. Supports pagination.
118    #[returns(cw20::AllAllowancesResponse)]
119    AllAllowances {
120        owner: String,
121        start_after: Option<String>,
122        limit: Option<u32>,
123    },
124    /// Only with "enumerable" extension (and "allowances")
125    /// Returns all allowances this spender has been granted. Supports pagination.
126    #[returns(cw20::AllSpenderAllowancesResponse)]
127    AllSpenderAllowances {
128        spender: String,
129        start_after: Option<String>,
130        limit: Option<u32>,
131    },
132    /// Only with "enumerable" extension
133    /// Returns all accounts that have balances. Supports pagination.
134    #[returns(cw20::AllAccountsResponse)]
135    AllAccounts {
136        start_after: Option<String>,
137        limit: Option<u32>,
138    },
139    /// Only with "marketing" extension
140    /// Returns more metadata on the contract to display in the client:
141    /// - description, logo, project url, etc.
142    #[returns(cw20::MarketingInfoResponse)]
143    MarketingInfo {},
144    /// Only with "marketing" extension
145    /// Downloads the embedded logo data (if stored on chain). Errors if no logo data is stored for this
146    /// contract.
147    #[returns(cw20::DownloadLogoResponse)]
148    DownloadLogo {},
149
150    // ICG new queries
151    #[returns(String)]
152    RemoteContract { chain: String },
153    // ICG new queries
154    #[returns(String)]
155    Gate {},
156}
157
158#[cw_serde]
159pub struct InstantiateMsg {
160    pub name: String,
161    pub symbol: String,
162    pub decimals: u8,
163    pub initial_balances: Vec<Cw20Coin>,
164    pub mint: Option<MinterResponse>,
165}
166
167impl InstantiateMsg {
168    pub fn get_cap(&self) -> Option<Uint128> {
169        self.mint.as_ref().and_then(|v| v.cap)
170    }
171
172    pub fn validate(&self) -> StdResult<()> {
173        // Check name, symbol, decimals
174        if !is_valid_name(&self.name) {
175            return Err(StdError::generic_err(
176                "Name is not in the expected format (3-50 UTF-8 bytes)",
177            ));
178        }
179        if !is_valid_symbol(&self.symbol) {
180            return Err(StdError::generic_err(
181                "Ticker symbol is not in expected format [a-zA-Z\\-]{3,12}",
182            ));
183        }
184        if self.decimals > 18 {
185            return Err(StdError::generic_err("Decimals must not exceed 18"));
186        }
187        Ok(())
188    }
189}
190
191fn is_valid_name(name: &str) -> bool {
192    let bytes = name.as_bytes();
193    if bytes.len() < 3 || bytes.len() > 50 {
194        return false;
195    }
196    true
197}
198
199fn is_valid_symbol(symbol: &str) -> bool {
200    let bytes = symbol.as_bytes();
201    if bytes.len() < 3 || bytes.len() > 12 {
202        return false;
203    }
204    for byte in bytes.iter() {
205        if (*byte != 45) && (*byte < 65 || *byte > 90) && (*byte < 97 || *byte > 122) {
206            return false;
207        }
208    }
209    true
210}