Skip to content
Open
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
4 changes: 2 additions & 2 deletions app/src/components/admin/ConfigurationSection.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ const READY: ConfigurationState = {
freshness: DAY,
cooldown: 3_600n,
maxUpBps: 1_000,
maxDownBps: null,
maxDownBps: 500,
min: PRICE_ONE / 2n,
max: 2n * PRICE_ONE,
},
Expand Down Expand Up @@ -157,7 +157,7 @@ describe("ConfigurationSection", () => {
freshness_duration: DAY,
cooldown_secs: 3_600n,
max_up_bps: 500,
max_down_bps: null,
max_down_bps: 500,
min_answer: PRICE_ONE / 2n,
max_answer: 2n * PRICE_ONE,
},
Expand Down
6 changes: 3 additions & 3 deletions app/src/components/admin/CycleActionRail.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -422,15 +422,15 @@ describe("CycleActionRail", () => {

it("states an action's note outside the conditions", () => {
renderRail([
{ ...attestAction, note: "Ripcord raised — attesting does not lift it." },
{ ...attestAction, note: "NAV paused — attesting does not unpause it." },
])
expand("Attest price")

const list = screen.getByRole("list", { name: "Attest price conditions" })
expect(
screen.getByText("Ripcord raised — attesting does not lift it."),
screen.getByText("NAV paused — attesting does not unpause it."),
).toBeTruthy()
expect(within(list).queryByText(/Ripcord/)).toBeNull()
expect(within(list).queryByText(/NAV paused/)).toBeNull()
})
})

Expand Down
4 changes: 2 additions & 2 deletions app/src/components/admin/CycleSection.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -140,13 +140,13 @@ const ready = (overrides: Partial<ReadyState> = {}): CycleState => ({
price: price(1n),
attestedAt: 1_700_050_000n,
expiresAt: 1_700_136_000n,
ripcord: false,
navPaused: false,
recorded: true,
limits: {
freshness: 86_400n,
cooldown: 3_600n,
maxUpBps: 500,
maxDownBps: null,
maxDownBps: 1_000,
min: price(1n) / 2n,
max: price(2n),
},
Expand Down
40 changes: 20 additions & 20 deletions app/src/components/admin/EmergencySection.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ const {
useOracleStateMock,
pauseVaultMock,
unpauseVaultMock,
raiseRipcordMock,
setRipcordMock,
pauseNavMock,
setNavPausedMock,
clearLatestMock,
pauseTokenMock,
unpauseTokenMock,
Expand All @@ -33,8 +33,8 @@ const {
useOracleStateMock: vi.fn(),
pauseVaultMock: tx(),
unpauseVaultMock: tx(),
raiseRipcordMock: tx(),
setRipcordMock: tx(),
pauseNavMock: tx(),
setNavPausedMock: tx(),
clearLatestMock: tx(),
pauseTokenMock: tx(),
unpauseTokenMock: tx(),
Expand All @@ -58,8 +58,8 @@ vi.mock("../../hooks/useOracleState", () => ({
vi.mock("../../hooks/useEmergencyTransactions", () => ({
usePauseVault: () => pauseVaultMock,
useUnpauseVault: () => unpauseVaultMock,
useRaiseRipcord: () => raiseRipcordMock,
useSetRipcord: () => setRipcordMock,
usePauseNav: () => pauseNavMock,
useSetNavPaused: () => setNavPausedMock,
useClearLatest: () => clearLatestMock,
usePauseToken: () => pauseTokenMock,
useUnpauseToken: () => unpauseTokenMock,
Expand Down Expand Up @@ -103,8 +103,8 @@ describe("EmergencySection", () => {
for (const mock of [
pauseVaultMock,
unpauseVaultMock,
raiseRipcordMock,
setRipcordMock,
pauseNavMock,
setNavPausedMock,
clearLatestMock,
pauseTokenMock,
unpauseTokenMock,
Expand All @@ -122,7 +122,7 @@ describe("EmergencySection", () => {
expect(within(overview).getByText("Vault")).toBeTruthy()
expect(within(overview).getAllByText("Paused")).toHaveLength(2)
expect(within(overview).getByText("Open")).toBeTruthy()
expect(within(overview).getByText("Ripcord raised")).toBeTruthy()
expect(within(overview).getByText("NAV paused")).toBeTruthy()
})

it("offers the vault guardian only the pause, saying what it stops and what stays open", () => {
Expand Down Expand Up @@ -155,36 +155,36 @@ describe("EmergencySection", () => {
).toBeTruthy()
})

it("raises the ripcord for an oracle admin through set_ripcord, shown as raising", () => {
it("pauses the NAV for an oracle admin through set_nav_paused, shown as pausing", () => {
const { rerender } = render(
<EmergencySection grants={[oracleAdmin]} wallet={WALLET} />,
)

fireEvent.click(button("Raise the ripcord"))
expect(setRipcordMock.submit).toHaveBeenCalledWith(true, oracleAdmin)
expect(raiseRipcordMock.submit).not.toHaveBeenCalled()
fireEvent.click(button("Pause the NAV"))
expect(setNavPausedMock.submit).toHaveBeenCalledWith(true, oracleAdmin)
expect(pauseNavMock.submit).not.toHaveBeenCalled()

setRipcordMock.status = { status: "preparing" }
setNavPausedMock.status = { status: "preparing" }
rerender(<EmergencySection grants={[oracleAdmin]} wallet={WALLET} />)

expect(
screen.getByRole("heading", { name: "Preparing to raise the ripcord" }),
screen.getByRole("heading", { name: "Preparing to pause the NAV" }),
).toBeTruthy()
})

it("lowers the ripcord, and clears the latest price once raised", () => {
it("unpauses the NAV, and clears the latest price once paused", () => {
setState("open", "open", "paused")
const { rerender } = render(
<EmergencySection grants={[oracleAdmin]} wallet={WALLET} />,
)

fireEvent.click(button("Lower the ripcord"))
expect(setRipcordMock.submit).toHaveBeenCalledWith(false, oracleAdmin)
fireEvent.click(button("Unpause the NAV"))
expect(setNavPausedMock.submit).toHaveBeenCalledWith(false, oracleAdmin)

setRipcordMock.status = { status: "preparing" }
setNavPausedMock.status = { status: "preparing" }
rerender(<EmergencySection grants={[oracleAdmin]} wallet={WALLET} />)
expect(
screen.getByRole("heading", { name: "Preparing to lower the ripcord" }),
screen.getByRole("heading", { name: "Preparing to unpause the NAV" }),
).toBeTruthy()

fireEvent.click(button("Clear the latest price"))
Expand Down
28 changes: 14 additions & 14 deletions app/src/components/admin/EmergencySection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import {
useClearLatest,
usePauseToken,
usePauseVault,
useRaiseRipcord,
useSetRipcord,
usePauseNav,
useSetNavPaused,
useUnpauseToken,
useUnpauseVault,
} from "../../hooks/useEmergencyTransactions"
Expand All @@ -29,8 +29,8 @@ import CycleActionRail from "./CycleActionRail"
import SurfaceLayout from "./SurfaceLayout"
import layoutStyles from "./SurfaceLayout.module.css"

const RAISE = "raise"
const LOWER = "lower"
const PAUSE = "pause"
const UNPAUSE = "unpause"

const EmergencySection: React.FC<{
grants: Grant[]
Expand All @@ -43,8 +43,8 @@ const EmergencySection: React.FC<{
const { oracle } = useOracleState()
const pauseVault = usePendingTransaction(usePauseVault())
const unpauseVault = usePendingTransaction(useUnpauseVault())
const raiseRipcord = usePendingTransaction(useRaiseRipcord())
const setRipcord = usePendingTransaction(useSetRipcord())
const pauseNav = usePendingTransaction(usePauseNav())
const setNavPaused = usePendingTransaction(useSetNavPaused())
const clearLatest = usePendingTransaction(useClearLatest())
const pauseToken = usePendingTransaction(usePauseToken())
const unpauseToken = usePendingTransaction(useUnpauseToken())
Expand All @@ -60,12 +60,12 @@ const EmergencySection: React.FC<{
case "unpause-vault":
unpauseVault.submit(undefined, "", action.grant)
return
case "raise-ripcord":
if (action.viaAdmin) setRipcord.submit(true, RAISE, action.grant)
else raiseRipcord.submit(undefined, "", action.grant)
case "pause-nav":
if (action.viaAdmin) setNavPaused.submit(true, PAUSE, action.grant)
else pauseNav.submit(undefined, "", action.grant)
return
case "lower-ripcord":
setRipcord.submit(false, LOWER, action.grant)
case "unpause-nav":
setNavPaused.submit(false, UNPAUSE, action.grant)
return
case "clear-latest":
clearLatest.submit(undefined, "", action.grant)
Expand Down Expand Up @@ -95,10 +95,10 @@ const EmergencySection: React.FC<{
const modalFlows: TransactionModalProps[] = [
flow("pause-vault", pauseVault),
flow("unpause-vault", unpauseVault),
flow("raise-ripcord", raiseRipcord),
flow("pause-nav", pauseNav),
flow(
setRipcord.amountLabel === RAISE ? "raise-ripcord" : "lower-ripcord",
setRipcord,
setNavPaused.amountLabel === PAUSE ? "pause-nav" : "unpause-nav",
setNavPaused,
),
flow("clear-latest", clearLatest),
flow("pause-token", pauseToken),
Expand Down
11 changes: 6 additions & 5 deletions app/src/components/vault/TransactionModal.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1601,6 +1601,7 @@ describe("TransactionModal, attesting a price", () => {
[3005, /already have expired/],
[3003, /cooldown .* has not elapsed/],
[3004, /moves further from the last attested price/],
[3010, /^Unpause the NAV first\.$/],
])("names the oracle's reason for code %i", (code, sentence) => {
renderAttestModal({
status: "failed",
Expand Down Expand Up @@ -2105,8 +2106,8 @@ describe("TransactionModal, emergency actions", () => {
it.each<[EmergencyModalAction, string, string]>([
["pause-vault", "Preparing to pause the vault", "Vault paused"],
["unpause-vault", "Preparing to unpause the vault", "Vault unpaused"],
["raise-ripcord", "Preparing to raise the ripcord", "Ripcord raised"],
["lower-ripcord", "Preparing to lower the ripcord", "Ripcord lowered"],
["pause-nav", "Preparing to pause the NAV", "NAV paused"],
["unpause-nav", "Preparing to unpause the NAV", "NAV unpaused"],
[
"clear-latest",
"Preparing to clear the latest price",
Expand Down Expand Up @@ -2177,8 +2178,8 @@ describe("TransactionModal, emergency actions", () => {
["unpause-vault", 1001, "vault", /The vault is not paused/],
["pause-token", 1000, "share token", /The share token is already paused/],
["unpause-token", 1001, "share token", /The share token is not paused/],
["raise-ripcord", 2000, "oracle", /does not hold the role/],
["clear-latest", 3008, "oracle", /The ripcord is not raised/],
["pause-nav", 2000, "oracle", /does not hold the role/],
["clear-latest", 3008, "oracle", /The NAV is not paused/],
])(
"names the reason %s was refused with code %i",
(action, code, refuser, sentence) => {
Expand Down Expand Up @@ -2209,7 +2210,7 @@ describe("TransactionModal, emergency actions", () => {
})

it("sends an unknown outcome to the Emergency tab", () => {
renderEmergencyModal("raise-ripcord", {
renderEmergencyModal("pause-nav", {
status: "failed",
failure: { kind: "unknown" },
})
Expand Down
30 changes: 16 additions & 14 deletions app/src/components/vault/TransactionModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ import styles from "./TransactionModal.module.css"
export type EmergencyModalAction =
| "pause-vault"
| "unpause-vault"
| "raise-ripcord"
| "lower-ripcord"
| "pause-nav"
| "unpause-nav"
| "clear-latest"
| "pause-token"
| "unpause-token"
Expand Down Expand Up @@ -331,6 +331,8 @@ const attestContractErrorReason = (code: number): string => {
return "The cooldown since the last attestation has not elapsed yet."
case 3004:
return "That price moves further from the last attested price than the oracle allows."
case 3010:
return "Unpause the NAV first."
default:
return GENERIC_REFUSAL
}
Expand Down Expand Up @@ -1026,19 +1028,19 @@ const EMERGENCY_COPY: Record<EmergencyModalAction, AdminCopy> = {
done: "Vault unpaused",
doneBody: "Deposits, pricing and upgrades are open again.",
},
"raise-ripcord": {
"pause-nav": {
refuser: "oracle",
verb: "raise the ripcord",
signing: "Signing stops pricing until the ripcord is lowered.",
done: "Ripcord raised",
verb: "pause the NAV",
signing: "Signing stops pricing until the NAV is unpaused.",
done: "NAV paused",
doneBody:
"Pricing is stopped. No epoch can be fulfilled until the ripcord is lowered.",
"Pricing is stopped. No epoch can be fulfilled until the NAV is unpaused.",
},
"lower-ripcord": {
"unpause-nav": {
refuser: "oracle",
verb: "lower the ripcord",
verb: "unpause the NAV",
signing: "Signing resumes pricing.",
done: "Ripcord lowered",
done: "NAV unpaused",
doneBody: "Epochs can be fulfilled again while the price is valid.",
},
"clear-latest": {
Expand All @@ -1047,7 +1049,7 @@ const EMERGENCY_COPY: Record<EmergencyModalAction, AdminCopy> = {
signing: "Signing removes the recorded price.",
done: "Latest price cleared",
doneBody:
"The next attestation is not limited by its distance from the last. Pricing stays stopped until the ripcord is lowered.",
"The next attestation is not limited by its distance from the last. Pricing stays stopped until the NAV is unpaused.",
},
"pause-token": {
refuser: "share token",
Expand Down Expand Up @@ -1339,7 +1341,7 @@ const adminContractErrorReason =
case 3001:
return "One of the oracle limits is out of range."
case 3008:
return "The ripcord is not raised, so the latest price cannot be cleared."
return "The NAV is not paused, so the latest price cannot be cleared."
case 6007:
return "The deposit cap cannot be negative."
case 6045:
Expand Down Expand Up @@ -1443,8 +1445,8 @@ const describeStatus = (
return describeFinalizeRoundStatus(props.status, props.round)
case "pause-vault":
case "unpause-vault":
case "raise-ripcord":
case "lower-ripcord":
case "pause-nav":
case "unpause-nav":
case "clear-latest":
case "pause-token":
case "unpause-token":
Expand Down
22 changes: 11 additions & 11 deletions app/src/hooks/useAdminTransaction.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ import {
useClearLatest,
usePauseToken,
usePauseVault,
useRaiseRipcord,
useSetRipcord,
usePauseNav,
useSetNavPaused,
useUnpauseToken,
useUnpauseVault,
} from "./useEmergencyTransactions"
Expand Down Expand Up @@ -115,8 +115,8 @@ const {
verifier: { allow: vi.fn() },
verifierWriterMock: vi.fn(),
oracle: {
raise_ripcord: vi.fn(),
set_ripcord: vi.fn(),
pause_nav: vi.fn(),
set_nav_paused: vi.fn(),
clear_latest: vi.fn(),
set_config: vi.fn(),
grant_role: vi.fn(),
Expand Down Expand Up @@ -144,7 +144,7 @@ const ORACLE_CONFIG = {
freshness_duration: 86_400n,
cooldown_secs: 3_600n,
max_up_bps: 1_000,
max_down_bps: null,
max_down_bps: 500,
min_answer: 1n,
max_answer: 10n,
}
Expand Down Expand Up @@ -200,9 +200,9 @@ const cases: Case[] = [
refusal: 1001,
},
{
name: "useRaiseRipcord",
useHook: useRaiseRipcord,
method: oracle.raise_ripcord,
name: "usePauseNav",
useHook: usePauseNav,
method: oracle.pause_nav,
arg: undefined,
args: { caller: investorAddress },
keys: oracleWriteKeys,
Expand All @@ -218,9 +218,9 @@ const cases: Case[] = [
refusal: 3008,
},
{
name: "useSetRipcord",
useHook: useSetRipcord,
method: oracle.set_ripcord,
name: "useSetNavPaused",
useHook: useSetNavPaused,
method: oracle.set_nav_paused,
arg: false,
args: { paused: false, caller: investorAddress },
keys: oracleWriteKeys,
Expand Down
Loading
Loading