From 964363049556c82f53d5c6505f6ac4a0fc360dde Mon Sep 17 00:00:00 2001
From: Jecket1 <134037206+Jecket1@users.noreply.github.com>
Date: Fri, 19 Jul 2024 16:20:17 +0800
Subject: [PATCH 1/5] Collection approve (#168)
* feat: add ListedNFTTotalAmountMap
* ut: fix ut
* feat: modify GetTotalEffectiveListedNFTAmount
---
contract/Forest/ForestContractConstants.cs | 2 +
contract/Forest/ForestContractState.cs | 5 +++
contract/Forest/ForestContract_Buyers.cs | 28 ++++++++++++
contract/Forest/ForestContract_Helpers.cs | 25 +++++++++++
contract/Forest/ForestContract_Sellers.cs | 44 +++++++++++++++++++
contract/Forest/ForestContract_Views.cs | 17 ++++++-
.../InscriptionContractTests.cs | 2 +-
.../Forest.Tests/ForestContractTests_Views.cs | 6 +--
8 files changed, 124 insertions(+), 5 deletions(-)
diff --git a/contract/Forest/ForestContractConstants.cs b/contract/Forest/ForestContractConstants.cs
index 561026f1..db5de96e 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/ForestContractState.cs b/contract/Forest/ForestContractState.cs
index c21a6ff0..6e598787 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; }
diff --git a/contract/Forest/ForestContract_Buyers.cs b/contract/Forest/ForestContract_Buyers.cs
index dd167c35..9a3ab4ab 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 a6955b1f..fe5dc3cc 100644
--- a/contract/Forest/ForestContract_Helpers.cs
+++ b/contract/Forest/ForestContract_Helpers.cs
@@ -54,6 +54,7 @@ private void PerformDeal(PerformDealInput performDealInput)
PurchaseSymbol = performDealInput.PurchaseSymbol,
PurchaseAmount = performDealInput.PurchaseAmount
});
+
}
private struct PerformDealInput
@@ -309,6 +310,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_Sellers.cs b/contract/Forest/ForestContract_Sellers.cs
index d816d548..e9904e6c 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,6 +121,20 @@ 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] =
+ Math.Max(allowance, 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 +226,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 +304,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 +319,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/contract/Forest/ForestContract_Views.cs b/contract/Forest/ForestContract_Views.cs
index e947dfc9..383756f6 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;
@@ -117,12 +118,26 @@ 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 (collectionAllowance == null || collectionAllowance == "")
+ {
+ return new GetTotalEffectiveListedNFTAmountOutput()
+ {
+ Symbol = input.Symbol,
+ Allowance = allowance,
+ TotalAmount = Math.Max(allowance,totalAmount)
+ };
+ }
+
var getTotalEffectiveListedNftAmountOutput = new GetTotalEffectiveListedNFTAmountOutput()
{
Symbol = input.Symbol,
Allowance = allowance,
- TotalAmount = totalAmount
+ TotalAmount = long.Parse(collectionAllowance)
};
return getTotalEffectiveListedNftAmountOutput;
diff --git a/test/Forest.Contracts.Inscription.Tests/InscriptionContractTests.cs b/test/Forest.Contracts.Inscription.Tests/InscriptionContractTests.cs
index 0a2b1d6d..dd9da133 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",
diff --git a/test/Forest.Tests/ForestContractTests_Views.cs b/test/Forest.Tests/ForestContractTests_Views.cs
index 6417a2d0..a9d62136 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(allowanceQuanlity);
- getTotalEffectiveListedNftAmount.TotalAmount.ShouldBe(0);
+ getTotalEffectiveListedNftAmount.Allowance.ShouldBe(1);
+ getTotalEffectiveListedNftAmount.TotalAmount.ShouldBe(1);
}
#endregion
@@ -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
From b101522277acceb853c77d5d6eb572513970e784 Mon Sep 17 00:00:00 2001
From: Jecket1 <134037206+Jecket1@users.noreply.github.com>
Date: Fri, 19 Jul 2024 18:24:43 +0800
Subject: [PATCH 2/5] Collection approve (#168) (#170) (#171)
* feat: add ListedNFTTotalAmountMap
* ut: fix ut
* feat: modify GetTotalEffectiveListedNFTAmount
From f819a1a2407b90824f42b71a25ecfa9345f972fe Mon Sep 17 00:00:00 2001
From: kevin
Date: Wed, 24 Jul 2024 17:48:38 +0800
Subject: [PATCH 3/5] optimize max approve
---
contract/Forest/ForestContractConstants.cs | 2 ++
contract/Forest/ForestContract_Sellers.cs | 10 ++++++----
contract/Forest/ForestContract_Views.cs | 4 ++--
3 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/contract/Forest/ForestContractConstants.cs b/contract/Forest/ForestContractConstants.cs
index db5de96e..28871187 100644
--- a/contract/Forest/ForestContractConstants.cs
+++ b/contract/Forest/ForestContractConstants.cs
@@ -26,5 +26,7 @@ public partial class ForestContract
public const int DefaultMaxBatchCancelListCount= 20;
public const string CollectionSymbolSuffix = "0";
public const string SymbolSeparator = "-";
+ public const long DefaultApproveAllowance = 10000;
+ public const long MaxApproveAllowance = 9223372036854775000;
}
\ No newline at end of file
diff --git a/contract/Forest/ForestContract_Sellers.cs b/contract/Forest/ForestContract_Sellers.cs
index e9904e6c..bf58488c 100644
--- a/contract/Forest/ForestContract_Sellers.cs
+++ b/contract/Forest/ForestContract_Sellers.cs
@@ -126,12 +126,14 @@ public override Empty ListWithFixedPrice(ListWithFixedPriceInput input)
var collectionAllowance = State.ListedNFTTotalAmountMap[collectionSymbol][Context.Sender];
if (collectionAllowance == null || collectionAllowance == "")
{
- State.ListedNFTTotalAmountMap[collectionSymbol][Context.Sender] =
- Math.Max(allowance, input.Quantity).ToString();
+ var listedNFTTotalAmount = (allowance == MaxApproveAllowance) ? input.Quantity : Math.Max(allowance, input.Quantity);
+ State.ListedNFTTotalAmountMap[collectionSymbol][Context.Sender] = listedNFTTotalAmount.ToString();
}
else
{
- var originQuantity = long.Parse(collectionAllowance);
+ var originQuantity = (long.Parse(collectionAllowance) == MaxApproveAllowance)
+ ? DefaultApproveAllowance
+ : long.Parse(collectionAllowance);
State.ListedNFTTotalAmountMap[collectionSymbol][Context.Sender] =
(input.Quantity + originQuantity).ToString();
}
@@ -238,7 +240,7 @@ private Empty SingleDelist(DelistInput input)
var originQuantity = long.Parse(collectionAllowance);
var resultQuantity = originQuantity - input.Quantity;
State.ListedNFTTotalAmountMap[collectionSymbol][Context.Sender] =
- (resultQuantity >= 0 ? resultQuantity.ToString() : "");
+ (resultQuantity >= 0 ? resultQuantity.ToString() : "0");
}
return new Empty();
diff --git a/contract/Forest/ForestContract_Views.cs b/contract/Forest/ForestContract_Views.cs
index 383756f6..02a474bd 100644
--- a/contract/Forest/ForestContract_Views.cs
+++ b/contract/Forest/ForestContract_Views.cs
@@ -129,7 +129,7 @@ public override GetTotalEffectiveListedNFTAmountOutput GetTotalEffectiveListedNF
{
Symbol = input.Symbol,
Allowance = allowance,
- TotalAmount = Math.Max(allowance,totalAmount)
+ TotalAmount = (allowance == MaxApproveAllowance) ? totalAmount : Math.Max(allowance,totalAmount)
};
}
@@ -137,7 +137,7 @@ public override GetTotalEffectiveListedNFTAmountOutput GetTotalEffectiveListedNF
{
Symbol = input.Symbol,
Allowance = allowance,
- TotalAmount = long.Parse(collectionAllowance)
+ TotalAmount = (long.Parse(collectionAllowance) == MaxApproveAllowance) ? DefaultApproveAllowance : long.Parse(collectionAllowance)
};
return getTotalEffectiveListedNftAmountOutput;
From 1d09f65b87a7b75af54eedbdf9cc26cf47e01f17 Mon Sep 17 00:00:00 2001
From: kevin
Date: Wed, 24 Jul 2024 19:51:22 +0800
Subject: [PATCH 4/5] fix issue
---
contract/Forest/ForestContractConstants.cs | 5 +++--
contract/Forest/ForestContract_Sellers.cs | 4 ++--
contract/Forest/ForestContract_Views.cs | 4 ++--
3 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/contract/Forest/ForestContractConstants.cs b/contract/Forest/ForestContractConstants.cs
index 28871187..c92dc0bf 100644
--- a/contract/Forest/ForestContractConstants.cs
+++ b/contract/Forest/ForestContractConstants.cs
@@ -27,6 +27,7 @@ public partial class ForestContract
public const string CollectionSymbolSuffix = "0";
public const string SymbolSeparator = "-";
public const long DefaultApproveAllowance = 10000;
- public const long MaxApproveAllowance = 9223372036854775000;
-
+ public const long MaxApproveAllowance = 9223372036854770000;
+
+
}
\ No newline at end of file
diff --git a/contract/Forest/ForestContract_Sellers.cs b/contract/Forest/ForestContract_Sellers.cs
index bf58488c..3e5cd019 100644
--- a/contract/Forest/ForestContract_Sellers.cs
+++ b/contract/Forest/ForestContract_Sellers.cs
@@ -126,12 +126,12 @@ public override Empty ListWithFixedPrice(ListWithFixedPriceInput input)
var collectionAllowance = State.ListedNFTTotalAmountMap[collectionSymbol][Context.Sender];
if (collectionAllowance == null || collectionAllowance == "")
{
- var listedNFTTotalAmount = (allowance == MaxApproveAllowance) ? input.Quantity : Math.Max(allowance, input.Quantity);
+ var listedNFTTotalAmount = (allowance >= MaxApproveAllowance) ? input.Quantity : Math.Max(allowance, input.Quantity);
State.ListedNFTTotalAmountMap[collectionSymbol][Context.Sender] = listedNFTTotalAmount.ToString();
}
else
{
- var originQuantity = (long.Parse(collectionAllowance) == MaxApproveAllowance)
+ var originQuantity = (long.Parse(collectionAllowance) >= MaxApproveAllowance)
? DefaultApproveAllowance
: long.Parse(collectionAllowance);
State.ListedNFTTotalAmountMap[collectionSymbol][Context.Sender] =
diff --git a/contract/Forest/ForestContract_Views.cs b/contract/Forest/ForestContract_Views.cs
index 02a474bd..31a6089e 100644
--- a/contract/Forest/ForestContract_Views.cs
+++ b/contract/Forest/ForestContract_Views.cs
@@ -129,7 +129,7 @@ public override GetTotalEffectiveListedNFTAmountOutput GetTotalEffectiveListedNF
{
Symbol = input.Symbol,
Allowance = allowance,
- TotalAmount = (allowance == MaxApproveAllowance) ? totalAmount : Math.Max(allowance,totalAmount)
+ TotalAmount = (allowance >= MaxApproveAllowance) ? totalAmount : Math.Max(allowance,totalAmount)
};
}
@@ -137,7 +137,7 @@ public override GetTotalEffectiveListedNFTAmountOutput GetTotalEffectiveListedNF
{
Symbol = input.Symbol,
Allowance = allowance,
- TotalAmount = (long.Parse(collectionAllowance) == MaxApproveAllowance) ? DefaultApproveAllowance : long.Parse(collectionAllowance)
+ TotalAmount = (long.Parse(collectionAllowance) >= MaxApproveAllowance) ? DefaultApproveAllowance : long.Parse(collectionAllowance)
};
return getTotalEffectiveListedNftAmountOutput;
From d4cf510100ef8d585e8c237fb35f583733e7c23e Mon Sep 17 00:00:00 2001
From: kevin
Date: Thu, 25 Jul 2024 14:12:15 +0800
Subject: [PATCH 5/5] modify max value
---
contract/Forest/ForestContractConstants.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/contract/Forest/ForestContractConstants.cs b/contract/Forest/ForestContractConstants.cs
index c92dc0bf..fa17ac75 100644
--- a/contract/Forest/ForestContractConstants.cs
+++ b/contract/Forest/ForestContractConstants.cs
@@ -27,7 +27,7 @@ public partial class ForestContract
public const string CollectionSymbolSuffix = "0";
public const string SymbolSeparator = "-";
public const long DefaultApproveAllowance = 10000;
- public const long MaxApproveAllowance = 9223372036854770000;
+ public const long MaxApproveAllowance = 9223372000000000000;
}
\ No newline at end of file