Aere Network public source. Everything here can be checked against the live chain (chain id 2800, https://rpc.aere.network). Scope note, stated up front rather than buried: consensus on chain 2800 is classical secp256k1 ECDSA QBFT. The post-quantum work in this repository is at the signature, precompile, account and transport layers. Nothing here makes the consensus post-quantum, and no document in it should be read as claiming so.
161 lines
6.0 KiB
JavaScript
161 lines
6.0 KiB
JavaScript
const { expect } = require("chai");
|
|
const { ethers } = require("hardhat");
|
|
|
|
describe("AereBestExReceipt", () => {
|
|
let foundation, casp1, casp2, outsider;
|
|
let reg;
|
|
|
|
const LICENCE_REF = ethers.keccak256(ethers.toUtf8Bytes("MICA-XYZ-12345||DE-BAFIN||LEI-1234"));
|
|
|
|
beforeEach(async () => {
|
|
[foundation, casp1, casp2, outsider] = await ethers.getSigners();
|
|
const F = await ethers.getContractFactory("AereBestExReceipt");
|
|
reg = await F.deploy(foundation.address);
|
|
await reg.waitForDeployment();
|
|
});
|
|
|
|
function blankReceipt(caspAddr, overrides = {}) {
|
|
return {
|
|
casp: caspAddr,
|
|
clientHash: ethers.keccak256(ethers.toUtf8Bytes("client-42")),
|
|
clientClass: 0, // Retail
|
|
orderId: ethers.keccak256(ethers.toUtf8Bytes("order-1")),
|
|
orderType: 0, // Market
|
|
instrumentSymbol: ethers.keccak256(ethers.toUtf8Bytes("BTC/EUR")),
|
|
requestedQty: ethers.parseUnits("1", 18),
|
|
executedQty: ethers.parseUnits("1", 18),
|
|
executedPrice: ethers.parseUnits("63000", 18),
|
|
executedVenue: ethers.keccak256(ethers.toUtf8Bytes("Binance.com")),
|
|
alternativesRoot: ethers.keccak256(ethers.toUtf8Bytes("merkle-root-alts")),
|
|
algorithmRef: ethers.keccak256(ethers.toUtf8Bytes("SOR-v3.1||abc123")),
|
|
decisionTsMs: 1717880000000n,
|
|
executionTsMs: 1717880000420n,
|
|
evidenceUri: "ipfs://bafy...alts.json",
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
it("registers a CASP only by the Foundation", async () => {
|
|
await expect(
|
|
reg.connect(outsider).registerCasp(casp1.address, LICENCE_REF)
|
|
).to.be.revertedWithCustomError(reg, "NotFoundation");
|
|
await reg.connect(foundation).registerCasp(casp1.address, LICENCE_REF);
|
|
expect((await reg.caspOf(casp1.address)).exists).to.equal(true);
|
|
});
|
|
|
|
it("rejects double-registration + zero licence", async () => {
|
|
await reg.connect(foundation).registerCasp(casp1.address, LICENCE_REF);
|
|
await expect(
|
|
reg.connect(foundation).registerCasp(casp1.address, LICENCE_REF)
|
|
).to.be.revertedWithCustomError(reg, "CaspExists");
|
|
await expect(
|
|
reg.connect(foundation).registerCasp(casp2.address, ethers.ZeroHash)
|
|
).to.be.revertedWithCustomError(reg, "ZeroLicence");
|
|
});
|
|
|
|
it("issues a receipt, increments nonce, emits the full event", async () => {
|
|
await reg.connect(foundation).registerCasp(casp1.address, LICENCE_REF);
|
|
const r = blankReceipt(casp1.address);
|
|
const expectedId = await reg.nextReceiptId(casp1.address);
|
|
|
|
await expect(reg.connect(casp1).issueReceipt(r))
|
|
.to.emit(reg, "ReceiptIssued")
|
|
.withArgs(
|
|
casp1.address,
|
|
expectedId,
|
|
r.clientHash,
|
|
r.instrumentSymbol,
|
|
r.executedVenue,
|
|
r.alternativesRoot,
|
|
r.executedQty,
|
|
r.executedPrice,
|
|
r.decisionTsMs,
|
|
r.executionTsMs,
|
|
r.algorithmRef,
|
|
r.evidenceUri
|
|
);
|
|
|
|
expect(await reg.issuedCount(casp1.address)).to.equal(1n);
|
|
expect(await reg.receiptNonce(casp1.address)).to.equal(1n);
|
|
const stored = await reg.getReceipt(expectedId);
|
|
expect(stored.executedPrice).to.equal(r.executedPrice);
|
|
expect(await reg.executionLatencyMs(expectedId)).to.equal(420n);
|
|
expect(await reg.caspIsActive(casp1.address)).to.equal(true);
|
|
});
|
|
|
|
it("rejects unregistered, paused, and mismatched-casp issuance", async () => {
|
|
const r = blankReceipt(casp1.address);
|
|
// unregistered
|
|
await expect(reg.connect(casp1).issueReceipt(r)).to.be.revertedWithCustomError(reg, "CaspUnknown");
|
|
|
|
await reg.connect(foundation).registerCasp(casp1.address, LICENCE_REF);
|
|
|
|
// r.casp != msg.sender
|
|
await expect(
|
|
reg.connect(casp1).issueReceipt(blankReceipt(casp2.address))
|
|
).to.be.revertedWithCustomError(reg, "CaspUnknown");
|
|
|
|
// pause then attempt
|
|
await reg.connect(foundation).setCaspPaused(casp1.address, true);
|
|
await expect(reg.connect(casp1).issueReceipt(r)).to.be.revertedWithCustomError(reg, "CaspIsPaused");
|
|
|
|
// unpause + succeed
|
|
await reg.connect(foundation).setCaspPaused(casp1.address, false);
|
|
await reg.connect(casp1).issueReceipt(r);
|
|
});
|
|
|
|
it("rejects malformed receipts (timestamps, qty, alts root)", async () => {
|
|
await reg.connect(foundation).registerCasp(casp1.address, LICENCE_REF);
|
|
// execution before decision
|
|
await expect(
|
|
reg.connect(casp1).issueReceipt(
|
|
blankReceipt(casp1.address, { decisionTsMs: 1000n, executionTsMs: 500n })
|
|
)
|
|
).to.be.revertedWithCustomError(reg, "BadTimestamps");
|
|
|
|
// zero qty
|
|
await expect(
|
|
reg.connect(casp1).issueReceipt(blankReceipt(casp1.address, { executedQty: 0 }))
|
|
).to.be.revertedWithCustomError(reg, "BadQuantities");
|
|
|
|
// over-execution
|
|
await expect(
|
|
reg.connect(casp1).issueReceipt(
|
|
blankReceipt(casp1.address, {
|
|
requestedQty: ethers.parseUnits("1", 18),
|
|
executedQty: ethers.parseUnits("2", 18),
|
|
})
|
|
)
|
|
).to.be.revertedWithCustomError(reg, "BadQuantities");
|
|
|
|
// zero alts root
|
|
await expect(
|
|
reg.connect(casp1).issueReceipt(
|
|
blankReceipt(casp1.address, { alternativesRoot: ethers.ZeroHash })
|
|
)
|
|
).to.be.revertedWithCustomError(reg, "BadAlternatives");
|
|
|
|
// zero venue
|
|
await expect(
|
|
reg.connect(casp1).issueReceipt(
|
|
blankReceipt(casp1.address, { executedVenue: ethers.ZeroHash })
|
|
)
|
|
).to.be.revertedWithCustomError(reg, "BadAlternatives");
|
|
});
|
|
|
|
it("caspIsActive false until first receipt issued", async () => {
|
|
await reg.connect(foundation).registerCasp(casp1.address, LICENCE_REF);
|
|
expect(await reg.caspIsActive(casp1.address)).to.equal(false);
|
|
await reg.connect(casp1).issueReceipt(blankReceipt(casp1.address));
|
|
expect(await reg.caspIsActive(casp1.address)).to.equal(true);
|
|
});
|
|
|
|
it("receiptIds for distinct CASPs do not collide", async () => {
|
|
await reg.connect(foundation).registerCasp(casp1.address, LICENCE_REF);
|
|
await reg.connect(foundation).registerCasp(casp2.address, LICENCE_REF);
|
|
const id1 = await reg.nextReceiptId(casp1.address);
|
|
const id2 = await reg.nextReceiptId(casp2.address);
|
|
expect(id1).to.not.equal(id2);
|
|
});
|
|
});
|