From 04889a9f43f268a6482244abca5ca96796fa98a6 Mon Sep 17 00:00:00 2001 From: theodore Date: Tue, 16 Jul 2024 19:38:13 +0800 Subject: [PATCH 1/9] feat: add ListedNFTTotalAmountMap --- contract/Forest/ForestContractState.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/contract/Forest/ForestContractState.cs b/contract/Forest/ForestContractState.cs index c21a6ff..6e59878 100755 --- a/contract/Forest/ForestContractState.cs +++ b/contract/Forest/ForestContractState.cs @@ -53,6 +53,11 @@ public partial class ForestContractState : ContractState /// public MappedState OfferTotalAmountMap { get; set; } + /// + /// Collection Symbol -> User Address -> Listing Amount * decimal + /// + public MappedState ListedNFTTotalAmountMap { get; set; } + public SingletonState AIServiceFeeConfig { get; set; } public SingletonState
AIServiceFeeReceiver { get; set; } From 5b0b7bb204aac31cda0d4bfbc831559101f8b30a Mon Sep 17 00:00:00 2001 From: theodore Date: Wed, 17 Jul 2024 15:33:02 +0800 Subject: [PATCH 2/9] feat: modify GetTotalEffectiveListedNFTAmount --- contract/Forest/ForestContractConstants.cs | 2 ++ contract/Forest/ForestContract_Helpers.cs | 24 +++++++++++++++++++++ contract/Forest/ForestContract_Views.cs | 25 +++++++++++++++++++++- 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/contract/Forest/ForestContractConstants.cs b/contract/Forest/ForestContractConstants.cs index 561026f..db5de96 100644 --- a/contract/Forest/ForestContractConstants.cs +++ b/contract/Forest/ForestContractConstants.cs @@ -24,5 +24,7 @@ public partial class ForestContract public const string DefaultAIImageSize256 = "256x256"; public const int DefaultMaxBatchCancelOfferCount= 20; public const int DefaultMaxBatchCancelListCount= 20; + public const string CollectionSymbolSuffix = "0"; + public const string SymbolSeparator = "-"; } \ No newline at end of file diff --git a/contract/Forest/ForestContract_Helpers.cs b/contract/Forest/ForestContract_Helpers.cs index a6955b1..8f627a6 100644 --- a/contract/Forest/ForestContract_Helpers.cs +++ b/contract/Forest/ForestContract_Helpers.cs @@ -309,6 +309,30 @@ private long GetAllowance(Address address, string symbol) }); return allowance?.Allowance ?? 0; } + + public static string TransferCollectionSymbol(string symbol) + { + if (string.IsNullOrEmpty(symbol)) + return symbol; + + var parts = symbol.Split($"{SymbolSeparator}"); + + if (parts.Length == 1) + { + return parts[0]; + } + + if (parts.Length == 2) + { + var baseString = parts[0]; + if (int.TryParse(parts[1], out int number)) + { + return $"{baseString}{SymbolSeparator}{CollectionSymbolSuffix}"; + } + } + + return symbol; + } private void RequireContractAIServiceFeeConfigSet() { diff --git a/contract/Forest/ForestContract_Views.cs b/contract/Forest/ForestContract_Views.cs index e947dfc..b8881ad 100644 --- a/contract/Forest/ForestContract_Views.cs +++ b/contract/Forest/ForestContract_Views.cs @@ -117,11 +117,34 @@ public override GetTotalOfferAmountOutput GetTotalOfferAmount(GetTotalOfferAmoun public override GetTotalEffectiveListedNFTAmountOutput GetTotalEffectiveListedNFTAmount(GetTotalEffectiveListedNFTAmountInput input) { var totalAmount = GetEffectiveListedNFTTotalAmount(input.Address, input.Symbol); + + var collectionSymbol = TransferCollectionSymbol(input.Symbol); + var collectionAllowance = State.ListedNFTTotalAmountMap[collectionSymbol][input.Address]; var allowance = GetAllowance(input.Address, input.Symbol); + if (allowance == 0) + { + return new GetTotalEffectiveListedNFTAmountOutput() + { + Symbol = input.Symbol, + Allowance = allowance, + TotalAmount = totalAmount + }; + } + + if (allowance != 0 && collectionAllowance == "") + { + return new GetTotalEffectiveListedNFTAmountOutput() + { + Symbol = input.Symbol, + Allowance = 0, + TotalAmount = totalAmount + }; + } + var getTotalEffectiveListedNftAmountOutput = new GetTotalEffectiveListedNFTAmountOutput() { Symbol = input.Symbol, - Allowance = allowance, + Allowance = long.Parse(collectionAllowance), TotalAmount = totalAmount }; From 69e31eb36501707749d35ad86965317748d8cf9e Mon Sep 17 00:00:00 2001 From: theodore Date: Wed, 17 Jul 2024 17:16:42 +0800 Subject: [PATCH 3/9] ut: fix ut --- .../InscriptionContractTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Forest.Contracts.Inscription.Tests/InscriptionContractTests.cs b/test/Forest.Contracts.Inscription.Tests/InscriptionContractTests.cs index 0a2b1d6..dd9da13 100644 --- a/test/Forest.Contracts.Inscription.Tests/InscriptionContractTests.cs +++ b/test/Forest.Contracts.Inscription.Tests/InscriptionContractTests.cs @@ -1620,7 +1620,7 @@ await TokenContractStub.Create.SendAsync(new CreateInput }); var seedOwnedSymbol = "ELFS" + "-0"; - var seedExpTime = "1720590467"; + var seedExpTime = "1752076800"; await TokenContractStub.Create.SendAsync(new CreateInput { Symbol = "SEED-1", From 9e80db2f7865c9bda4e47a9319ee3f90d32c4afd Mon Sep 17 00:00:00 2001 From: theodore Date: Wed, 17 Jul 2024 17:27:55 +0800 Subject: [PATCH 4/9] feat: modify GetTotalEffectiveListedNFTAmount --- contract/Forest/ForestContract_Views.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contract/Forest/ForestContract_Views.cs b/contract/Forest/ForestContract_Views.cs index b8881ad..f23524e 100644 --- a/contract/Forest/ForestContract_Views.cs +++ b/contract/Forest/ForestContract_Views.cs @@ -130,8 +130,8 @@ public override GetTotalEffectiveListedNFTAmountOutput GetTotalEffectiveListedNF TotalAmount = totalAmount }; } - - if (allowance != 0 && collectionAllowance == "") + + if (allowance != 0 && (collectionAllowance == null || collectionAllowance == "")) { return new GetTotalEffectiveListedNFTAmountOutput() { From ceda73b1b54c9757ae7280f94c252e30174853fe Mon Sep 17 00:00:00 2001 From: theodore Date: Wed, 17 Jul 2024 19:22:17 +0800 Subject: [PATCH 5/9] feat: modify GetTotalEffectiveListedNFTAmount --- contract/Forest/ForestContract_Helpers.cs | 13 ++++++ contract/Forest/ForestContract_Sellers.cs | 41 +++++++++++++++++++ .../Forest.Tests/ForestContractTests_Views.cs | 4 +- 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/contract/Forest/ForestContract_Helpers.cs b/contract/Forest/ForestContract_Helpers.cs index 8f627a6..5d5d4bf 100644 --- a/contract/Forest/ForestContract_Helpers.cs +++ b/contract/Forest/ForestContract_Helpers.cs @@ -54,6 +54,19 @@ private void PerformDeal(PerformDealInput performDealInput) PurchaseSymbol = performDealInput.PurchaseSymbol, PurchaseAmount = performDealInput.PurchaseAmount }); + var collectionSymbol = TransferCollectionSymbol(performDealInput.NFTSymbol); + var collectionAllowance = State.ListedNFTTotalAmountMap[collectionSymbol][performDealInput.NFTTo]; + if (collectionAllowance == null || collectionAllowance == "") + { + State.ListedNFTTotalAmountMap[collectionSymbol][performDealInput.NFTTo] = ""; + } + else + { + var originQuantity = long.Parse(collectionAllowance); + var resultQuantity = originQuantity - performDealInput.NFTQuantity; + State.ListedNFTTotalAmountMap[collectionSymbol][performDealInput.NFTTo] = + (resultQuantity >= 0 ? resultQuantity : 0).ToString(); + } } private struct PerformDealInput diff --git a/contract/Forest/ForestContract_Sellers.cs b/contract/Forest/ForestContract_Sellers.cs index d816d54..b0cbf62 100644 --- a/contract/Forest/ForestContract_Sellers.cs +++ b/contract/Forest/ForestContract_Sellers.cs @@ -120,6 +120,18 @@ public override Empty ListWithFixedPrice(ListWithFixedPriceInput input) Quantity = input.Quantity, WhitelistId = whitelistId }); + var collectionSymbol = TransferCollectionSymbol(input.Symbol); + var collectionAllowance = State.ListedNFTTotalAmountMap[collectionSymbol][Context.Sender]; + if (collectionAllowance == null || collectionAllowance == "") + { + State.ListedNFTTotalAmountMap[collectionSymbol][Context.Sender] = input.Quantity.ToString(); + } + else + { + var originQuantity = long.Parse(collectionAllowance); + State.ListedNFTTotalAmountMap[collectionSymbol][Context.Sender] = + (input.Quantity + originQuantity).ToString(); + } State.ListedNFTInfoListMap[input.Symbol][Context.Sender] = listedNftInfoList; @@ -211,6 +223,20 @@ private Empty SingleDelist(DelistInput input) Owner = Context.Sender, Quantity = input.Quantity }); + + var collectionSymbol = TransferCollectionSymbol(input.Symbol); + var collectionAllowance = State.ListedNFTTotalAmountMap[collectionSymbol][Context.Sender]; + if (collectionAllowance == null || collectionAllowance == "") + { + State.ListedNFTTotalAmountMap[collectionSymbol][Context.Sender] = ""; + } + else + { + var originQuantity = long.Parse(collectionAllowance); + var resultQuantity = originQuantity - input.Quantity; + State.ListedNFTTotalAmountMap[collectionSymbol][Context.Sender] = + (resultQuantity >= 0 ? resultQuantity.ToString() : ""); + } return new Empty(); } @@ -275,6 +301,9 @@ public override Empty BatchDeList(BatchDeListInput input) return new Empty(); } + var collectionSymbol = TransferCollectionSymbol(input.Symbol); + var collectionAllowance = State.ListedNFTTotalAmountMap[collectionSymbol][Context.Sender]; + foreach (var listedNftInfo in fixedPriceListedNftInfoList) { var projectId = CalculateProjectId(input.Symbol, Context.Sender); @@ -287,6 +316,18 @@ public override Empty BatchDeList(BatchDeListInput input) Owner = listedNftInfo.Owner, Price = listedNftInfo.Price }); + + if (collectionAllowance == null || collectionAllowance == "" || collectionAllowance == "0") + { + continue; + } + + var originQuantity = long.Parse(collectionAllowance); + var resultQuantity = originQuantity - listedNftInfo.Quantity; + State.ListedNFTTotalAmountMap[collectionSymbol][Context.Sender] = + (resultQuantity >= 0 ? resultQuantity : 0).ToString(); + collectionAllowance = State.ListedNFTTotalAmountMap[collectionSymbol][Context.Sender]; + } return new Empty(); diff --git a/test/Forest.Tests/ForestContractTests_Views.cs b/test/Forest.Tests/ForestContractTests_Views.cs index 6417a2d..db7f672 100644 --- a/test/Forest.Tests/ForestContractTests_Views.cs +++ b/test/Forest.Tests/ForestContractTests_Views.cs @@ -375,7 +375,7 @@ await UserTokenContractStub.Approve.SendAsync(new ApproveInput() Symbol = NftSymbol, Address = User1Address })); - getTotalEffectiveListedNftAmount.Allowance.ShouldBe(allowanceQuanlity); + getTotalEffectiveListedNftAmount.Allowance.ShouldBe(0); getTotalEffectiveListedNftAmount.TotalAmount.ShouldBe(0); } @@ -934,7 +934,7 @@ await Seller1ForestContractStub.Delist.SendAsync(new DelistInput Symbol = NftSymbol, Address = User1Address })); - getTotalEffectiveListedNftAmount.Allowance.ShouldBe(sellQuantity*2); + getTotalEffectiveListedNftAmount.Allowance.ShouldBe(sellQuantity); getTotalEffectiveListedNftAmount.TotalAmount.ShouldBe(sellQuantity); } From a343c02890985b8e3cf271ee0c57dccaf0ccd304 Mon Sep 17 00:00:00 2001 From: theodore Date: Thu, 18 Jul 2024 15:28:08 +0800 Subject: [PATCH 6/9] feat: modify GetTotalEffectiveListedNFTAmount --- contract/Forest/ForestContract_Helpers.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contract/Forest/ForestContract_Helpers.cs b/contract/Forest/ForestContract_Helpers.cs index 5d5d4bf..02efc53 100644 --- a/contract/Forest/ForestContract_Helpers.cs +++ b/contract/Forest/ForestContract_Helpers.cs @@ -55,16 +55,16 @@ private void PerformDeal(PerformDealInput performDealInput) PurchaseAmount = performDealInput.PurchaseAmount }); var collectionSymbol = TransferCollectionSymbol(performDealInput.NFTSymbol); - var collectionAllowance = State.ListedNFTTotalAmountMap[collectionSymbol][performDealInput.NFTTo]; + var collectionAllowance = State.ListedNFTTotalAmountMap[collectionSymbol][performDealInput.NFTFrom]; if (collectionAllowance == null || collectionAllowance == "") { - State.ListedNFTTotalAmountMap[collectionSymbol][performDealInput.NFTTo] = ""; + State.ListedNFTTotalAmountMap[collectionSymbol][performDealInput.NFTFrom] = ""; } else { var originQuantity = long.Parse(collectionAllowance); var resultQuantity = originQuantity - performDealInput.NFTQuantity; - State.ListedNFTTotalAmountMap[collectionSymbol][performDealInput.NFTTo] = + State.ListedNFTTotalAmountMap[collectionSymbol][performDealInput.NFTFrom] = (resultQuantity >= 0 ? resultQuantity : 0).ToString(); } } From 54858f1b549ec3791576a22fc5b6a98c02f11781 Mon Sep 17 00:00:00 2001 From: theodore Date: Thu, 18 Jul 2024 17:57:07 +0800 Subject: [PATCH 7/9] feat: modify GetTotalEffectiveListedNFTAmount --- contract/Forest/ForestContract_Views.cs | 20 ++++++------------- .../Forest.Tests/ForestContractTests_Views.cs | 6 +++--- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/contract/Forest/ForestContract_Views.cs b/contract/Forest/ForestContract_Views.cs index f23524e..383756f 100644 --- a/contract/Forest/ForestContract_Views.cs +++ b/contract/Forest/ForestContract_Views.cs @@ -1,3 +1,4 @@ +using System; using AElf.Types; using Google.Protobuf.WellKnownTypes; @@ -121,31 +122,22 @@ public override GetTotalEffectiveListedNFTAmountOutput GetTotalEffectiveListedNF var collectionSymbol = TransferCollectionSymbol(input.Symbol); var collectionAllowance = State.ListedNFTTotalAmountMap[collectionSymbol][input.Address]; var allowance = GetAllowance(input.Address, input.Symbol); - if (allowance == 0) - { - return new GetTotalEffectiveListedNFTAmountOutput() - { - Symbol = input.Symbol, - Allowance = allowance, - TotalAmount = totalAmount - }; - } - if (allowance != 0 && (collectionAllowance == null || collectionAllowance == "")) + if (collectionAllowance == null || collectionAllowance == "") { return new GetTotalEffectiveListedNFTAmountOutput() { Symbol = input.Symbol, - Allowance = 0, - TotalAmount = totalAmount + Allowance = allowance, + TotalAmount = Math.Max(allowance,totalAmount) }; } var getTotalEffectiveListedNftAmountOutput = new GetTotalEffectiveListedNFTAmountOutput() { Symbol = input.Symbol, - Allowance = long.Parse(collectionAllowance), - TotalAmount = totalAmount + Allowance = allowance, + TotalAmount = long.Parse(collectionAllowance) }; return getTotalEffectiveListedNftAmountOutput; diff --git a/test/Forest.Tests/ForestContractTests_Views.cs b/test/Forest.Tests/ForestContractTests_Views.cs index db7f672..9e065af 100644 --- a/test/Forest.Tests/ForestContractTests_Views.cs +++ b/test/Forest.Tests/ForestContractTests_Views.cs @@ -375,8 +375,8 @@ await UserTokenContractStub.Approve.SendAsync(new ApproveInput() Symbol = NftSymbol, Address = User1Address })); - getTotalEffectiveListedNftAmount.Allowance.ShouldBe(0); - getTotalEffectiveListedNftAmount.TotalAmount.ShouldBe(0); + getTotalEffectiveListedNftAmount.Allowance.ShouldBe(1); + getTotalEffectiveListedNftAmount.TotalAmount.ShouldBe(1); } #endregion @@ -934,7 +934,7 @@ await Seller1ForestContractStub.Delist.SendAsync(new DelistInput Symbol = NftSymbol, Address = User1Address })); - getTotalEffectiveListedNftAmount.Allowance.ShouldBe(sellQuantity); + getTotalEffectiveListedNftAmount.Allowance.ShouldBe(sellQuantity*2); getTotalEffectiveListedNftAmount.TotalAmount.ShouldBe(sellQuantity); } From 808e2194baaec35bf97def45c59c200f0d04197c Mon Sep 17 00:00:00 2001 From: theodore Date: Thu, 18 Jul 2024 19:51:38 +0800 Subject: [PATCH 8/9] feat: modify GetTotalEffectiveListedNFTAmount --- contract/Forest/ForestContract_Buyers.cs | 28 +++++++++++++++++++++++ contract/Forest/ForestContract_Helpers.cs | 14 +----------- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/contract/Forest/ForestContract_Buyers.cs b/contract/Forest/ForestContract_Buyers.cs index dd167c3..9a3ab4a 100644 --- a/contract/Forest/ForestContract_Buyers.cs +++ b/contract/Forest/ForestContract_Buyers.cs @@ -346,6 +346,20 @@ private void SingleMakeOfferForBatchBuyNow(string symbol, FixPrice inputFixPrice Quantity = listedNftInfo.Quantity, Price = listedNftInfo.Price, }); + + var collectionSymbol = TransferCollectionSymbol(listedNftInfo.Symbol); + var collectionAllowance = State.ListedNFTTotalAmountMap[collectionSymbol][listedNftInfo.Owner]; + if (collectionAllowance == null || collectionAllowance == "") + { + State.ListedNFTTotalAmountMap[collectionSymbol][listedNftInfo.Owner] = ""; + } + else + { + var originQuantity = long.Parse(collectionAllowance); + var resultQuantity = originQuantity - dealQuantity; + State.ListedNFTTotalAmountMap[collectionSymbol][listedNftInfo.Owner] = + (resultQuantity >= 0 ? resultQuantity : 0).ToString(); + } } } @@ -361,6 +375,20 @@ private void SingleMakeOfferForBatchBuyNow(string symbol, FixPrice inputFixPrice Owner = info.Owner, Price = info.Price }); + var collectionSymbol = TransferCollectionSymbol(info.Symbol); + var collectionAllowance = State.ListedNFTTotalAmountMap[collectionSymbol][info.Owner]; + if (collectionAllowance == null || collectionAllowance == "") + { + State.ListedNFTTotalAmountMap[collectionSymbol][info.Owner] = ""; + } + else + { + var originQuantity = long.Parse(collectionAllowance); + var resultQuantity = originQuantity - info.Quantity; + State.ListedNFTTotalAmountMap[collectionSymbol][info.Owner] = + (resultQuantity >= 0 ? resultQuantity : 0).ToString(); + } + } } diff --git a/contract/Forest/ForestContract_Helpers.cs b/contract/Forest/ForestContract_Helpers.cs index 02efc53..fe5dc3c 100644 --- a/contract/Forest/ForestContract_Helpers.cs +++ b/contract/Forest/ForestContract_Helpers.cs @@ -54,19 +54,7 @@ private void PerformDeal(PerformDealInput performDealInput) PurchaseSymbol = performDealInput.PurchaseSymbol, PurchaseAmount = performDealInput.PurchaseAmount }); - var collectionSymbol = TransferCollectionSymbol(performDealInput.NFTSymbol); - var collectionAllowance = State.ListedNFTTotalAmountMap[collectionSymbol][performDealInput.NFTFrom]; - if (collectionAllowance == null || collectionAllowance == "") - { - State.ListedNFTTotalAmountMap[collectionSymbol][performDealInput.NFTFrom] = ""; - } - else - { - var originQuantity = long.Parse(collectionAllowance); - var resultQuantity = originQuantity - performDealInput.NFTQuantity; - State.ListedNFTTotalAmountMap[collectionSymbol][performDealInput.NFTFrom] = - (resultQuantity >= 0 ? resultQuantity : 0).ToString(); - } + } private struct PerformDealInput From 1c8be44c610b1f4669f14700f75ffb44edb11fed Mon Sep 17 00:00:00 2001 From: theodore Date: Fri, 19 Jul 2024 14:20:29 +0800 Subject: [PATCH 9/9] feat: modify GetTotalEffectiveListedNFTAmount --- contract/Forest/ForestContract_Sellers.cs | 5 ++++- test/Forest.Tests/ForestContractTests_Views.cs | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/contract/Forest/ForestContract_Sellers.cs b/contract/Forest/ForestContract_Sellers.cs index b0cbf62..e9904e6 100644 --- a/contract/Forest/ForestContract_Sellers.cs +++ b/contract/Forest/ForestContract_Sellers.cs @@ -1,3 +1,4 @@ +using System; using System.Linq; using AElf; using AElf.Contracts.MultiToken; @@ -120,11 +121,13 @@ public override Empty ListWithFixedPrice(ListWithFixedPriceInput input) Quantity = input.Quantity, WhitelistId = whitelistId }); + var allowance = GetAllowance(Context.Sender, input.Symbol); var collectionSymbol = TransferCollectionSymbol(input.Symbol); var collectionAllowance = State.ListedNFTTotalAmountMap[collectionSymbol][Context.Sender]; if (collectionAllowance == null || collectionAllowance == "") { - State.ListedNFTTotalAmountMap[collectionSymbol][Context.Sender] = input.Quantity.ToString(); + State.ListedNFTTotalAmountMap[collectionSymbol][Context.Sender] = + Math.Max(allowance, input.Quantity).ToString(); } else { diff --git a/test/Forest.Tests/ForestContractTests_Views.cs b/test/Forest.Tests/ForestContractTests_Views.cs index 9e065af..a9d6213 100644 --- a/test/Forest.Tests/ForestContractTests_Views.cs +++ b/test/Forest.Tests/ForestContractTests_Views.cs @@ -1185,7 +1185,7 @@ await BuyerForestContractStub.MakeOffer.SendAsync(new MakeOfferInput() Address = User1Address })); getTotalEffectiveListedNftAmount.Allowance.ShouldBe(0); - getTotalEffectiveListedNftAmount.TotalAmount.ShouldBe(sellQuantity); + getTotalEffectiveListedNftAmount.TotalAmount.ShouldBe(sellQuantity*2); } #endregion