Skip to content
2 changes: 1 addition & 1 deletion backend/.prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
"singleQuote": true,
"trailingComma": "all",
"arrowParens": "always",
"endOfLine": "lf"
"endOfLine": "auto"
}
4 changes: 3 additions & 1 deletion backend/src/middleware/pauseGuard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,11 @@ export function pauseGuard(req: Request, _res: Response, next: NextFunction): vo
});

// Return 503 Service Unavailable with pause info
throw AppError.serviceUnavailable(
throw new AppError(
`Contract operations are temporarily paused. Reason: ${globalPauseState.reason || 'Maintenance or security measure'}. ` +
`Affected contracts: ${globalPauseState.contracts.join(', ')}`,
503,
true,
);
}

Expand Down
59 changes: 59 additions & 0 deletions frontend/src/app/utils/soroban.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { TextDecoder, TextEncoder } from "util";

if (typeof global.TextEncoder === "undefined") {
(global as any).TextEncoder = TextEncoder;
}
if (typeof global.TextDecoder === "undefined") {
(global as any).TextDecoder = TextDecoder;
}

/* eslint-disable @typescript-eslint/no-require-imports */
const {
Account,
Keypair,
rpc,
scValToNative,
TransactionBuilder,
} = require("@stellar/stellar-sdk");
const { buildUnsignedRepaymentXdr } = require("./soroban");

describe("buildUnsignedRepaymentXdr", () => {
const borrower = Keypair.random().publicKey();
const contractId = Keypair.random().publicKey();

beforeEach(() => {
jest.spyOn(rpc.Server.prototype, "getAccount").mockResolvedValue(new Account(borrower, "100"));
});

afterEach(() => {
jest.restoreAllMocks();
});

it("encodes the full repayment amount into the XDR, not a tenth of it", async () => {
const inputAmount = 1000;
const loanId = "42";

const xdrString = await buildUnsignedRepaymentXdr({
borrower,
loanId,
amount: inputAmount,
contractId,
});

const tx = TransactionBuilder.fromXDR(xdrString, "Test SDF Network ; September 2015");

const op = tx.operations[0];
expect(op.type).toBe("invokeHostFunction");

if (op.type === "invokeHostFunction") {
const invokeArgs = op.func.invokeContract();
const args = invokeArgs.args();
const loanIdVal = scValToNative(args[1]);
const amountVal = scValToNative(args[2]);

expect(loanIdVal).toBe(BigInt(loanId));
expect(amountVal).toBe(BigInt(inputAmount));
expect(amountVal).not.toBe(BigInt(inputAmount / 10));
}
});
});
2 changes: 1 addition & 1 deletion frontend/src/app/utils/soroban.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export async function buildUnsignedRepaymentXdr({

const borrowerScVal = new Address(borrower).toScVal();
const loanIdScVal = nativeToScVal(BigInt(loanId), { type: "u64" });
const amountScVal = nativeToScVal(BigInt(Math.floor(amount / 10)), { type: "i128" });
const amountScVal = nativeToScVal(BigInt(Math.floor(amount)), { type: "i128" });

const tx = new TransactionBuilder(source, {
fee: "10000",
Expand Down
Loading