diff --git a/__tests__/token.test.ts b/__tests__/token.test.ts index 19a4007..1223138 100644 --- a/__tests__/token.test.ts +++ b/__tests__/token.test.ts @@ -681,7 +681,7 @@ describe("Token standard functionalities", () => { const res = await handle( generateOracleResponse({ BTC: 85325.425 }, oracleRes) ); - + expect(res.Messages).toEqual( expect.arrayContaining([ expect.objectContaining({ diff --git a/src/borrow/borrow.lua b/src/borrow/borrow.lua index b3be414..91b9fae 100644 --- a/src/borrow/borrow.lua +++ b/src/borrow/borrow.lua @@ -94,8 +94,7 @@ function mod.borrow(msg, _, oracle) " " .. CollateralTicker ) - ao.send({ - device = "patch@1.0", + patch({ ["pool-state"] = { cash = precision.formatInternalAsNative(Cash, "rounddown"), ["total-borrows"] = precision.formatInternalAsNative(TotalBorrows, "roundup"), diff --git a/src/borrow/interest.lua b/src/borrow/interest.lua index f5a2521..aabf075 100644 --- a/src/borrow/interest.lua +++ b/src/borrow/interest.lua @@ -170,8 +170,7 @@ function mod.accrueInterest(msg) ReservesRemainder = tostring(remainder) -- patch the updated globals - ao.send({ - device = "patch@1.0", + patch({ ["pool-state"] = { ["total-borrows"] = precision.formatInternalAsNative(TotalBorrows, "roundup"), ["total-reserves"] = precision.formatInternalAsNative(Reserves, "roundup"), @@ -212,8 +211,7 @@ function mod.accrueInterestForUser(address) InterestIndices[address] = tostring(interestIndex) -- patch updated global values - ao.send({ - device = "patch@1.0", + patch({ loans = { [address] = Loans[address] }, ["interest-indices"] = { [address] = InterestIndices[address] }, -- !!do not update positions to avoid an infinite recursive loop!! diff --git a/src/borrow/repay.lua b/src/borrow/repay.lua index f367754..1ad402e 100644 --- a/src/borrow/repay.lua +++ b/src/borrow/repay.lua @@ -159,8 +159,7 @@ function repay.repayToPool(target, quantity) TotalBorrows = tostring(bint(TotalBorrows) - precision.toInternalPrecision(actualRepaidQty)) -- patch the updated globals - ao.send({ - device = "patch@1.0", + patch({ ["pool-state"] = { cash = precision.formatInternalAsNative(Cash, "rounddown"), ["total-borrows"] = precision.formatInternalAsNative(TotalBorrows, "roundup"), diff --git a/src/controller/config.lua b/src/controller/config.lua index 1903fb0..59ca5f7 100644 --- a/src/controller/config.lua +++ b/src/controller/config.lua @@ -111,8 +111,7 @@ function mod.update(msg) if newAOToken then AOToken = newAOToken end -- patch - ao.send({ - device = "patch@1.0", + patch({ environment = { ["risk-parameters"] = { ["collateral-factor"] = CollateralFactor, @@ -173,8 +172,7 @@ function mod.toggleInteractions(msg) -- patch local enabledInteractions, disabledInteractions = patching.utils.interactionsState() - ao.send({ - device = "patch@1.0", + patch({ environment = { limits = { ["enabled-interactions"] = enabledInteractions, diff --git a/src/controller/cooldown.lua b/src/controller/cooldown.lua index dd80ba6..36b62b2 100644 --- a/src/controller/cooldown.lua +++ b/src/controller/cooldown.lua @@ -49,8 +49,7 @@ function mod.gate(msg) Cooldowns[sender] = msg["Block-Height"] + CooldownPeriod -- patch - ao.send({ - device = "patch@1.0", + patch({ cooldowns = { [sender] = Cooldowns[sender] } }) end diff --git a/src/controller/friend.lua b/src/controller/friend.lua index 4e751ca..2b89728 100644 --- a/src/controller/friend.lua +++ b/src/controller/friend.lua @@ -1,4 +1,5 @@ local assertions = require ".utils.assertions" +local patching = require ".token.patching" local utils = require ".utils.utils" local json = require "json" @@ -52,8 +53,7 @@ function friend.add(msg) }) -- patch - ao.send({ - device = "patch@1.0", + patch({ environment = { friends = Friends } }) @@ -89,8 +89,7 @@ function friend.remove(msg) assert(#removed > 0, "Friend " .. target .. " not yet added") -- patch - ao.send({ - device = "patch@1.0", + patch({ environment = { friends = Friends } }) diff --git a/src/controller/reserves.lua b/src/controller/reserves.lua index 664f96c..0670b80 100644 --- a/src/controller/reserves.lua +++ b/src/controller/reserves.lua @@ -1,5 +1,6 @@ local assertions = require ".utils.assertions" local precision = require ".utils.precision" +local patching = require ".token.patching" local bint = require ".utils.bint"(1024) local mod = {} @@ -66,8 +67,7 @@ function mod.deploy(msg) Cash = tostring(bint(Cash) + quantity) -- patch - ao.send({ - device = "patch@1.0", + patch({ ["pool-state"] = { cash = precision.formatInternalAsNative(Cash, "rounddown"), ["total-reserves"] = precision.formatInternalAsNative(Reserves, "roundup") diff --git a/src/liquidations/liquidate.lua b/src/liquidations/liquidate.lua index 11434fb..3ca9c3f 100644 --- a/src/liquidations/liquidate.lua +++ b/src/liquidations/liquidate.lua @@ -243,8 +243,7 @@ function mod.liquidatePosition(msg) }) -- patch - ao.send({ - device = "patch@1.0", + patch({ ["token-info"] = { supply = TotalSupply }, ["pool-state"] = { cash = precision.formatInternalAsNative(Cash, "rounddown"), diff --git a/src/process.lua b/src/process.lua index 8fb09b8..ea2e548 100644 --- a/src/process.lua +++ b/src/process.lua @@ -7,6 +7,9 @@ require(".utils.assignment").init(ao) local process = { _version = "0.0.1" } local coroutine = require "coroutine" +local utils = require ".utils.utils" + +patch = function (data) utils.patch_table(PatchData or {}, data) end local friend = require ".controller.friend" local config = require ".controller.config" @@ -34,7 +37,6 @@ local rate = require ".supply.rate" local redeem = require ".supply.redeem" local delegation = require ".supply.delegation" -local utils = require ".utils.utils" local precision = require ".utils.precision" HandlersAdded = HandlersAdded or false @@ -380,8 +382,6 @@ function process.handle(msg, env) if not status then -- call default error handler Handlers.defaultErrorHandler(msg, env, result) - - return ao.result() end return ao.result() diff --git a/src/supply/mint.lua b/src/supply/mint.lua index 2483343..f6abe8e 100644 --- a/src/supply/mint.lua +++ b/src/supply/mint.lua @@ -61,8 +61,7 @@ function mint.handler(msg) -- patch patching.patchOrder(msg.Tags["Pushed-For"] or msg.Id, true) - ao.send({ - device = "patch@1.0", + patch({ ["pool-state"] = { cash = precision.formatInternalAsNative(Cash, "rounddown"), ["total-borrows"] = precision.formatInternalAsNative(TotalBorrows, "roundup"), diff --git a/src/supply/redeem.lua b/src/supply/redeem.lua index 47da439..66ad35a 100644 --- a/src/supply/redeem.lua +++ b/src/supply/redeem.lua @@ -99,8 +99,7 @@ function mod.redeem(msg, _, oracle) Recipient = sender }) patching.patchOrder(msg.Id, true) - ao.send({ - device = "patch@1.0", + patch({ ["pool-state"] = { cash = precision.formatInternalAsNative(Cash, "rounddown"), ["total-borrows"] = precision.formatInternalAsNative(TotalBorrows, "roundup"), diff --git a/src/token/patching.lua b/src/token/patching.lua index 146b9b0..522fedb 100644 --- a/src/token/patching.lua +++ b/src/token/patching.lua @@ -10,6 +10,9 @@ local mod = { ---@type HandlerFunction function mod.setup() + PatchingSetUp = PatchingSetUp or false + if PatchingSetUp then return end + -- enabled and disabled interactions local enabledInteractions, disabledInteractions = mod.utils.interactionsState() @@ -87,6 +90,8 @@ function mod.setup() ["interest-indices"] = interestIndices, orders = { device = "trie@1.0" } }) + + PatchingSetUp = true end -- Patch the result of a borrow/mint/redeem/repay @@ -94,8 +99,7 @@ end ---@param success boolean The result of the order ---@param message string? Optional result message function mod.patchOrder(id, success, message) - ao.send({ - device = "patch@1.0", + patch({ orders = { [id] = { success = success, diff --git a/src/token/transfer.lua b/src/token/transfer.lua index 9d882ac..adecb33 100644 --- a/src/token/transfer.lua +++ b/src/token/transfer.lua @@ -63,8 +63,7 @@ local function transfer(msg, _, oracle) Balances[sender] = tostring(walletBalance - quantity) -- patch transfer - ao.send({ - device = "patch@1.0", + patch({ balances = { [sender] = Balances[sender], [target] = Balances[target] diff --git a/src/utils/handlers.lua b/src/utils/handlers.lua index d75c73a..7978f47 100644 --- a/src/utils/handlers.lua +++ b/src/utils/handlers.lua @@ -468,6 +468,9 @@ function handlers.evaluate(msg, env) assert(type(msg) == 'table', 'msg is not valid') assert(type(env) == 'table', 'env is not valid') + -- reset current patch + PatchData = {} + for _, o in ipairs(handlers.list) do if o.name ~= "_default" and not o.inactive then local match = utils.matchesSpec(msg, o.pattern) @@ -556,7 +559,7 @@ function handlers.evaluate(msg, env) end end if match < 0 then - return handled + break end end end @@ -569,6 +572,13 @@ function handlers.evaluate(msg, env) handlers.remove(name) end + -- send summarized patch + if next(PatchData) ~= nil then + PatchData.device = "patch@1.0" + ao.send(PatchData) + PatchData = {} + end + -- make sure the request was handled assert( handled or msg.Id == ao.id or string.match(msg.Action or "", "Error$"), diff --git a/src/utils/utils.lua b/src/utils/utils.lua index 6db032f..4c7fa7c 100644 --- a/src/utils/utils.lua +++ b/src/utils/utils.lua @@ -402,4 +402,17 @@ function utils.udiv_roundup(x, y) ) end +-- Patches a table with another table, without deleting any keys (recursively merges nested tables) +---@param target table The table to be patched (modified in-place) +---@param patch table The table providing new or updated values +function utils.patch_table(target, patch) + for k, v in pairs(patch) do + if type(v) == "table" and type(target[k]) == "table" then + utils.patch_table(target[k], v) + else + target[k] = v + end + end +end + return utils