Skip to content

Commit

Permalink
fix(token): update token-cost to properly round to integer
Browse files Browse the repository at this point in the history
  • Loading branch information
dtfiedler committed Jun 25, 2024
1 parent 9cd568d commit ef29a8c
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 21 deletions.
16 changes: 10 additions & 6 deletions src/arns.lua
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ end

function arns.calculateExtensionFee(baseFee, years, demandFactor)
local extensionFee = arns.calculateAnnualRenewalFee(baseFee, years)
return demandFactor * extensionFee
return math.floor(demandFactor * extensionFee)
end

function arns.increaseundernameLimit(from, name, qty, currentTimestamp)
Expand Down Expand Up @@ -245,8 +245,9 @@ function arns.calculateUndernameCost(baseFee, increaseQty, registrationType, yea
return math.floor(demandFactor * totalFeeForQtyAndYears)
end

-- this is intended to be a float point number - TODO: protect against large decimals
function arns.calculateYearsBetweenTimestamps(startTimestamp, endTimestamp)
local yearsRemainingFloat = math.floor((endTimestamp - startTimestamp) / constants.oneYearMs)
local yearsRemainingFloat = (endTimestamp - startTimestamp) / constants.oneYearMs
return yearsRemainingFloat
end

Expand Down Expand Up @@ -333,11 +334,14 @@ function arns.getTokenCost(intendedAction)
tokenCost = arns.calculateExtensionFee(baseFee, years, demand.getDemandFactor())
elseif intendedAction.intent == "Increase-Undername-Limit" then
local name = intendedAction.name
local qty = intendedAction.quantity
local qty = tonumber(intendedAction.quantity)
local currentTimestamp = intendedAction.currentTimestamp
assert(type(name) == "string", "Name is required and must be a string.")
assert(qty >= 1 and qty <= 9990, "Quantity is invalid, must be between 1 and 9990")
assert(currentTimestamp, "CurrentTimestamp is required")
assert(
qty >= 1 and qty <= 9990 and utils.isInteger(qty),
"Quantity is invalid, must be an integer between 1 and 9990"
)
assert(type(currentTimestamp) == "number" and currentTimestamp > 0, "Timestamp is required")
local record = arns.getRecord(intendedAction.name)
if not record then
error("Name is not registered")
Expand Down Expand Up @@ -369,7 +373,7 @@ function arns.assertValidIncreaseUndername(record, qty, currentTimestamp)
error("Name is expired")
end

if qty < 1 or qty > 9990 then
if qty < 1 or qty > 9990 or not utils.isInteger(qty) then
error("Qty is invalid")
end

Expand Down
3 changes: 1 addition & 2 deletions src/balances.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ function balances.transfer(recipient, from, qty)
assert(type(recipient) == "string", "Recipient is required!")
assert(type(from) == "string", "From is required!")
assert(type(qty) == "number", "Quantity is required and must be a number!")
assert(qty > 0, "Quantity must be greater than 0")
-- assert(qty % 1 == 0, "Quantity must be an integer")
assert(utils.isInteger(qty), "Quantity must be an integer")

balances.reduceBalance(from, qty)
balances.increaseBalance(recipient, qty)
Expand Down
27 changes: 14 additions & 13 deletions src/epochs.lua
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ function epochs.getObservers()
end

function epochs.getSettings()
return epochSettings
return utils.deepCopy(epochSettings)
end

function epochs.getObservations()
Expand Down Expand Up @@ -103,14 +103,14 @@ function epochs.computePrescribedNamesForEpoch(epochIndex, hashchain)
return nameAString < nameBString
end)

if #activeArNSNames < epochSettings.prescribedNameCount then
if #activeArNSNames < epochs.getSettings().prescribedNameCount then
return activeArNSNames
end

local epochHash = utils.getHashFromBase64URL(hashchain)
local prescribedNames = {}
local hash = epochHash
while #prescribedNames < epochSettings.prescribedNameCount do
while #prescribedNames < epochs.getSettings().prescribedNameCount do
local hashString = crypto.utils.array.toString(hash)
local random = crypto.random(nil, nil, hashString) % #activeArNSNames

Expand Down Expand Up @@ -153,7 +153,7 @@ function epochs.computePrescribedObserversForEpoch(epochIndex, hashchain)
table.insert(filteredObservers, observer)
end
end
if #filteredObservers <= epochSettings.maxObservers then
if #filteredObservers <= epochs.getSettings().maxObservers then
return filteredObservers
end

Expand All @@ -172,7 +172,7 @@ function epochs.computePrescribedObserversForEpoch(epochIndex, hashchain)
-- get our prescribed observers, using the hashchain as entropy
local hash = epochHash
local prescribedObserversAddresses = {}
while #prescribedObserversAddresses < epochSettings.maxObservers do
while #prescribedObserversAddresses < epochs.getSettings().maxObservers do
local hashString = crypto.utils.array.toString(hash)
local random = crypto.random(nil, nil, hashString) / 0xffffffff
local cumulativeNormalizedCompositeWeight = 0
Expand Down Expand Up @@ -219,15 +219,16 @@ function epochs.computePrescribedObserversForEpoch(epochIndex, hashchain)
end

function epochs.getEpochTimestampsForIndex(epochIndex)
local epochStartTimestamp = epochSettings.epochZeroStartTimestamp + epochSettings.durationMs * epochIndex
local epochEndTimestamp = epochStartTimestamp + epochSettings.durationMs
local epochDistributionTimestamp = epochEndTimestamp + epochSettings.distributionDelayMs
local epochStartTimestamp = epochs.getSettings().epochZeroStartTimestamp
+ epochs.getSettings().durationMs * epochIndex
local epochEndTimestamp = epochStartTimestamp + epochs.getSettings().durationMs
local epochDistributionTimestamp = epochEndTimestamp + epochs.getSettings().distributionDelayMs
return epochStartTimestamp, epochEndTimestamp, epochDistributionTimestamp
end

function epochs.getEpochIndexForTimestamp(timestamp)
local epochZeroStartTimestamp = epochSettings.epochZeroStartTimestamp
local epochLengthMs = epochSettings.durationMs
local epochZeroStartTimestamp = epochs.getSettings().epochZeroStartTimestamp
local epochLengthMs = epochs.getSettings().durationMs
local epochIndex = math.floor((timestamp - epochZeroStartTimestamp) / epochLengthMs)
return epochIndex
end
Expand Down Expand Up @@ -294,7 +295,7 @@ function epochs.saveObservations(observerAddress, reportTxId, failedGatewayAddre
epochs.getEpochTimestampsForIndex(epochIndex)

-- avoid observations before the previous epoch distribution has occurred, as distributions affect weights of the current epoch
if timestamp < epochStartTimestamp + epochSettings.distributionDelayMs then
if timestamp < epochStartTimestamp + epochs.getSettings().distributionDelayMs then
error("Observations for the current epoch cannot be submitted before: " .. epochDistributionTimestamp)
end

Expand Down Expand Up @@ -381,7 +382,7 @@ end
-- 5. Distribute the rewards to the gateways and observers
-- 6. Increment the epoch stats for the gateways
function epochs.distributeRewardsForEpoch(currentTimestamp)
local epochIndex = epochs.getEpochIndexForTimestamp(currentTimestamp - epochSettings.durationMs) -- go back to previous epoch
local epochIndex = epochs.getEpochIndexForTimestamp(currentTimestamp - epochs.getSettings().durationMs) -- go back to previous epoch
local epoch = epochs.getEpoch(epochIndex)
if not next(epoch) then
-- silently return
Expand All @@ -397,7 +398,7 @@ function epochs.distributeRewardsForEpoch(currentTimestamp)

local activeGatewayAddresses = gar.getActiveGatewaysBetweenTimestamps(epoch.startTimestamp, epoch.endTimestamp)
local prescribedObservers = epochs.getPrescribedObserversForEpoch(epochIndex)
local totalEligibleRewards = math.floor(balances.getBalance(ao.id) * epochSettings.rewardPercentage)
local totalEligibleRewards = math.floor(balances.getBalance(ao.id) * epochs.getSettings().rewardPercentage)
local gatewayReward = math.floor(totalEligibleRewards * 0.95 / #activeGatewayAddresses)
local observerReward = math.floor(totalEligibleRewards * 0.05 / #prescribedObservers)

Expand Down
2 changes: 2 additions & 0 deletions src/gar.lua
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ end

function gar.increaseOperatorStake(from, qty)
assert(type(qty) == "number", "Quantity is required and must be a number!")
-- asssert it is an integer
assert(utils.isInteger(qty), "Quantity must be an integer!")
assert(qty > 0, "Quantity must be greater than 0")

local gateway = gar.getGateway(from)
Expand Down
5 changes: 5 additions & 0 deletions src/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ function utils.deepCopy(original)
if not original then
return nil
end

if type(original) ~= "table" then
return original
end

local copy = {}
for key, value in pairs(original) do
if type(value) == "table" then
Expand Down

0 comments on commit ef29a8c

Please sign in to comment.