diff --git a/contract-rs/01-basic-auction/src/lib.rs b/contract-rs/01-basic-auction/src/lib.rs index 567e7df4..13f6cd75 100644 --- a/contract-rs/01-basic-auction/src/lib.rs +++ b/contract-rs/01-basic-auction/src/lib.rs @@ -1,6 +1,6 @@ // Find all our documentation at https://docs.near.org use near_sdk::json_types::U64; -use near_sdk::{env, near,require, AccountId, NearToken, PanicOnDefault, Promise}; +use near_sdk::{env, near, require, AccountId, NearToken, PanicOnDefault, Promise}; #[near(serializers = [json, borsh])] #[derive(Clone)] @@ -86,4 +86,4 @@ mod tests { let end_time = contract.get_auction_end_time(); assert_eq!(end_time, U64::from(1000)); } -} \ No newline at end of file +} diff --git a/contract-rs/01-basic-auction/tests/test_basics.rs b/contract-rs/01-basic-auction/tests/test_basics.rs index f643ff17..8692a531 100644 --- a/contract-rs/01-basic-auction/tests/test_basics.rs +++ b/contract-rs/01-basic-auction/tests/test_basics.rs @@ -60,48 +60,38 @@ async fn test_contract_is_operational() -> Result<(), Box let highest_bid_json = contract.view("get_highest_bid").await?; let highest_bid: Bid = highest_bid_json.json::()?; - assert_eq!( - highest_bid.bid, - NearToken::from_near(1) - ); + assert_eq!(highest_bid.bid, NearToken::from_near(1)); assert_eq!(highest_bid.bidder, *alice.id()); - // Bob makes second bid let bob_bid = bob - .call(contract.id(), "bid") - .deposit(NearToken::from_near(2)) - .transact() - .await?; + .call(contract.id(), "bid") + .deposit(NearToken::from_near(2)) + .transact() + .await?; assert!(bob_bid.is_success()); let highest_bid_json = contract.view("get_highest_bid").await?; let highest_bid: Bid = highest_bid_json.json::()?; - assert_eq!( - highest_bid.bid, - NearToken::from_near(2) - ); + assert_eq!(highest_bid.bid, NearToken::from_near(2)); assert_eq!(highest_bid.bidder, *bob.id()); // Alice makes the third bid but fails let alice_bid = alice - .call(contract.id(), "bid") - .deposit(NearToken::from_near(1)) - .transact() - .await?; + .call(contract.id(), "bid") + .deposit(NearToken::from_near(1)) + .transact() + .await?; assert!(alice_bid.is_failure()); let highest_bid_json = contract.view("get_highest_bid").await?; let highest_bid: Bid = highest_bid_json.json::()?; - assert_eq!( - highest_bid.bid, - NearToken::from_near(2) - ); + assert_eq!(highest_bid.bid, NearToken::from_near(2)); assert_eq!(highest_bid.bidder, *bob.id()); Ok(()) -} \ No newline at end of file +} diff --git a/contract-rs/02-owner-claims-money/src/lib.rs b/contract-rs/02-owner-claims-money/src/lib.rs index 6ebda18c..839667db 100644 --- a/contract-rs/02-owner-claims-money/src/lib.rs +++ b/contract-rs/02-owner-claims-money/src/lib.rs @@ -15,7 +15,7 @@ pub struct Contract { highest_bid: Bid, auction_end_time: U64, auctioneer: AccountId, - auction_was_claimed: bool, + claimed: bool, } #[near] @@ -26,10 +26,10 @@ impl Contract { Self { highest_bid: Bid { bidder: env::current_account_id(), - bid: NearToken::from_yoctonear(0), + bid: NearToken::from_yoctonear(1), }, auction_end_time: end_time, - auction_was_claimed: false, + claimed: false, auctioneer, } } @@ -73,12 +73,11 @@ impl Contract { pub fn claim(&mut self) -> Promise { require!( env::block_timestamp() > self.auction_end_time.into(), - "Auction has ended" + "Auction has not ended yet" ); - - require!(!self.auction_was_claimed, "Auction has been claimed"); - self.auction_was_claimed = true; - let auctioneer = self.auctioneer.clone(); - Promise::new(auctioneer).transfer(self.highest_bid.bid) + + require!(!self.claimed, "Auction has already been claimed"); + self.claimed = true; + Promise::new(self.auctioneer.clone()).transfer(self.highest_bid.bid) } } diff --git a/contract-rs/02-owner-claims-money/tests/test_basics.rs b/contract-rs/02-owner-claims-money/tests/test_basics.rs index 007e62d8..ec58cfd7 100644 --- a/contract-rs/02-owner-claims-money/tests/test_basics.rs +++ b/contract-rs/02-owner-claims-money/tests/test_basics.rs @@ -1,6 +1,6 @@ use chrono::Utc; use contract_rs::Bid; -use near_sdk::{log, NearToken, Gas}; +use near_sdk::{log, Gas, NearToken}; use serde_json::json; const FIVE_NEAR: NearToken = NearToken::from_near(5); @@ -27,11 +27,11 @@ async fn test_contract_is_operational() -> Result<(), Box .unwrap(); let auctioneer = root - .create_subaccount("auctioneer") - .initial_balance(FIVE_NEAR) - .transact() - .await? - .unwrap(); + .create_subaccount("auctioneer") + .initial_balance(FIVE_NEAR) + .transact() + .await? + .unwrap(); let contract_account = root .create_subaccount("contract") @@ -67,56 +67,46 @@ async fn test_contract_is_operational() -> Result<(), Box let highest_bid_json = contract.view("get_highest_bid").await?; let highest_bid: Bid = highest_bid_json.json::()?; - assert_eq!( - highest_bid.bid, - NearToken::from_near(1) - ); + assert_eq!(highest_bid.bid, NearToken::from_near(1)); assert_eq!(highest_bid.bidder, *alice.id()); - // Bob makes second bid let bob_bid = bob - .call(contract.id(), "bid") - .deposit(NearToken::from_near(2)) - .transact() - .await?; + .call(contract.id(), "bid") + .deposit(NearToken::from_near(2)) + .transact() + .await?; assert!(bob_bid.is_success()); let highest_bid_json = contract.view("get_highest_bid").await?; let highest_bid: Bid = highest_bid_json.json::()?; - assert_eq!( - highest_bid.bid, - NearToken::from_near(2) - ); + assert_eq!(highest_bid.bid, NearToken::from_near(2)); assert_eq!(highest_bid.bidder, *bob.id()); // Alice makes the third bid but fails let alice_bid = alice - .call(contract.id(), "bid") - .deposit(NearToken::from_near(1)) - .transact() - .await?; + .call(contract.id(), "bid") + .deposit(NearToken::from_near(1)) + .transact() + .await?; assert!(alice_bid.is_failure()); let highest_bid_json = contract.view("get_highest_bid").await?; let highest_bid: Bid = highest_bid_json.json::()?; - assert_eq!( - highest_bid.bid, - NearToken::from_near(2) - ); + assert_eq!(highest_bid.bid, NearToken::from_near(2)); assert_eq!(highest_bid.bidder, *bob.id()); // Auctioneer claims auction but did not finish let auctioneer_claim = auctioneer - .call(contract_account.id(), "claim") - .args_json(json!({})) - .gas(Gas::from_tgas(300)) - .transact() - .await?; + .call(contract_account.id(), "claim") + .args_json(json!({})) + .gas(Gas::from_tgas(300)) + .transact() + .await?; assert!(auctioneer_claim.is_failure()); // Fast forward @@ -125,23 +115,25 @@ async fn test_contract_is_operational() -> Result<(), Box sandbox.fast_forward(blocks_to_advance).await?; let auctioneer_claim = auctioneer - .call(contract_account.id(), "claim") - .args_json(json!({})) - .gas(Gas::from_tgas(300)) - .transact() - .await?; + .call(contract_account.id(), "claim") + .args_json(json!({})) + .gas(Gas::from_tgas(300)) + .transact() + .await?; assert!(auctioneer_claim.is_success()); + // TODO: Assert the auctioneer got the money + // Auctioneer claims auction back but fails - let auctioneer_claim =auctioneer - .call(contract_account.id(), "claim") - .args_json(json!({})) - .gas(Gas::from_tgas(300)) - .transact() - .await?; + let auctioneer_claim = auctioneer + .call(contract_account.id(), "claim") + .args_json(json!({})) + .gas(Gas::from_tgas(300)) + .transact() + .await?; assert!(auctioneer_claim.is_failure()); Ok(()) -} \ No newline at end of file +} diff --git a/contract-rs/03-owner-claims-winner-gets-nft/src/lib.rs b/contract-rs/03-owner-claims-winner-gets-nft/src/lib.rs index 1d66750e..3437ef8a 100644 --- a/contract-rs/03-owner-claims-winner-gets-nft/src/lib.rs +++ b/contract-rs/03-owner-claims-winner-gets-nft/src/lib.rs @@ -1,6 +1,6 @@ // Find all our documentation at https://docs.near.org -use near_sdk::json_types::{U64}; -use near_sdk::{env, near, require, AccountId, Gas, NearToken, PanicOnDefault,Promise}; +use near_sdk::json_types::U64; +use near_sdk::{env, near, require, AccountId, Gas, NearToken, PanicOnDefault, Promise}; pub mod ext; pub use crate::ext::*; @@ -20,7 +20,7 @@ pub struct Contract { highest_bid: Bid, auction_end_time: U64, auctioneer: AccountId, - auction_was_claimed: bool, + claimed: bool, nft_contract: AccountId, token_id: TokenId, } @@ -38,11 +38,11 @@ impl Contract { Self { highest_bid: Bid { bidder: env::current_account_id(), - bid: NearToken::from_yoctonear(0), + bid: NearToken::from_yoctonear(1), }, auction_end_time: end_time, auctioneer, - auction_was_claimed: false, + claimed: false, nft_contract, token_id, } @@ -86,12 +86,11 @@ impl Contract { "Auction has not ended yet" ); - assert!(!self.auction_was_claimed, "Auction has been claimed"); + assert!(!self.claimed, "Auction has already been claimed"); - self.auction_was_claimed = true; - let auctioneer = self.auctioneer.clone(); + self.claimed = true; - Promise::new(auctioneer).transfer(self.highest_bid.bid); + Promise::new(self.auctioneer.clone()).transfer(self.highest_bid.bid); nft_contract::ext(self.nft_contract.clone()) .with_static_gas(Gas::from_tgas(30)) diff --git a/contract-rs/03-owner-claims-winner-gets-nft/tests/test_basics.rs b/contract-rs/03-owner-claims-winner-gets-nft/tests/test_basics.rs index 8c8b2ab6..3b7642a4 100644 --- a/contract-rs/03-owner-claims-winner-gets-nft/tests/test_basics.rs +++ b/contract-rs/03-owner-claims-winner-gets-nft/tests/test_basics.rs @@ -45,11 +45,11 @@ async fn test_contract_is_operational() -> Result<(), Box .unwrap(); let auctioneer = root - .create_subaccount("auctioneer") - .initial_balance(FIVE_NEAR) - .transact() - .await? - .unwrap(); + .create_subaccount("auctioneer") + .initial_balance(FIVE_NEAR) + .transact() + .await? + .unwrap(); let contract_account = root .create_subaccount("contract") @@ -96,10 +96,10 @@ async fn test_contract_is_operational() -> Result<(), Box // Alice makes first bid let alice_bid = alice - .call(contract.id(), "bid") - .deposit(NearToken::from_near(1)) - .transact() - .await?; + .call(contract.id(), "bid") + .deposit(NearToken::from_near(1)) + .transact() + .await?; assert!(alice_bid.is_success()); @@ -115,10 +115,10 @@ async fn test_contract_is_operational() -> Result<(), Box // Bob makes second bid let bob_bid = bob - .call(contract.id(), "bid") - .deposit(NearToken::from_near(2)) - .transact() - .await?; + .call(contract.id(), "bid") + .deposit(NearToken::from_near(2)) + .transact() + .await?; assert!(bob_bid.is_success()); @@ -133,10 +133,10 @@ async fn test_contract_is_operational() -> Result<(), Box // Alice makes the third bid but fails let alice_bid = alice - .call(contract.id(), "bid") - .deposit(NearToken::from_near(1)) - .transact() - .await?; + .call(contract.id(), "bid") + .deposit(NearToken::from_near(1)) + .transact() + .await?; assert!(alice_bid.is_failure()); @@ -151,11 +151,11 @@ async fn test_contract_is_operational() -> Result<(), Box // Auctioneer claims auction but did not finish let auctioneer_claim = auctioneer - .call(contract_account.id(), "claim") - .args_json(json!({})) - .gas(Gas::from_tgas(300)) - .transact() - .await?; + .call(contract_account.id(), "claim") + .args_json(json!({})) + .gas(Gas::from_tgas(300)) + .transact() + .await?; assert!(auctioneer_claim.is_failure()); // Fast forward @@ -164,21 +164,25 @@ async fn test_contract_is_operational() -> Result<(), Box sandbox.fast_forward(blocks_to_advance).await?; let auctioneer_claim = auctioneer - .call(contract_account.id(), "claim") - .args_json(json!({})) - .gas(Gas::from_tgas(300)) - .transact() - .await?; + .call(contract_account.id(), "claim") + .args_json(json!({})) + .gas(Gas::from_tgas(300)) + .transact() + .await?; assert!(auctioneer_claim.is_success()); + // TODO: + // Auctioneer has the balance + // NFT is transferred to the highest bidder + // Auctioneer claims auction back but fails - let auctioneer_claim =auctioneer - .call(contract_account.id(), "claim") - .args_json(json!({})) - .gas(Gas::from_tgas(300)) - .transact() - .await?; + let auctioneer_claim = auctioneer + .call(contract_account.id(), "claim") + .args_json(json!({})) + .gas(Gas::from_tgas(300)) + .transact() + .await?; assert!(auctioneer_claim.is_failure()); diff --git a/contract-rs/04-ft-owner-claims-winner-gets-nft/src/lib.rs b/contract-rs/04-ft-owner-claims-winner-gets-nft/src/lib.rs index 1d385126..8b487cee 100644 --- a/contract-rs/04-ft-owner-claims-winner-gets-nft/src/lib.rs +++ b/contract-rs/04-ft-owner-claims-winner-gets-nft/src/lib.rs @@ -20,7 +20,7 @@ pub struct Contract { highest_bid: Bid, auction_end_time: U64, auctioneer: AccountId, - auction_was_claimed: bool, + claimed: bool, ft_contract: AccountId, nft_contract: AccountId, token_id: TokenId, @@ -44,7 +44,7 @@ impl Contract { }, auction_end_time: end_time, auctioneer, - auction_was_claimed: false, + claimed: false, ft_contract, nft_contract, token_id, @@ -61,15 +61,14 @@ impl Contract { "Auction has not ended yet" ); - assert!(!self.auction_was_claimed, "Auction has been claimed"); + assert!(!self.claimed, "Auction has been claimed"); - self.auction_was_claimed = true; - let auctioneer = self.auctioneer.clone(); + self.claimed = true; ft_contract::ext(self.ft_contract.clone()) .with_attached_deposit(NearToken::from_yoctonear(1)) .with_static_gas(Gas::from_tgas(30)) - .ft_transfer(auctioneer, self.highest_bid.bid); + .ft_transfer(self.auctioneer.clone(), self.highest_bid.bid); nft_contract::ext(self.nft_contract.clone()) .with_static_gas(Gas::from_tgas(30)) @@ -77,6 +76,7 @@ impl Contract { .nft_transfer(self.highest_bid.bidder.clone(), self.token_id.clone()); } + // Users bid by transferring FT tokens pub fn ft_on_transfer(&mut self, sender_id: AccountId, amount: U128, msg: String) -> U128 { require!( env::block_timestamp() < self.auction_end_time.into(), diff --git a/contract-ts/01-basic-auction/src/contract.ts b/contract-ts/01-basic-auction/src/contract.ts index 03a5792c..484fa957 100644 --- a/contract-ts/01-basic-auction/src/contract.ts +++ b/contract-ts/01-basic-auction/src/contract.ts @@ -11,12 +11,10 @@ class AuctionContract { highest_bid: Bid = { bidder: '', bid: BigInt(0) }; auction_end_time: bigint = BigInt(0); - @initialize({ privateFunction: true }) init({ end_time}: { end_time: bigint}) { this.auction_end_time = end_time; - this.highest_bid = { bidder: near.currentAccountId(), bid: BigInt(0) }; - + this.highest_bid = { bidder: near.currentAccountId(), bid: BigInt(1) }; } @call({ payableFunction: true }) @@ -35,7 +33,7 @@ class AuctionContract { assert(bid > lastBid, "You must place a higher bid"); // Update the highest bid - this.highest_bid = { bidder, bid }; // Save the new bid + this.highest_bid = { bidder, bid }; // Transfer tokens back to the last bidder return NearPromise.new(lastBidder).transfer(lastBid); diff --git a/contract-ts/02-owner-claims-money/src/contract.ts b/contract-ts/02-owner-claims-money/src/contract.ts index 93a9f04f..17fb7314 100644 --- a/contract-ts/02-owner-claims-money/src/contract.ts +++ b/contract-ts/02-owner-claims-money/src/contract.ts @@ -6,20 +6,17 @@ class Bid { bid: bigint; } -const THIRTY_TGAS = BigInt("20000000000000"); -const NO_DEPOSIT = BigInt(0); - @NearBindgen({ requireInit: true }) class AuctionContract { highest_bid: Bid = { bidder: '', bid: BigInt(0) }; auction_end_time: bigint = BigInt(0); auctioneer: string = ""; - auction_was_claimed: boolean = false; + claimed: boolean = false; @initialize({ privateFunction: true }) init({ end_time, auctioneer}: { end_time: bigint, auctioneer: string}) { this.auction_end_time = end_time; - this.highest_bid = { bidder: near.currentAccountId(), bid: BigInt(0) }; + this.highest_bid = { bidder: near.currentAccountId(), bid: BigInt(1) }; this.auctioneer = auctioneer; } @@ -57,15 +54,9 @@ class AuctionContract { @call({}) claim() { - assert(this.auction_end_time <= near.blockTimestamp(), "Auction has not ended yet"); - assert(!this.auction_was_claimed, "Auction has been claimed"); - - this.auction_was_claimed = true; - - + assert(!this.claimed, "Auction has been claimed"); + this.claimed = true; return NearPromise.new(this.auctioneer).transfer(this.highest_bid.bid) - } - } \ No newline at end of file diff --git a/contract-ts/03-owner-claims-winner-gets-nft/src/contract.ts b/contract-ts/03-owner-claims-winner-gets-nft/src/contract.ts index 8ec07fc6..6be4f2b1 100644 --- a/contract-ts/03-owner-claims-winner-gets-nft/src/contract.ts +++ b/contract-ts/03-owner-claims-winner-gets-nft/src/contract.ts @@ -6,7 +6,7 @@ class Bid { bid: bigint; } -const THIRTY_TGAS = BigInt("20000000000000"); +const TWENTY_TGAS = BigInt("20000000000000"); const NO_DEPOSIT = BigInt(0); @NearBindgen({ requireInit: true }) @@ -14,14 +14,14 @@ class AuctionContract { highest_bid: Bid = { bidder: '', bid: BigInt(0) }; auction_end_time: bigint = BigInt(0); auctioneer: string = ""; - auction_was_claimed: boolean = false; + claimed: boolean = false; nft_contract: AccountId = ""; token_id: string = ""; @initialize({ privateFunction: true }) init({ end_time, auctioneer, nft_contract, token_id }: { end_time: bigint, auctioneer: string, nft_contract: AccountId, token_id: string }) { this.auction_end_time = end_time; - this.highest_bid = { bidder: near.currentAccountId(), bid: BigInt(0) }; + this.highest_bid = { bidder: near.currentAccountId(), bid: BigInt(1) }; this.auctioneer = auctioneer; this.nft_contract = nft_contract; this.token_id = token_id; @@ -61,26 +61,20 @@ class AuctionContract { @call({}) claim() { - assert(this.auction_end_time <= near.blockTimestamp(), "Auction has not ended yet"); - assert(!this.auction_was_claimed, "Auction has been claimed"); + assert(!this.claimed, "Auction has been claimed"); + this.claimed = true; - this.auction_was_claimed = true; - - return NearPromise.new(this.nft_contract) - .functionCall("nft_transfer", JSON.stringify({ receiver_id: this.highest_bid.bidder, token_id: this.token_id }), BigInt(1), THIRTY_TGAS) - .and(NearPromise.new(this.auctioneer).transfer(this.highest_bid.bid)) - .then( - NearPromise.new(near.currentAccountId()) - .functionCall("nft_transfer_callback", JSON.stringify({}), NO_DEPOSIT, THIRTY_TGAS) + .functionCall( + "nft_transfer", + JSON.stringify({ receiver_id: this.highest_bid.bidder, token_id: this.token_id }), + BigInt(1), + TWENTY_TGAS + ) + .and( + NearPromise.new(this.auctioneer).transfer(this.highest_bid.bid) ) .asReturn() - } - - @call({ privateFunction: true }) - nft_transfer_callback({ }): BigInt { - return BigInt(0); - } -} \ No newline at end of file +} diff --git a/contract-ts/04-ft-owner-claims-winner-gets-nft/src/contract.ts b/contract-ts/04-ft-owner-claims-winner-gets-nft/src/contract.ts index de6b7958..2a4af592 100644 --- a/contract-ts/04-ft-owner-claims-winner-gets-nft/src/contract.ts +++ b/contract-ts/04-ft-owner-claims-winner-gets-nft/src/contract.ts @@ -14,7 +14,7 @@ class AuctionContract { highest_bid: Bid = { bidder: '', bid: BigInt(1) }; auction_end_time: bigint = BigInt(0); auctioneer: string = ""; - auction_was_claimed: boolean = false; + claimed: boolean = false; ft_contract: AccountId = ""; nft_contract: AccountId = ""; token_id: string = ""; @@ -41,25 +41,17 @@ class AuctionContract { @call({}) claim() { - assert(this.auction_end_time <= near.blockTimestamp(), "Auction has not ended yet"); - assert(!this.auction_was_claimed, "Auction has been claimed"); + assert(!this.claimed, "Auction has been claimed"); - this.auction_was_claimed = true; + this.claimed = true; return NearPromise.new(this.nft_contract) .functionCall("nft_transfer", JSON.stringify({ receiver_id: this.highest_bid.bidder, token_id: this.token_id }), BigInt(1), THIRTY_TGAS) - .and(NearPromise.new(this.ft_contract) + .and( + NearPromise.new(this.ft_contract) .functionCall("ft_transfer", JSON.stringify({ receiver_id: this.auctioneer, amount: this.highest_bid.bid }), BigInt(1), THIRTY_TGAS) - .then( - NearPromise.new(near.currentAccountId()) - .functionCall("ft_transfer_callback", JSON.stringify({}), NO_DEPOSIT, THIRTY_TGAS) - )) - .then( - NearPromise.new(near.currentAccountId()) - .functionCall("nft_transfer_callback", JSON.stringify({}), NO_DEPOSIT, THIRTY_TGAS) - ) - .asReturn() + ).asReturn() } @call({}) @@ -95,9 +87,4 @@ class AuctionContract { ft_transfer_callback({ }): BigInt { return BigInt(0); } - - @call({ privateFunction: true }) - nft_transfer_callback({ }): BigInt { - return BigInt(0); - } } \ No newline at end of file