Skip to content

Commit 3f0ee5c

Browse files
committed
Update burner contract to take a list of denoms
1 parent bd9a788 commit 3f0ee5c

File tree

5 files changed

+98
-15
lines changed

5 files changed

+98
-15
lines changed

contracts/burner/schema/burner.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"title": "MigrateMsg",
1717
"type": "object",
1818
"required": [
19+
"denoms",
1920
"payout"
2021
],
2122
"properties": {
@@ -26,8 +27,15 @@
2627
"format": "uint32",
2728
"minimum": 0.0
2829
},
30+
"denoms": {
31+
"description": "The denoms of the final payout. Balances of tokens not listed here will remain in the account untouched.",
32+
"type": "array",
33+
"items": {
34+
"type": "string"
35+
}
36+
},
2937
"payout": {
30-
"description": "The address we send all remaining balance to",
38+
"description": "The address we send all remaining balance to. See denoms below for the denoms to consider.",
3139
"type": "string"
3240
}
3341
},

contracts/burner/schema/raw/migrate.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"title": "MigrateMsg",
44
"type": "object",
55
"required": [
6+
"denoms",
67
"payout"
78
],
89
"properties": {
@@ -13,8 +14,15 @@
1314
"format": "uint32",
1415
"minimum": 0.0
1516
},
17+
"denoms": {
18+
"description": "The denoms of the final payout. Balances of tokens not listed here will remain in the account untouched.",
19+
"type": "array",
20+
"items": {
21+
"type": "string"
22+
}
23+
},
1624
"payout": {
17-
"description": "The address we send all remaining balance to",
25+
"description": "The address we send all remaining balance to. See denoms below for the denoms to consider.",
1826
"type": "string"
1927
}
2028
},

contracts/burner/src/contract.rs

Lines changed: 68 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use cosmwasm_std::{
2-
entry_point, BankMsg, DepsMut, Env, MessageInfo, Order, Response, StdError, StdResult, Storage,
2+
entry_point, BankMsg, Coin, DepsMut, Env, MessageInfo, Order, Response, StdError, StdResult,
3+
Storage,
34
};
5+
use std::collections::BTreeSet;
46

57
use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg};
68

@@ -18,12 +20,22 @@ pub fn instantiate(
1820

1921
#[entry_point]
2022
pub fn migrate(deps: DepsMut, env: Env, msg: MigrateMsg) -> StdResult<Response> {
21-
// get balance and send all to recipient
22-
#[allow(deprecated)]
23-
let balance = deps.querier.query_all_balances(env.contract.address)?;
23+
let denom_len = msg.denoms.len();
24+
let denoms = BTreeSet::<String>::from_iter(msg.denoms); // Ensure uniqueness
25+
if denoms.len() != denom_len {
26+
return Err(StdError::generic_err("Denoms not unique"));
27+
}
28+
29+
// get balance and send to recipient
30+
let mut balances = Vec::<Coin>::with_capacity(denoms.len());
31+
for denom in denoms {
32+
let balance = deps.querier.query_balance(&env.contract.address, denom)?;
33+
balances.push(balance);
34+
}
35+
2436
let send = BankMsg::Send {
2537
to_address: msg.payout.clone(),
26-
amount: balance,
38+
amount: balances,
2739
};
2840

2941
let deleted = cleanup(deps.storage, msg.delete as usize);
@@ -86,7 +98,7 @@ mod tests {
8698
use cosmwasm_std::testing::{
8799
message_info, mock_dependencies, mock_dependencies_with_balance, mock_env,
88100
};
89-
use cosmwasm_std::{coins, Attribute, StdError, Storage, SubMsg};
101+
use cosmwasm_std::{coin, coins, Attribute, StdError, Storage, SubMsg};
90102

91103
/// Gets the value of the first attribute with the given key
92104
fn first_attr(data: impl AsRef<[Attribute]>, search_key: &str) -> Option<String> {
@@ -118,24 +130,64 @@ mod tests {
118130
}
119131

120132
#[test]
121-
fn migrate_sends_funds() {
122-
let mut deps = mock_dependencies_with_balance(&coins(123456, "gold"));
133+
fn migrate_sends_one_balance() {
134+
let initial_balance = vec![coin(123456, "gold"), coin(77, "silver")];
135+
let mut deps = mock_dependencies_with_balance(&initial_balance);
136+
let payout = String::from("someone else");
137+
138+
// malformed denoms
139+
let msg = MigrateMsg {
140+
payout: payout.clone(),
141+
denoms: vec!["gold".to_string(), "silver".to_string(), "gold".to_string()],
142+
delete: 0,
143+
};
144+
let err = migrate(deps.as_mut(), mock_env(), msg).unwrap_err();
145+
match err {
146+
StdError::GenericErr { msg, .. } => assert_eq!(msg, "Denoms not unique"),
147+
err => panic!("Unexpected error: {err:?}"),
148+
}
149+
150+
// One denom
151+
let msg = MigrateMsg {
152+
payout: payout.clone(),
153+
denoms: vec!["gold".to_string()],
154+
delete: 0,
155+
};
156+
let res = migrate(deps.as_mut(), mock_env(), msg).unwrap();
157+
// check payout
158+
assert_eq!(res.messages.len(), 1);
159+
let msg = res.messages.first().expect("no message");
160+
assert_eq!(
161+
msg,
162+
&SubMsg::new(BankMsg::Send {
163+
to_address: payout,
164+
amount: coins(123456, "gold"),
165+
})
166+
);
167+
}
168+
169+
// as above but this time we want all gold and silver
170+
#[test]
171+
fn migrate_sends_two_balances() {
172+
let initial_balance = vec![coin(123456, "gold"), coin(77, "silver")];
173+
let mut deps = mock_dependencies_with_balance(&initial_balance);
123174

124175
// change the verifier via migrate
125176
let payout = String::from("someone else");
126177
let msg = MigrateMsg {
127178
payout: payout.clone(),
179+
denoms: vec!["silver".to_string(), "gold".to_string()],
128180
delete: 0,
129181
};
130182
let res = migrate(deps.as_mut(), mock_env(), msg).unwrap();
131183
// check payout
132-
assert_eq!(1, res.messages.len());
184+
assert_eq!(res.messages.len(), 1);
133185
let msg = res.messages.first().expect("no message");
134186
assert_eq!(
135187
msg,
136188
&SubMsg::new(BankMsg::Send {
137189
to_address: payout,
138-
amount: coins(123456, "gold"),
190+
amount: vec![coin(123456, "gold"), coin(77, "silver")],
139191
})
140192
);
141193
}
@@ -154,6 +206,7 @@ mod tests {
154206
// migrate all of the data in one go
155207
let msg = MigrateMsg {
156208
payout: "user".to_string(),
209+
denoms: vec![],
157210
delete: 100,
158211
};
159212
migrate(deps.as_mut(), mock_env(), msg).unwrap();
@@ -178,7 +231,11 @@ mod tests {
178231

179232
// change the verifier via migrate
180233
let payout = String::from("someone else");
181-
let msg = MigrateMsg { payout, delete: 0 };
234+
let msg = MigrateMsg {
235+
payout,
236+
denoms: vec![],
237+
delete: 0,
238+
};
182239
let _res = migrate(deps.as_mut(), mock_env(), msg).unwrap();
183240

184241
let res = execute(

contracts/burner/src/msg.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@ use cosmwasm_schema::cw_serde;
22

33
#[cw_serde]
44
pub struct MigrateMsg {
5-
/// The address we send all remaining balance to
5+
/// The address we send all remaining balance to. See denoms
6+
/// below for the denoms to consider.
67
pub payout: String,
8+
/// The denoms of the final payout. Balances of tokens not listed here
9+
/// will remain in the account untouched.
10+
pub denoms: Vec<String>,
711
/// Optional amount of items to delete in this call.
812
/// If it is not provided, nothing will be deleted.
913
/// You can delete further items in a subsequent execute call.

contracts/burner/tests/integration.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,10 @@ fn migrate_sends_funds() {
6060

6161
// change the verifier via migrate
6262
let payout = String::from("someone else");
63+
6364
let msg = MigrateMsg {
6465
payout: payout.clone(),
66+
denoms: vec!["gold".to_string()],
6567
delete: 0,
6668
};
6769
let res: Response = migrate(&mut deps, mock_env(), msg).unwrap();
@@ -95,7 +97,11 @@ fn execute_cleans_up_data() {
9597

9698
// change the verifier via migrate
9799
let payout = String::from("someone else");
98-
let msg = MigrateMsg { payout, delete: 0 };
100+
let msg = MigrateMsg {
101+
payout,
102+
denoms: vec![],
103+
delete: 0,
104+
};
99105
let _res: Response = migrate(&mut deps, mock_env(), msg).unwrap();
100106

101107
let res: Response = execute(

0 commit comments

Comments
 (0)