Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 115 additions & 0 deletions __tests__/controller.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1831,3 +1831,118 @@ describe("Reserves tests", () => {
);
});
});

describe("Interactions toggler tests", () => {
let handle: HandleFunction;
let controller: string;
let tags: Record<string, string>;

beforeAll(async () => {
handle = await setupProcess(env);
controller = env.Process.Owner;
tags = normalizeTags(env.Process.Tags);
});

it("Does not allow the toggle function to be called by anyone other than the controller", async () => {
const otherAddr = generateArweaveAddress();
const res = await handle(createMessage({
From: otherAddr,
Owner: otherAddr,
Action: "Toggle-Interactions",
Mint: "Enabled",
Borrow: "Disabled"
}));

expect(res.Messages).toEqual(
expect.arrayContaining([
expect.objectContaining({
Target: otherAddr,
Tags: expect.arrayContaining([
expect.objectContaining({
name: "Error",
value: expect.stringContaining(
"The request could not be handled"
)
})
])
})
])
);
});

it("Toggles defined functions", async () => {
const res = await handle(createMessage({
Action: "Toggle-Interactions",
Mint: "Disabled",
Borrow: "Enabled"
}));

expect(res.Messages).toEqual(
expect.arrayContaining([
expect.objectContaining({
Target: controller,
Tags: expect.arrayContaining([
expect.objectContaining({
name: "Updated",
value: "true"
})
])
})
])
);

const infoRes = await handle(createMessage({ Action: "Info" }));

expect(infoRes.Messages).toEqual(
expect.arrayContaining([
expect.objectContaining({
Target: controller,
Tags: expect.arrayContaining([
expect.objectContaining({
name: "Enabled-Interactions",
value: expect.toBeJsonEncoded(expect.not.arrayContaining(["Mint"]))
}),
expect.objectContaining({
name: "Disabled-Interactions",
value: expect.toBeJsonEncoded(expect.arrayContaining(["Mint"]))
})
])
})
])
);

const sender = generateArweaveAddress();
const borrowRes = await handle(createMessage({
Action: "Credit-Notice",
"X-Action": "Mint",
Owner: tags["Collateral-Id"],
From: tags["Collateral-Id"],
"From-Process": tags["Collateral-Id"],
Quantity: "1",
Recipient: env.Process.Id,
Sender: sender
}));
const queueRes = await handle(createMessage({
"Queued-User": sender,
"X-Reference": normalizeTags(
getMessageByAction("Add-To-Queue", borrowRes.Messages)?.Tags || []
)["Reference"]
}));

expect(queueRes.Messages).toEqual(
expect.arrayContaining([
expect.objectContaining({
Target: sender,
Tags: expect.arrayContaining([
expect.objectContaining({
name: "Error",
value: expect.stringContaining(
"Minting is currently disabled"
)
})
])
})
])
);
});
});
3 changes: 3 additions & 0 deletions src/borrow/borrow.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ local function borrow(msg, _, oracle)
-- get position data
local pos = position.globalPosition(account, oracle)

-- check if the interaction is enabled
assert(EnabledInteractions.borrow, "Borrowing is currently disabled")

-- amount of tokens to borrow
local rawQuantity = bint(msg.Tags.Quantity)
local quantity = precision.toInternalPrecision(rawQuantity)
Expand Down
10 changes: 10 additions & 0 deletions src/borrow/pool.lua
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,16 @@ function mod.setup(msg)
-- reserves
ReserveFactor = ReserveFactor or tonumber(ao.env.Process.Tags["Reserve-Factor"]) or 0
Reserves = Reserves or "0"

-- enabled functionalities
EnabledInteractions = EnabledInteractions or {
mint = true,
redeem = true,
borrow = true,
repay = true,
transfer = true,
liquidation = true
}
end

-- This syncs the global timestamp and block using the current message
Expand Down
3 changes: 3 additions & 0 deletions src/borrow/repay.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ local repay = {}

---@type HandlerFunction
function repay.handler(msg)
-- check if the interaction is enabled
assert(EnabledInteractions.repay, "Repaying is currently disabled")

assert(
assertions.isTokenQuantity(msg.Tags.Quantity),
"Invalid incoming transfer quantity"
Expand Down
19 changes: 19 additions & 0 deletions src/controller/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,23 @@ function mod.update(msg)
})
end

-- Handler to enable interactions
---@type HandlerFunction
function mod.toggleInteractions(msg)
local updatedInteractions = {}

for name, value in pairs(EnabledInteractions) do
local expectedTagName = string.upper(string.sub(name, 1, 1)) .. string.sub(name, 2)
updatedInteractions[name] = value

if msg.Tags[expectedTagName] ~= nil then
updatedInteractions[name] = msg.Tags[expectedTagName] == "Enabled"
end
end

EnabledInteractions = updatedInteractions

msg.reply({ Updated = "true" })
end

return mod
6 changes: 6 additions & 0 deletions src/liquidations/liquidate.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ local mod = {}
-- (similar functionality to repaying)
---@type HandlerFunction
function mod.liquidateBorrow(msg)
-- check if the interaction is enabled
assert(EnabledInteractions.liquidation, "Borrow liquidation is currently disabled")

assert(
assertions.isTokenQuantity(msg.Tags.Quantity),
"Invalid incoming transfer quantity"
Expand Down Expand Up @@ -150,6 +153,9 @@ end
-- (reverse redeem)
---@type HandlerFunction
function mod.liquidatePosition(msg)
-- check if the interaction is enabled
assert(EnabledInteractions.liquidation, "Position liquidation is currently disabled")

-- check if the message is coming from a friend process
assert(
assertions.isFriend(msg.From) or msg.From == ao.id,
Expand Down
7 changes: 6 additions & 1 deletion src/process.lua
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ local function setup_handlers()
if msg.Tags.Action ~= "Credit-Notice" then
return false -- not a token transfer
end
if WrappedAO ~= nil and msg.From == AOToken and msg.Tags.Sender == WrappedAO then
if WrappedAOToken ~= nil and msg.From == AOToken and msg.Tags.Sender == WrappedAOToken then
return false -- this oToken process accrues AO and the message is a wAO claim response
end
if msg.From ~= CollateralID then
Expand Down Expand Up @@ -180,6 +180,11 @@ local function setup_handlers()
{ From = Controller, Action = "Update-Config" },
config.update
)
Handlers.add(
"controller-toggle-interactions",
{ From = Controller, Action = "Toggle-Interactions" },
config.toggleInteractions
)

Handlers.advanced({
name = "liquidate-borrow",
Expand Down
3 changes: 3 additions & 0 deletions src/supply/mint.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ local mint = {}

---@type HandlerFunction
function mint.handler(msg)
-- check if the interaction is enabled
assert(EnabledInteractions.mint, "Minting is currently disabled")

assert(
assertions.isTokenQuantity(msg.Tags.Quantity),
"Invalid incoming transfer quantity"
Expand Down
3 changes: 3 additions & 0 deletions src/supply/redeem.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ local rate = require ".supply.rate"

---@type HandlerWithOracle
local function redeem(msg, _, oracle)
-- check if the interaction is enabled
assert(EnabledInteractions.redeem, "Redeeming is currently disabled")

-- the wallet that is burning the tokens
local sender = msg.From

Expand Down
16 changes: 15 additions & 1 deletion src/token/token.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
local precision = require ".utils.precision"
local bint = require ".utils.bint"(1024)
local utils = require ".utils.utils"
local json = require "json"

local mod = {}

Expand Down Expand Up @@ -48,6 +49,17 @@ function mod.info(msg)
)
end

-- enabled and disabled interactions
local enabledInteractions = {}
local disabledInteractions = {}

for name, enabled in pairs(EnabledInteractions) do
table.insert(
enabled and enabledInteractions or disabledInteractions,
string.upper(string.sub(name, 1, 1)) .. string.sub(name, 2)
)
end

msg.reply({
Name = Name,
Ticker = Ticker,
Expand All @@ -70,7 +82,9 @@ function mod.info(msg)
["Jump-Rate"] = tostring(JumpRate),
["Kink-Param"] = tostring(KinkParam),
["Cooldown-Period"] = tostring(CooldownPeriod),
Utilization = tostring(utils.bintToFloat(utilization, utilizationDecimals))
Utilization = tostring(utils.bintToFloat(utilization, utilizationDecimals)),
["Enabled-Interactions"] = json.encode(enabledInteractions),
["Disabled-Interactions"] = json.encode(disabledInteractions)
})
end

Expand Down
3 changes: 3 additions & 0 deletions src/token/transfer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ local function transfer(msg, _, oracle)
-- get position data
local pos = position.globalPosition(sender, oracle)

-- check if the interaction is enabled
assert(EnabledInteractions.transfer, "Transferring is currently disabled")

-- validate target and quantity
assert(assertions.isAddress(target), "Invalid address")
assert(target ~= sender, "Target cannot be the sender")
Expand Down