Browse Source

Pricing

master
Lev 2 years ago
parent
commit
b35dbb9283
  1. 31
      contracts/imports/dns-utils.fc
  2. 17
      contracts/main.ts
  3. 10
      contracts/nft-collection.fc
  4. 14
      test/creation.spec.ts

31
contracts/imports/dns-utils.fc

@ -172,6 +172,37 @@ int check_domain_string(slice domain) {
return (10, 1); return (10, 1);
} }
int price_function(int length, int multiplierx10, int steepness) {
;; length is the length of the domain, the price depends on it. The rest is the price config
;; multiplierx10 is the price multiplier, the default price is multiplied by multiplierx10 / 10
;; steepness (from 0 to 10) is the steepness of the price function,
;; 10 means the distribution is as in the function from `get_min_price_config` (the second number), 0 means the price is always the same, 50
int price = 50;
if (length == 3) {
price = 200;
}
if (length == 4) {
price = 100;
}
if (length == 5) {
price = 50;
}
if (length == 6) {
price = 40;
}
if (length == 7) {
price = 30;
}
if (length == 8) {
price = 20;
}
if (length >= 9) {
price = 10;
}
price = (steepness * price + (10 - steepness) * 50) / 10;
return price * one_ton * multiplierx10 / 10;
}
int get_min_price(int domain_bits_length, int now_time) { int get_min_price(int domain_bits_length, int now_time) {
(int start_min_price, int end_min_price) = get_min_price_config(domain_bits_length / 8); (int start_min_price, int end_min_price) = get_min_price_config(domain_bits_length / 8);
start_min_price *= one_ton; start_min_price *= one_ton;

17
contracts/main.ts

@ -36,11 +36,20 @@ export function data(params: { ownerAddress: Address; collectionAddress: Address
return beginCell().storeRef(data_cell).storeBuffer(params.publicKey).endCell(); return beginCell().storeRef(data_cell).storeBuffer(params.publicKey).endCell();
} }
export function collectionData(params: { code: Cell, ownerAddress: Address, ownerKey: number }): Cell { export function collectionData(params: {
code: Cell, ownerAddress: Address, ownerKey: number,
price_multiplier?: number, price_steepness?: number
}): Cell {
if (params.price_multiplier == undefined) {
params.price_multiplier = 10;
}
if (params.price_steepness == undefined) {
params.price_steepness = 5;
}
return beginCell() return beginCell()
.storeRef(encodeOffChainContent("https://agorata.io/collection.json")) .storeRef(encodeOffChainContent("https://agorata.io/collection.json"))
.storeRef(params.code) .storeRef(params.code)
.storeRef(beginCell().endCell()) .storeRef(beginCell().storeUint(params.price_multiplier, 8).storeUint(params.price_steepness, 4).endCell())
.storeUint(params.ownerKey, 256) .storeUint(params.ownerKey, 256)
.storeAddress(params.ownerAddress) .storeAddress(params.ownerAddress)
.endCell(); .endCell();
@ -54,7 +63,9 @@ export function setContractBalance(contract: SmartContract, balance: number) {
contract.setC7Config({balance: balance}); contract.setC7Config({balance: balance});
} }
export function TON(): number { return 1000000000; } export function TON(): number {
return 1000000000;
}
// message encoders for all ops (see contracts/imports/constants.fc for consts) // message encoders for all ops (see contracts/imports/constants.fc for consts)

10
contracts/nft-collection.fc

@ -41,7 +41,10 @@ int calcprice(slice domain, cell pricing) inline_ref {
throw_unless(201, len <= 126 * 8); ;; maxmimum 126 characters throw_unless(201, len <= 126 * 8); ;; maxmimum 126 characters
throw_unless(202, mod(len, 8) == 0); throw_unless(202, mod(len, 8) == 0);
throw_unless(203, check_domain_string(domain)); throw_unless(203, check_domain_string(domain));
return 100000; ;; todo slice pr = pricing.begin_parse();
int multiplier = pr~load_uint(8);
int steepness = pr~load_uint(4);
return price_function(len / 8, multiplier, steepness);
} }
cell calculate_nft_item_state_init(int item_index, cell nft_item_code) { cell calculate_nft_item_state_init(int item_index, cell nft_item_code) {
@ -138,6 +141,11 @@ cell get_nft_content(int index, cell individual_nft_content) method_id {
return individual_nft_content; return individual_nft_content;
} }
int get_price(slice domain) method_id {
var (content, nft_item_code, pricing, key, addr) = load_data();
return calcprice(domain, pricing);
}
(int, cell) dnsresolve(slice subdomain, int category) method_id { (int, cell) dnsresolve(slice subdomain, int category) method_id {
throw_unless(70, mod(slice_bits(subdomain), 8) == 0); throw_unless(70, mod(slice_bits(subdomain), 8) == 0);

14
test/creation.spec.ts

@ -33,13 +33,23 @@ describe("Creating items tests", () => {
const sendToSelfMessage = internalMessage({ const sendToSelfMessage = internalMessage({
from: ownerAddr, from: ownerAddr,
body: main.createItem({ domain: "test" }), body: main.createItem({ domain: "test" }),
value: new BN(10 * main.TON()), value: new BN(100 * main.TON()),
}); });
const res = await contract.sendInternalMessage(sendToSelfMessage); const res = await contract.sendInternalMessage(sendToSelfMessage);
console.log(res); console.log(res);
expect(res.type).to.equal("success"); expect(res.type).to.equal("success");
expect(res.exit_code).to.equal(0); expect(res.exit_code).to.equal(0);
});
it("does not allow to buy an item if the price is too low", async () => {
main.setContractBalance(contract, 10 * main.TON());
let ownerAddr = randomAddress("owner");
const sendToSelfMessage = internalMessage({
from: ownerAddr,
body: main.createItem({ domain: "test" }),
value: new BN(10 * main.TON()),
});
const res = await contract.sendInternalMessage(sendToSelfMessage);
expect(res.type).to.equal("failed");
}); });
}); });

Loading…
Cancel
Save