Skip to content

Commit

Permalink
add display of winning bid
Browse files Browse the repository at this point in the history
  • Loading branch information
baedrik committed Dec 14, 2020
1 parent 5290ddf commit 6b5466c
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 18 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,21 @@ secretcli tx compute instantiate 1 '{"name": "*token_name*","admin": "*address_w
```
You may include as many address/amount pairs as you like in the initial_balances field.

You will want to create a token for sale as well as a token to bid in, because the auction will currently not allow the sale token and bid token to be the same (there is no reason to swap different amounts of the same fungible token). When the SNIP-721 spec is more fleshed out, this will probably be changed to allow for the exchanging of different NFT token IDs regardless of whether they are part of the same NFT contract or not. Once you have created your test sale and bid tokens, you are ready to create an auction. I have also stored this sealed-bid auction contract on Holodeck-2 testnet. Its code ID is 101.
You will want to create a token for sale as well as a token to bid in, because the auction will currently not allow the sale token and bid token to be the same (there is no reason to swap different amounts of the same fungible token). When the SNIP-721 spec is more fleshed out, this will probably be changed to allow for the exchanging of different NFT token IDs regardless of whether they are part of the same NFT contract or not. Once you have created your test sale and bid tokens, you are ready to create an auction. I have also stored this sealed-bid auction contract on Holodeck-2 testnet. Its code ID is 102.

I have created a bash script file (named auction.sh) to make it easier to use the auction contract. It requires that you have secretcli and jq installed.
You can install jq with
```sh
sudo apt-get install jq
```
The script is expecting the auction contract to have code ID 101, but you can change that on the first line if you store a new version of the contract.
The script is expecting the auction contract to have code ID 102, but you can change that on the first line if you store a new version of the contract.

This script was primarily written as a quick-and-dirty helper for my own testing purposes. If you intend to create a production UI for the contract, when placing a bid, you should follow the example of the script and use the optional padding field when calling a token contract's Send. You will want the number of digits of the send amount + the number of characters in the padding field to be a constant number (I use 40 characters, because the maximum number of digits of Uint128 is 39, and I always want at least one blank in padding). This way you do not leak information about the number of digits of the bid. You do not have to do this for consign, because the consignment amount is public (it is the amount of tokens for sale in the auction), but it will not cause any problems if you also pad the consignment call to Send if the same function is used to Send the tokens for both placing bids, and consigning tokens.

## Creating a new auction
You can create a new auction with
```sh
secretcli tx compute instantiate 101 '{"sell_contract": {"code_hash": "*sale_tokens_code_hash*", "address": "*sale_tokens_contract_address*"}, "bid_contract": {"code_hash": "*bid_tokens_code_hash*", "address": "*bid_tokens_contract_address*"}, "sell_amount": "*amount_being_sold_in_smallest_denomination_of_sale_token*", "minimum_bid": "*minimum_accepted_bid_in_smallest_denomination_of_bid_token*", "description": "*optional_text_description*"}' --from *your_key_alias_or_addr* --label *name_for_the_auction* --gas 300000 -y
secretcli tx compute instantiate 102 '{"sell_contract": {"code_hash": "*sale_tokens_code_hash*", "address": "*sale_tokens_contract_address*"}, "bid_contract": {"code_hash": "*bid_tokens_code_hash*", "address": "*bid_tokens_contract_address*"}, "sell_amount": "*amount_being_sold_in_smallest_denomination_of_sale_token*", "minimum_bid": "*minimum_accepted_bid_in_smallest_denomination_of_bid_token*", "description": "*optional_text_description*"}' --from *your_key_alias_or_addr* --label *name_for_the_auction* --gas 300000 -y
```
You can find a contract's code hash with
```sh
Expand All @@ -72,7 +72,7 @@ There is a lot of info there, so it is best viewed piping it through jq
```sh
secretcli q compute query *auction_contract_address* '{"auction_info":{}}'|jq
```
Status will either be "Closed" if the auction is over, or it will be "Accepting bids". If the auction is accepting bids, auction_info will also tell you if the auction owner has consigned the tokens to be sold to the auction. You may want to wait until the owner consigns the tokens before you bid, but there is no risk in doing it earlier. At any time before the auction closes, you can retract your bid to have your tokens returned to you. But if you wait until the owner consigns his tokens, you can be more sure the owner is likely to finalize the auction, because once the tokens to be sold are consigned to the auction, he can not get his orignal tokens or the bid tokens until he finalizes the auction. The original consigned tokens will only be returned if there are no active bids (either no bids were placed meeting the minimum asking price or all qualifying bids have been retracted). Otherwise, the highest bid placed at the time of closure will be accepted and the swap will take place.
Status will either be "Closed" if the auction is over, or it will be "Accepting bids". If the auction is closed, it will also display the winning bid if there was one. If the auction is accepting bids, auction_info will also tell you if the auction owner has consigned the tokens to be sold to the auction. You may want to wait until the owner consigns the tokens before you bid, but there is no risk in doing it earlier. At any time before the auction closes, you can retract your bid to have your tokens returned to you. But if you wait until the owner consigns his tokens, you can be more sure the owner is likely to finalize the auction, because once the tokens to be sold are consigned to the auction, he can not get his orignal tokens or the bid tokens until he finalizes the auction. The original consigned tokens will only be returned if there are no active bids (either no bids were placed meeting the minimum asking price or all qualifying bids have been retracted). Otherwise, the highest bid placed at the time of closure will be accepted and the swap will take place.

If the auction is closed, it will display if there are any outstanding funds still residing in the auction account. This should never happen, but if it does for some unforeseen reason, it will remind the user to either use retract\_bid to have their bid tokens returned (if they haven't already been returned), or use return\_all to return all the funds still held by the auction. Return\_all can only be called after the auction has closed.

Expand Down
21 changes: 8 additions & 13 deletions WALKTHROUGH.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ pub struct State {
pub tokens_consigned: bool,
/// Optional text description of auction
pub description: Option<String>,
/// winning bid
pub winning_bid: u128,
}

```
Expand Down Expand Up @@ -247,6 +249,9 @@ pub enum QueryAnswer {
/// consigned" or "Closed" (will also state if there are outstanding funds after auction
/// closure
status: String,
/// If the auction resulted in a swap, this will state the winning bid
#[serde(skip_serializing_if = "Option::is_none")]
winning_bid: Option<Uint128>,
},
}

Expand Down Expand Up @@ -433,6 +438,7 @@ Your contract will have an `init` function that will be called whenever it is in
is_completed: false,
tokens_consigned: false,
description: msg.description,
winning_bid: 0,
};

save(&mut deps.storage, CONFIG_KEY, &state)?;
Expand All @@ -447,26 +453,14 @@ This is an example of how to save to storage using the function defined in state
state
.bid_contract
.register_receive_msg(env.contract_code_hash)?,


CallbackHandleMsg::HandleMsgName {
some: "a".to_string(),
data: "b".to_string(),
fields: "c".to_string(),
}
.to_cosmos_msg(
code_hash_of_contract_you_want_to_call,
that_contracts_address,
Some(1000000),
)?,
],
log: vec![],
})
}

```
Now that the auction contract has done everything it needs to do when instantiated, it is time to call other contracts. You do this by first creating the InitResponse. The `messages` field of InitReponse/HandleResponse is a `Vec<CosmosMsg>`. Anytime you want to call another contract, you push the appropriate CosmosMsg onto that Vec.<br/>
First are two examples of calling the RegisterReceive functions of the sell and bid contracts using the `register_receive_msg` functions implemented by the ContractInfo struct defined in msg.rs. Then I've included an example of calling the example HandleMsg defined earlier in the walkthrough, which is also sending 1000000uscrt along with the callback message.
Here are two examples of calling the RegisterReceive functions of the sell and bid contracts using the `register_receive_msg` functions implemented by the ContractInfo struct defined in msg.rs.
```rust
///////////////////////////////////// Handle //////////////////////////////////////
/// Returns HandleResult
Expand Down Expand Up @@ -601,6 +595,7 @@ If you need to query a contract that does not have its own toolkit helpers, you
description: state.description,
auction_address: state.auction_addr,
status,
winning_bid,
})
```
Because QueryResponse is just a Binary, and QueryResult is a `StdResult<QueryResponse>`, all you need to do to create the QueryResult is create an instance of your QueryAnswer enum and pass it to `to_binary` which will serialize it to a JSON string and then convert that to a Binary and return a StdResult wrapping that Binary.
2 changes: 1 addition & 1 deletion auction.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/bin/bash

# Change this to the code ID of the auction contract for whatever chain your secretcli is using
contractcode="101"
contractcode="102"

cat << EOF
Just a reminder that you need to have secretcli and jq installed.
Expand Down
9 changes: 9 additions & 0 deletions src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ pub fn init<S: Storage, A: Api, Q: Querier>(
is_completed: false,
tokens_consigned: false,
description: msg.description,
winning_bid: 0,
};

save(&mut deps.storage, CONFIG_KEY, &state)?;
Expand Down Expand Up @@ -622,6 +623,7 @@ fn try_finalize<S: Storage, A: Api, Q: Querier>(
state.currently_consigned = 0;
update_state = true;
winning_amount = Some(Uint128(winning_bid.bid.amount));
state.winning_bid = winning_bid.bid.amount;
remove(&mut deps.storage, &winning_bid.bidder.as_slice());
state
.bidders
Expand Down Expand Up @@ -738,6 +740,12 @@ fn try_query_info<S: Storage, A: Api, Q: Querier>(deps: &Extern<S, A, Q>) -> Que
)
};

let winning_bid = if state.winning_bid == 0 {
None
} else {
Some(Uint128(state.winning_bid))
};

to_binary(&QueryAnswer::AuctionInfo {
sell_token: Token {
contract_address: state.sell_contract.address,
Expand All @@ -752,5 +760,6 @@ fn try_query_info<S: Storage, A: Api, Q: Querier>(deps: &Extern<S, A, Q>) -> Que
description: state.description,
auction_address: state.auction_addr,
status,
winning_bid,
})
}
3 changes: 3 additions & 0 deletions src/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ pub enum QueryAnswer {
/// consigned" or "Closed" (will also state if there are outstanding funds after auction
/// closure
status: String,
/// If the auction resulted in a swap, this will state the winning bid
#[serde(skip_serializing_if = "Option::is_none")]
winning_bid: Option<Uint128>,
},
}

Expand Down
2 changes: 2 additions & 0 deletions src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ pub struct State {
pub tokens_consigned: bool,
/// Optional text description of auction
pub description: Option<String>,
/// winning bid
pub winning_bid: u128,
}

/// bid data
Expand Down

0 comments on commit 6b5466c

Please sign in to comment.