Skip to content

Commit

Permalink
chore(type): tweak auction type
Browse files Browse the repository at this point in the history
  • Loading branch information
dtfiedler committed Oct 21, 2024
1 parent f684dd2 commit f242629
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 114 deletions.
53 changes: 23 additions & 30 deletions spec/arns_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -600,23 +600,21 @@ describe("arns", function()
local existingAuction = Auction:new(
"active-auction",
currentTimestamp,
1000 * 60 * 60 * 24 * 14,
0.020379 / (1000 * 60 * 60 * 24 * 14),
190,
1,
1000000000,
"test-initiator"
500000000,
"test-initiator",
arns.calculateRegistrationFee
)
local expiredAuction = Auction:new(
"expired-auction",
currentTimestamp - 1,
0, -- ended after 0 ms
0.020379 / (1000 * 60 * 60 * 24 * 14),
190,
currentTimestamp,
1,
1000000000,
"test-initiator"
500000000,
"test-initiator",
arns.calculateRegistrationFee
)
-- manually set the end timestamp to the current timestamp
expiredAuction.endTimestamp = currentTimestamp
_G.NameRegistry.auctions = {
["active-auction"] = existingAuction,
["expired-auction"] = expiredAuction,
Expand Down Expand Up @@ -664,27 +662,19 @@ describe("arns", function()
assert.are.equal(auction.name, "test-name")
assert.are.equal(auction.startTimestamp, 1000000)
assert.are.equal(auction.endTimestamp, twoWeeksMs + 1000000) -- 14 days late
assert.are.equal(auction.initiator, "test-initiator")
assert.are.equal(auction.baseFee, 500000000)
assert.are.equal(auction.demandFactor, 1)
assert.are.equal(auction.decayRate, 0.02037911 / (1000 * 60 * 60 * 24 * 14))
assert.are.equal(auction.scalingExponent, 190)
assert.are.equal(auction.initiator, "test-initiator")
assert.are.equal(auction.settings.decayRate, 0.02037911 / (1000 * 60 * 60 * 24 * 14))
assert.are.equal(auction.settings.scalingExponent, 190)
assert.are.equal(auction.settings.startPriceMultiplier, 50)
assert.are.equal(auction.settings.durationMs, twoWeeksMs)
assert.are.equal(NameRegistry.records["test-name"], nil)
end)

it("should throw an error if the name is already in the auction map", function()
local existingAuction = Auction:new(
"test-name",
1000000,
1000 * 60 * 60 * 24 * 14,
0.020379 / (1000 * 60 * 60 * 24 * 14),
190,
1,
500000000,
"test-initiator",
50,
arns.calculateRegistrationFee
)
local existingAuction =
Auction:new("test-name", 1000000, 1, 500000000, "test-initiator", arns.calculateRegistrationFee)
_G.NameRegistry.auctions = {
["test-name"] = existingAuction,
}
Expand Down Expand Up @@ -716,7 +706,7 @@ describe("arns", function()
local currentTimestamp = startTimestamp + 1000 * 60 * 60 * 24 * 7 -- 1 week into the auction
local decayRate = 0.02037911 / (1000 * 60 * 60 * 24 * 14)
local scalingExponent = 190
local expectedStartPrice = arns.calculateRegistrationFee(
local expectedStartPrice = auction.registrationFeeCalculator(
"permabuy",
auction.baseFee,
nil,
Expand All @@ -742,8 +732,8 @@ describe("arns", function()
local floorPrice = baseFee + oneYearLeaseFee
local startPriceForLease = floorPrice * 50
-- create the curve of prices using the parameters of the auction
local decayRate = auction.decayRate
local scalingExponent = auction.scalingExponent
local decayRate = auction.settings.decayRate
local scalingExponent = auction.settings.scalingExponent
-- all the prices before the last one should match
for i = startTimestamp, auction.endTimestamp - intervalMs, intervalMs do
local timeSinceStart = i - auction.startTimestamp
Expand Down Expand Up @@ -795,7 +785,10 @@ describe("arns", function()
local balances = balances.getBalances()
local expectedPrice = math.floor(
startPrice
* ((1 - (auction.decayRate * (bidTimestamp - startTimestamp))) ^ auction.scalingExponent)
* (
(1 - (auction.settings.decayRate * (bidTimestamp - startTimestamp)))
^ auction.settings.scalingExponent
)
)
local expectedRecord = {
endTimestamp = nil,
Expand Down
18 changes: 2 additions & 16 deletions src/arns.lua
Original file line number Diff line number Diff line change
Expand Up @@ -438,24 +438,10 @@ function arns.createAuction(name, timestamp, initiator)
if arns.getAuction(name) then
error("Auction already exists for name")
end
local durationMs = 60 * 1000 * 60 * 24 * 14 -- 14 days in milliseconds
local decayRate = 0.02037911 / durationMs
local scalingExponent = 190

local baseFee = demand.getFees()[#name]
local demandFactor = demand.getDemandFactor()
local startPriceMultiplier = 50
local auction = Auction:new(
name,
timestamp,
durationMs,
decayRate,
scalingExponent,
demandFactor,
baseFee,
initiator,
startPriceMultiplier,
arns.calculateRegistrationFee
)
local auction = Auction:new(name, timestamp, demandFactor, baseFee, initiator, arns.calculateRegistrationFee)
NameRegistry.auctions[name] = auction
-- ensure the name is removed from the registry
arns.removeRecord(name)
Expand Down
54 changes: 23 additions & 31 deletions src/auctions.lua
Original file line number Diff line number Diff line change
@@ -1,55 +1,47 @@
local Auction = {}

-- Default Auction Settings
AuctionSettings = {
durationMs = 60 * 1000 * 60 * 24 * 14, -- 14 days in milliseconds
decayRate = 0.000000000016847809193121693, -- 0.02037911 / durationMs
scalingExponent = 190, -- steepness of the curve
startPriceMultiplier = 50, -- multiplier for the starting price
}

--- Represents an Auction.
--- @class Auction
--- @field name string The name of the auction
--- @field decayRate number The decay rate for price calculation
--- @field scalingExponent number The scaling exponent for price calculation
--- @field demandFactor number The demand factor for pricing
--- @field durationMs number The duration of the auction in milliseconds
--- @field initiator string The address of the initiator of the auction
--- @field baseFee number The base fee for the auction
--- @field initiator string The address of the initiator of the auction
--- @field settings table The settings for the auction
--- @field startTimestamp number The starting timestamp for the auction
--- @field endTimestamp number The ending timestamp for the auction
--- @field startPriceMultiplier number The multiplier for the starting price
--- @field registrationFeeCalculator function Function to calculate registration fee

--- Creates a new Auction instance
--- @param name string The name of the auction
--- @param startTimestamp number The starting timestamp for the auction
--- @param durationMs number The duration of the auction in milliseconds
--- @param decayRate number The decay rate for price calculation
--- @param scalingExponent number The scaling exponent for price calculation
--- @param demandFactor number The demand factor for pricing
--- @param baseFee number The base fee for the auction
--- @param initiator string The address of the initiator of the auction
--- @param startPriceMultiplier number The multiplier for the starting price
--- @param registrationFeeCalculator function Function to calculate registration fee that supports type, baseFee, years, demandFactor
--- @return Auction The new Auction instance
function Auction:new(
name,
startTimestamp,
durationMs,
decayRate,
scalingExponent,
demandFactor,
baseFee,
initiator,
startPriceMultiplier,
registrationFeeCalculator
)
function Auction:new(name, startTimestamp, demandFactor, baseFee, initiator, registrationFeeCalculator)
local auction = {
name = name,
decayRate = decayRate,
scalingExponent = scalingExponent,
demandFactor = demandFactor,
durationMs = durationMs,
initiator = initiator,
baseFee = baseFee,
startTimestamp = startTimestamp,
endTimestamp = startTimestamp + (durationMs or 14 * 24 * 60 * 60 * 1000),
startPriceMultiplier = startPriceMultiplier or 50,
endTimestamp = startTimestamp + AuctionSettings.durationMs,
registrationFeeCalculator = registrationFeeCalculator,
baseFee = baseFee,
demandFactor = demandFactor,
settings = {
durationMs = AuctionSettings.durationMs,
decayRate = AuctionSettings.decayRate,
scalingExponent = AuctionSettings.scalingExponent,
startPriceMultiplier = AuctionSettings.startPriceMultiplier,
},
}
setmetatable(auction, self)
self.__index = self
Expand Down Expand Up @@ -79,15 +71,15 @@ function Auction:getPriceForAuctionAtTimestamp(timestamp, type, years)
local startPrice = self:startPrice(type, years)
local floorPrice = self:floorPrice(type, years)
local timeSinceStart = timestamp - self.startTimestamp
local totalDecaySinceStart = self.decayRate * timeSinceStart
local currentPrice = math.floor(startPrice * ((1 - totalDecaySinceStart) ^ self.scalingExponent))
local totalDecaySinceStart = self.settings.decayRate * timeSinceStart
local currentPrice = math.floor(startPrice * ((1 - totalDecaySinceStart) ^ self.settings.scalingExponent))
return math.max(currentPrice, floorPrice)
end

--- Returns the start price for the auction
--- @return number The start price for the auction
function Auction:startPrice(type, years)
return self:floorPrice(type, years) * self.startPriceMultiplier
return self:floorPrice(type, years) * self.settings.startPriceMultiplier
end

--- Returns the floor price for the auction
Expand Down
46 changes: 13 additions & 33 deletions src/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2231,25 +2231,19 @@ addEventingHandler("auctionInfo", utils.hasMatchingTag("Action", ActionMap.Aucti
return
end

local auctionObj = {
name = auction.name,
startTimestamp = auction.startTimestamp,
endTimestamp = auction.endTimestamp,
initiator = auction.initiator,
currentPrice = auction:getPriceForAuctionAtTimestamp(timestamp, type, years),
settings = {
decayRate = auction.decayRate,
scalingExponent = auction.scalingExponent,
baseFee = auction.baseFee,
demandFactor = auction.demandFactor,
durationMs = auction.durationMs,
startPriceMultiplier = auction.startPriceMultiplier,
},
}
ao.send({
Target = msg.From,
Action = ActionMap.AuctionInfo .. "-Notice",
Data = json.encode(auctionObj),
Data = json.encode({
name = auction.name,
startTimestamp = auction.startTimestamp,
endTimestamp = auction.endTimestamp,
initiator = auction.initiator,
currentPrice = auction:getPriceForAuctionAtTimestamp(timestamp, type, years),
baseFee = auction.baseFee,
demandFactor = auction.demandFactor,
settings = auction.settings,
}),
})
end)

Expand Down Expand Up @@ -2360,22 +2354,6 @@ addEventingHandler("auctionBid", utils.hasMatchingTag("Action", ActionMap.Auctio
return
end

local auctionObj = {
name = auction.name,
startTimestamp = auction.startTimestamp,
endTimestamp = auction.endTimestamp,
initiator = auction.initiator,
currentPrice = auction:getPriceForAuctionAtTimestamp(timestamp, type, years),
settings = {
decayRate = auction.decayRate,
scalingExponent = auction.scalingExponent,
baseFee = auction.baseFee,
demandFactor = auction.demandFactor,
durationMs = auction.durationMs,
startPriceMultiplier = auction.startPriceMultiplier,
},
}

-- send buy record notice and auction close notice?
ao.send({
Target = bidder,
Expand All @@ -2388,7 +2366,9 @@ addEventingHandler("auctionBid", utils.hasMatchingTag("Action", ActionMap.Auctio
Action = "Debit-Notice",
Quantity = tostring(result.rewardForInitiator),
Data = json.encode({
auction = auctionObj,
type = type,
years = years,
name = auction.name,
bidder = result.bidder,
bidAmount = result.bidAmount,
rewardForInitiator = result.rewardForInitiator,
Expand Down
12 changes: 8 additions & 4 deletions tests/arns.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -454,12 +454,14 @@ describe('ArNS', async () => {
releaseNameResult.Memory,
);
// assert no error tag
const auctionErrorTag = auctionResult.Messages[0].Tags.find(
const auctionErrorTag = auctionResult.Messages?.[0]?.Tags?.find(
(tag) => tag.name === 'Error',
);

console.log(auctionResult);

assert.equal(auctionErrorTag, undefined);
const auction = JSON.parse(auctionResult.Messages[0].Data);
const auction = JSON.parse(auctionResult.Messages?.[0]?.Data);
const expectedStartPrice = 125000000000;
const expectedStartTimestamp = STUB_TIMESTAMP;
assert.deepEqual(auction, {
Expand All @@ -468,11 +470,11 @@ describe('ArNS', async () => {
startTimestamp: auction.startTimestamp,
endTimestamp: expectedStartTimestamp + 60 * 60 * 1000 * 24 * 14,
currentPrice: expectedStartPrice,
baseFee: 500000000,
demandFactor: 1,
settings: {
decayRate: (0.02037911 / (1000 * 60 * 60 * 24 * 14)).toFixed(24),
scalingExponent: 190,
baseFee: 500000000,
demandFactor: 1,
durationMs: 1209600000,
startPriceMultiplier: 50,
},
Expand Down Expand Up @@ -646,6 +648,8 @@ describe('ArNS', async () => {
);
assert.equal(auctionPricesErrorTag, undefined);

console.log(auctionPrices);

// parse the auction prices data
const auctionPricesData = JSON.parse(auctionPrices.Messages?.[0]?.Data);

Expand Down

0 comments on commit f242629

Please sign in to comment.