Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mint/sscrt to shade minting #38

Merged
merged 13 commits into from
Aug 11, 2021
2 changes: 1 addition & 1 deletion contracts/compiled/checksum/mint.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
c03334ef68a3f3a54a7254e426d7af07
28d7900c72ec86724ab8d1857370d302
11 changes: 9 additions & 2 deletions contracts/compiled/contractlib/mintlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@


class Mint(Contract):
def __init__(self, label, silk, oracle, contract='mint.wasm.gz', admin='a', uploader='a', gas='10000000',
def __init__(self, label, silk, shade, oracle, contract='mint.wasm.gz', admin='a', uploader='a', gas='10000000',
backend='test', instantiated_contract=None, code_id=None):
init_msg = json.dumps(
{"silk": {"address": silk.address, "code_hash": silk.code_hash},
"shade": {"address": shade.address, "code_hash": shade.code_hash},
"oracle": {"address": oracle.address, "code_hash": oracle.code_hash}})
super().__init__(contract, init_msg, label, admin, uploader, gas, backend,
instantiated_contract=instantiated_contract, code_id=code_id)
Expand All @@ -34,7 +35,7 @@ def migrate(self, label, code_id, code_hash):
new_mint.code_hash = code_hash
return new_mint

def update_config(self, owner=None, silk=None, oracle=None):
def update_config(self, owner=None, silk=None, shade=None, oracle=None):
"""
Updates the minting contract's config
:param owner: New admin
Expand All @@ -51,6 +52,12 @@ def update_config(self, owner=None, silk=None, oracle=None):
"code_hash": silk.code_hash
}
raw_msg["update_config"]["silk"] = contract
if shade is not None:
contract = {
"address": shade.address,
"code_hash": shade.code_hash
}
raw_msg["update_config"]["shade"] = contract
if oracle is not None:
contract = {
"address": oracle.address,
Expand Down
Binary file modified contracts/compiled/mint.wasm.gz
Binary file not shown.
36 changes: 25 additions & 11 deletions contracts/compiled/tester.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@
print(f"\tReceived {sscrt_minted} usSCRT")
assert sscrt_mint_amount == sscrt_minted, f"Minted {sscrt_minted}; expected {sscrt_mint_amount}"

print("Configuring silk")
print("Configuring Silk")
silk = SNIP20(gen_label(8), decimals=6, public_total_supply=True, enable_mint=True, enable_burn=True)
silk_password = silk.set_view_key(account_key, "password")

print("Configuring shade")
print("Configuring Shade")
shade = SNIP20(gen_label(8), decimals=6, public_total_supply=True, enable_mint=True, enable_burn=True)
shade_password = shade.set_view_key(account_key, "password")

Expand All @@ -45,7 +45,7 @@
print(price / (10 ** 18))

print("Configuring Mint contract")
mint = Mint(gen_label(8), silk, oracle)
mint = Mint(gen_label(8), silk, shade, oracle)
silk.set_minters([mint.address])
shade.set_minters([mint.address])
mint.register_asset(sscrt)
Expand All @@ -61,21 +61,35 @@
total_sent = 0

for i in range(total_tests):
send_amount = random.randint(minimum_amount, int(total_amount / total_tests) - 1)
send_amount = random.randint(minimum_amount, int(total_amount / total_tests / 2) - 1)
total_sent += send_amount

print(f"\tSending {send_amount} usSCRT")
# {"snip_msg_hook": {
# "minimum_expected_amount": "1",
# "mint_type": {"mint_silk": {}}}}
mint_option = "eyJtaW5pbXVtX2V4cGVjdGVkX2Ftb3VudCI6ICIxIiwgIm1pbnRfdHlwZSI6IHsibWludF9zaWxrIjoge319fQ=="
# {
# "minimum_expected_amount": "1",
# "mint_type": {"mint_silk": {}}}
mint_silk = "eyJtaW5pbXVtX2V4cGVjdGVkX2Ftb3VudCI6ICIxIiwgIm1pbnRfdHlwZSI6IHsibWludF9zaWxrIjoge319fQ=="
# This one will fail because mint will never exceed its expected amount
# mint_option = "eyJtaW5pbXVtX2V4cGVjdGVkX2Ftb3VudCI6ICIxNTkzNzA1MTUzMzg1NjAwMDAiLCAibWludF90eXBlIjogeyJtaW50X3NpbGsiOiB7fX19"
print(sscrt.send(account_key, mint.address, send_amount, mint_option))
# {
# "minimum_expected_amount": "1",
# "mint_type": {"mint_shade": {}}}
mint_shade = "eyJtaW5pbXVtX2V4cGVjdGVkX2Ftb3VudCI6ICIxIiwibWludF90eXBlIjogeyJtaW50X3NoYWRlIjoge319fQ=="

mint_silk_response = sscrt.send(account_key, mint.address, send_amount, mint_silk)
if mint_silk_response["plaintext_error"] != "":
print(f"Silk mint error: {mint_silk_response['plaintext_error']}")

mint_shade_response = sscrt.send(account_key, mint.address, send_amount, mint_shade)
if mint_shade_response["plaintext_error"] != "":
print(f"Shade mint error: {mint_shade_response['plaintext_error']}")

silk_minted = silk.get_balance(account, silk_password)
shade_minted = shade.get_balance(account, shade_password)
# assert total_sent == int(silk_minted), f"Total minted {silk_minted}; expected {total_sent}"

print(f"\tSilk balance: {silk_minted} uSILK")
print(f"\tShade balance: {shade_minted} uSHD")
burned_amount = mint.get_asset(sscrt)["asset"]["asset"]["burned_tokens"]
print(f"\tTotal burned: {burned_amount} usSCRT\n")
# assert total_sent == int(burned_amount), f"Burnt {burned_amount}; expected {total_sent}"
Expand Down Expand Up @@ -167,15 +181,15 @@
mint_instantiated_contract = PreInstantiatedContract(
address=contracts_config["mint"]["address"],
code_hash=contracts_config["mint"]["code_hash"])
mint = Mint(contracts_config["mint"]["label"], silk, oracle, admin=account, uploader=account, backend=None,
mint = Mint(contracts_config["mint"]["label"], silk, shade, oracle, admin=account, uploader=account, backend=None,
instantiated_contract=mint_instantiated_contract, code_id=contracts_config["mint"]["contract_id"])

if mint_checksum.readline().strip() != contracts_config["mint"]["checksum"].strip():
print("Instantiating Mint")
mint_updated = True
label = f"mint-{gen_label(8)}"
# TODO: upload and get codehash + id of the contract without instantiating to call the mint.migrate
new_mint = Mint(label, silk, oracle, admin=account, uploader=account, backend=None)
new_mint = Mint(label, silk, shade, oracle, admin=account, uploader=account, backend=None)
# mint.migrate()
mint = copy.deepcopy(new_mint)
contracts_config["mint"]["label"] = label
Expand Down
2 changes: 2 additions & 0 deletions contracts/mint/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ In the msg field of a snip20 send command you must send a base64 encoded json li
{"minimum_expected_amount": "Uint128", "mint_type": { "mint_silk": { } } }
```

The currently supported mint types are ```mint_silk``` and ```mint_shade```

## Contract
Type used in many of the admin commands
```json
Expand Down
84 changes: 60 additions & 24 deletions contracts/mint/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pub fn init<S: Storage, A: Api, Q: Querier>(
Some(admin) => { admin }
},
silk: msg.silk,
shade: msg.shade,
oracle: msg.oracle,
activated: true,
};
Expand Down Expand Up @@ -66,8 +67,9 @@ pub fn handle<S: Storage, A: Api, Q: Querier>(
HandleMsg::UpdateConfig {
owner,
silk,
shade,
oracle
} => try_update_config(deps, env, owner, silk, oracle),
} => try_update_config(deps, env, owner, silk, shade, oracle),
HandleMsg::RegisterAsset {
contract,
} => try_register_asset(deps, &env, contract, None),
Expand Down Expand Up @@ -117,6 +119,7 @@ pub fn try_migrate<S: Storage, A: Api, Q: Querier>(
let init_msg = InitMsg {
admin: Option::from(config_read.owner),
silk: config_read.silk,
shade: config_read.shade,
oracle: config_read.oracle,
initial_assets: Some(initial_assets)
};
Expand All @@ -134,6 +137,7 @@ pub fn try_update_config<S: Storage, A: Api, Q: Querier>(
env: Env,
owner: Option<HumanAddr>,
silk: Option<Contract>,
shade: Option<Contract>,
oracle: Option<Contract>,
) -> StdResult<HandleResponse> {
if !authorized(deps, &env, AllowedAccess::Admin)? {
Expand All @@ -149,6 +153,9 @@ pub fn try_update_config<S: Storage, A: Api, Q: Querier>(
if let Some(silk) = silk {
state.silk = silk;
}
if let Some(shade) = shade {
state.shade = shade;
}
if let Some(oracle) = oracle {
state.oracle = oracle;
}
Expand Down Expand Up @@ -275,25 +282,26 @@ pub fn try_burn<S: Storage, A: Api, Q: Querier>(

// Get mint command
let amount_to_mint: Uint128;
let mint_response: StdResult<(CosmosMsg, Uint128)>;
if let Some(msg) = msg {
let mint_msg: SnipMsgHook = from_binary(&msg)?;
match mint_msg.mint_type {
MintType::MintSilk {} => {
match mint_silk_with_asset(deps, &env, from, amount, mint_msg.minimum_expected_amount) {
Ok(tuple) => {
let (cosmos_msg, amount_returned) = tuple;
messages.push(cosmos_msg);
amount_to_mint = amount_returned;
}
Err(err) => { return Err(err) }
}
}
mint_response = match mint_msg.mint_type {
MintType::MintSilk {} => mint_with_asset(deps, &env, TargetCoin::Silk, from, amount, mint_msg.minimum_expected_amount),
MintType::MintShade {} => mint_with_asset(deps, &env, TargetCoin::Shade, from, amount, mint_msg.minimum_expected_amount)
}
} else {
return Err(StdError::generic_err("data cannot be empty"))
}


// Handle response
match mint_response {
Ok(tuple) => {
let (cosmos_msg, amount_returned) = tuple;
messages.push(cosmos_msg);
amount_to_mint = amount_returned;
}
Err(err) => { return Err(err) }
}

Ok(HandleResponse {
messages,
Expand Down Expand Up @@ -357,9 +365,15 @@ fn register_receive (
cosmos_msg
}

fn mint_silk_with_asset<S: Storage, A: Api, Q: Querier>(
enum TargetCoin {
Silk,
Shade,
}

fn mint_with_asset<S: Storage, A: Api, Q: Querier>(
deps: &mut Extern<S, A, Q>,
env: &Env,
target: TargetCoin,
sender: HumanAddr,
amount: Uint128,
minimum_expected_amount: Uint128,
Expand All @@ -374,28 +388,38 @@ fn mint_silk_with_asset<S: Storage, A: Api, Q: Querier>(
}

// Returned value is x * 10**18
let token_value = call_oracle(&deps, "SCRT".to_string())?;
let token_value = match target {
TargetCoin::Silk => call_oracle(&deps, "SCRT".to_string())?,
TargetCoin::Shade => call_oracle(&deps, "SCRT".to_string())?
FloppyDisck marked this conversation as resolved.
Show resolved Hide resolved
};

// Load the decimal information for both coins
// Get the target coin information
let config = config_read(&deps.storage).load()?;

let target_coin = match target {
TargetCoin::Silk => config.silk,
TargetCoin::Shade => config.shade
};

// Load the decimal information for both coins
let send_decimals = token_info_query(&deps.querier, 1, asset_contract.code_hash,
asset_contract.address)?.decimals as u32;
let silk_decimals = token_info_query(&deps.querier, 1,
config.silk.code_hash.clone(),
config.silk.address.clone())?.decimals as u32;
let target_decimals = token_info_query(&deps.querier, 1,
target_coin.code_hash.clone(),
target_coin.address.clone())?.decimals as u32;

// ( ( token_value * 10**18 ) * ( amount * 10**send_decimals ) ) / ( 10**(18 - ( send_decimals - silk-decimals ) ) )
// This will calculate the total mind value
let amount_to_mint = calculate_mint(token_value, amount, send_decimals, silk_decimals);
let amount_to_mint = calculate_mint(token_value, amount, send_decimals, target_decimals);

// If minimum amount is greater then ignore the process
if minimum_expected_amount > amount_to_mint {
return Err(StdError::generic_err("did not exceed expected amount"))
}

let mint_msg = mint_msg(sender, amount_to_mint, None,
256, config.silk.code_hash,
config.silk.address)?;
256, target_coin.code_hash,
target_coin.address)?;

// Set burned amount
let mut mut_assets = assets_w(&mut deps.storage);
Expand Down Expand Up @@ -464,11 +488,12 @@ mod tests {
}
}

fn dummy_init(admin: String, silk: Contract, oracle: Contract) -> Extern<MockStorage, MockApi, MockQuerier> {
fn dummy_init(admin: String, silk: Contract, shade: Contract, oracle: Contract) -> Extern<MockStorage, MockApi, MockQuerier> {
let mut deps = mock_dependencies(20, &[]);
let msg = InitMsg {
admin: None,
silk,
shade,
oracle,
initial_assets: None
};
Expand All @@ -484,6 +509,7 @@ mod tests {
let msg = InitMsg {
admin: None,
silk: create_contract("", ""),
shade: create_contract("", ""),
oracle: create_contract("", ""),
initial_assets: None
};
Expand All @@ -497,8 +523,9 @@ mod tests {
#[test]
fn config_update() {
let silk_contract = create_contract("silk_contract", "silk_hash");
let shade_contract = create_contract("shade_contract", "shade_hash");
let oracle_contract = create_contract("oracle_contract", "oracle_hash");
let mut deps = dummy_init("admin".to_string(), silk_contract, oracle_contract);
let mut deps = dummy_init("admin".to_string(), silk_contract, shade_contract, oracle_contract);

// Check config is properly updated
let res = query(&deps, QueryMsg::GetConfig {}).unwrap();
Expand All @@ -521,6 +548,7 @@ mod tests {
let msg = HandleMsg::UpdateConfig {
owner: None,
silk: Option::from(new_silk_contract),
shade: None,
oracle: Option::from(new_oracle_contract),
};
let _res = handle(&mut deps, user_env, msg);
Expand All @@ -544,6 +572,7 @@ mod tests {
#[test]
fn user_register_asset() {
let mut deps = dummy_init("admin".to_string(),
create_contract("", ""),
create_contract("", ""),
create_contract("", ""));

Expand Down Expand Up @@ -571,6 +600,7 @@ mod tests {
#[test]
fn admin_register_asset() {
let mut deps = dummy_init("admin".to_string(),
create_contract("", ""),
create_contract("", ""),
create_contract("", ""));

Expand All @@ -594,6 +624,7 @@ mod tests {
#[test]
fn duplicate_register_asset() {
let mut deps = dummy_init("admin".to_string(),
create_contract("", ""),
create_contract("", ""),
create_contract("", ""));

Expand All @@ -620,6 +651,7 @@ mod tests {
#[test]
fn user_update_asset() {
let mut deps = dummy_init("admin".to_string(),
create_contract("", ""),
create_contract("", ""),
create_contract("", ""));

Expand Down Expand Up @@ -649,6 +681,7 @@ mod tests {
#[test]
fn admin_update_asset() {
let mut deps = dummy_init("admin".to_string(),
create_contract("", ""),
create_contract("", ""),
create_contract("", ""));

Expand Down Expand Up @@ -682,6 +715,7 @@ mod tests {
#[test]
fn nonexisting_update_asset() {
let mut deps = dummy_init("admin".to_string(),
create_contract("", ""),
create_contract("", ""),
create_contract("", ""));

Expand Down Expand Up @@ -711,6 +745,7 @@ mod tests {
#[test]
fn receiving_an_asset() {
let mut deps = dummy_init("admin".to_string(),
create_contract("", ""),
create_contract("", ""),
create_contract("", ""));

Expand Down Expand Up @@ -750,6 +785,7 @@ mod tests {
#[test]
fn receiving_an_asset_from_non_supported_asset() {
let mut deps = dummy_init("admin".to_string(),
create_contract("", ""),
create_contract("", ""),
create_contract("", ""));

Expand Down
Loading