Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add permissioned versions of all Business Scenarios #130

Merged
merged 11 commits into from
Dec 7, 2022
4 changes: 4 additions & 0 deletions contracts/Pool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,7 @@ contract Pool is IPool, ERC20Upgradeable, IBeaconImplementation {
function requestRedeem(uint256 shares)
external
onlyActivatedPool
onlyPermittedLender
onlyLender
onlyCrankedPool
returns (uint256 assets)
Expand All @@ -455,6 +456,7 @@ contract Pool is IPool, ERC20Upgradeable, IBeaconImplementation {
function requestWithdraw(uint256 assets)
external
onlyActivatedPool
onlyPermittedLender
onlyLender
onlyCrankedPool
returns (uint256 shares)
Expand Down Expand Up @@ -508,6 +510,7 @@ contract Pool is IPool, ERC20Upgradeable, IBeaconImplementation {
function cancelRedeemRequest(uint256 shares)
external
onlyActivatedPool
onlyPermittedLender
onlyLender
onlyCrankedPool
returns (uint256 assets)
Expand All @@ -526,6 +529,7 @@ contract Pool is IPool, ERC20Upgradeable, IBeaconImplementation {
function cancelWithdrawRequest(uint256 assets)
external
onlyActivatedPool
onlyPermittedLender
onlyLender
onlyCrankedPool
returns (uint256 shares)
Expand Down
6 changes: 6 additions & 0 deletions contracts/mocks/MockVeriteAccessControl.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.16;

import {VeriteAccessControl} from "../permissioned/VeriteAccessControl.sol";

contract MockVeriteAccessControl is VeriteAccessControl {}
2 changes: 1 addition & 1 deletion contracts/permissioned/VeriteAccessControl.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import "@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol";
* Other contracts should inherit this contract to add Verite-specific
* access control logic.
*/
contract VeriteAccessControl is
abstract contract VeriteAccessControl is
IVeriteAccessControl,
EIP712("VerificationRegistry", "1.0")
{
Expand Down
13 changes: 13 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"@nomicfoundation/hardhat-toolbox": "^2.0.0",
"@openzeppelin/contracts-upgradeable": "^4.8.0",
"@openzeppelin/hardhat-upgrades": "^1.21.0",
"@types/uuid": "^9.0.0",
"@typescript-eslint/eslint-plugin": "^5.36.2",
"@typescript-eslint/parser": "^5.36.2",
"eslint": "^8.23.0",
Expand Down
167 changes: 167 additions & 0 deletions test/permissioned/VeriteAccessControl.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
import { ethers } from "hardhat";
import { getSignedVerificationResult } from "../support/verite";
import { expect } from "chai";

describe("VeriteAccessControl", () => {
async function deployFixture() {
const [verifier, admin, subject, otherSubject] = await ethers.getSigners();

const VeriteAccessControl = await ethers.getContractFactory(
"MockVeriteAccessControl"
);
const veriteAccessControl = await VeriteAccessControl.deploy();
await veriteAccessControl.deployed();

return {
veriteAccessControl,
verifier,
admin,
subject,
otherSubject
};
}

describe("verify()", () => {
it("succeeds when given a valid verification result from a trusted verifier", async () => {
const { veriteAccessControl, verifier, admin, subject } =
await deployFixture();

// Register the verifier
await veriteAccessControl
.connect(admin)
.addTrustedVerifier(verifier.address);

// Get a signed verification result
const { verificationResult, signature } =
await getSignedVerificationResult(
veriteAccessControl.address,
subject.address,
verifier
);

// Register the schema
await veriteAccessControl
.connect(admin)
.addCredentialSchema(verificationResult.schema);

// Verify the verification result
await expect(
veriteAccessControl
.connect(subject)
.verify(verificationResult, signature)
)
.to.emit(veriteAccessControl, "VerificationResultConfirmed")
.withArgs(subject.address);
});

it("reverts if the verifier is not trusted", async () => {
const { veriteAccessControl, verifier, admin, subject } =
await deployFixture();

// Get a signed verification result
const { verificationResult, signature } =
await getSignedVerificationResult(
veriteAccessControl.address,
subject.address,
verifier
);

// Register the schema
await veriteAccessControl
.connect(admin)
.addCredentialSchema(verificationResult.schema);

await expect(
veriteAccessControl
.connect(subject)
.verify(verificationResult, signature)
).to.be.revertedWith("INVALID_SIGNER");
});

it("reverts if the schema is not valid", async () => {
const { veriteAccessControl, verifier, admin, subject } =
await deployFixture();

// Register the verifier
await veriteAccessControl
.connect(admin)
.addTrustedVerifier(verifier.address);

// Get a signed verification result
const { verificationResult, signature } =
await getSignedVerificationResult(
veriteAccessControl.address,
subject.address,
verifier
);

// Verify the verification result
await expect(
veriteAccessControl
.connect(subject)
.verify(verificationResult, signature)
).to.be.revertedWith("INVALID_CREDENTIAL_SCHEMA");
});

it("reverts if the subject does not match the sender", async () => {
const { veriteAccessControl, verifier, admin, subject, otherSubject } =
await deployFixture();

// Register the verifier
await veriteAccessControl
.connect(admin)
.addTrustedVerifier(verifier.address);

// Get a signed verification result
const { verificationResult, signature } =
await getSignedVerificationResult(
veriteAccessControl.address,
subject.address,
verifier
);

// Register the schema
await veriteAccessControl
.connect(admin)
.addCredentialSchema(verificationResult.schema);

// Verify the verification result
await expect(
veriteAccessControl
.connect(otherSubject)
.verify(verificationResult, signature)
).to.be.revertedWith("SUBJECT_MISMATCH");
});

it("reverts if the result is expired", async () => {
const { veriteAccessControl, verifier, admin, subject } =
await deployFixture();

// Register the verifier
await veriteAccessControl
.connect(admin)
.addTrustedVerifier(verifier.address);

// Get a signed verification result
const { verificationResult, signature } =
await getSignedVerificationResult(
veriteAccessControl.address,
subject.address,
verifier,
{ expiration: 0 }
);

// Register the schema
await veriteAccessControl
.connect(admin)
.addCredentialSchema(verificationResult.schema);

// Verify the verification result
await expect(
veriteAccessControl
.connect(subject)
.verify(verificationResult, signature)
).to.be.revertedWith("VERIFICATION_RESULT_EXPIRED");
});
});
});
2 changes: 1 addition & 1 deletion test/scenarios/business/2.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ describe("Business Scenario 2", () => {
expect(await pool.maxWithdraw(lenderA.address)).to.equal(0);
expect(await pool.maxWithdraw(lenderB.address)).to.equal(0);

// +8 days, lenderB requests 300k PT redeption
// +8 days, lenderB requests 300k PT redemption
await advanceToDay(startTime, 8);
await pool.connect(lenderB).requestRedeem(300_000_000_000);

Expand Down
16 changes: 8 additions & 8 deletions test/scenarios/business/3.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ describe("Business Scenario 3", () => {
}

async function fixtures() {
const [operator, poolManager, lenderA, lenderB, borrower] =
const [operator, poolAdmin, lenderA, lenderB, borrower] =
await ethers.getSigners();
const endTime = (await time.latest()) + 5_184_000; // 60 days.
const poolSettings = {
Expand All @@ -53,7 +53,7 @@ describe("Business Scenario 3", () => {
);
const { pool, serviceConfiguration, poolController } = await deployPool({
operator,
poolAdmin: poolManager,
poolAdmin: poolAdmin,
settings: poolSettings,
liquidityAsset: mockUSDC
});
Expand All @@ -62,7 +62,7 @@ describe("Business Scenario 3", () => {
expect(await serviceConfiguration.firstLossFeeBps()).to.equal(500);

// activate pool
await activatePool(pool, poolManager, mockUSDC);
await activatePool(pool, poolAdmin, mockUSDC);
const startTime = (await pool.activatedAt()).toNumber();

// Mint for lenders
Expand Down Expand Up @@ -95,7 +95,7 @@ describe("Business Scenario 3", () => {
lenderA,
lenderB,
mockUSDC,
poolManager,
poolAdmin,
borrower,
loan
};
Expand All @@ -109,7 +109,7 @@ describe("Business Scenario 3", () => {
lenderA,
lenderB,
mockUSDC,
poolManager,
poolAdmin,
borrower,
loan
} = await loadFixture(fixtures);
Expand All @@ -118,7 +118,7 @@ describe("Business Scenario 3", () => {
// check that FL is zero
expect(await poolController.firstLossBalance()).to.equal(0);
// Check that PM has no USDC balance
expect(await mockUSDC.balanceOf(poolManager.address)).to.equal(0);
expect(await mockUSDC.balanceOf(poolAdmin.address)).to.equal(0);

// +2 days, lenderA deposits
await advanceToDay(startTime, 2);
Expand Down Expand Up @@ -148,15 +148,15 @@ describe("Business Scenario 3", () => {

// +4 days, loan is funded
await advanceToDay(startTime, 4);
await fundLoan(loan, poolController, poolManager);
await fundLoan(loan, poolController, poolAdmin);
await loan.connect(borrower).drawdown(INPUTS.loan.principal);

// +7 days, lenderA requests 200k PT redemption
await advanceToDay(startTime, 7);
await pool.crank(); // crank runs, but is meaningless
await pool.connect(lenderA).requestRedeem(200_000_000_000);

// +8 days, lenderB requests 300k PT redeption
// +8 days, lenderB requests 300k PT redemption
await advanceToDay(startTime, 8);
await pool.connect(lenderB).requestRedeem(300_000_000_000);

Expand Down
2 changes: 1 addition & 1 deletion test/scenarios/business/4.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ describe("Business Scenario 4", () => {
await pool.crank(); // crank runs, but is meaningless
await pool.connect(lenderA).requestRedeem(200_000_000_000);

// +8 days, lenderB requests 300k PT redeption
// +8 days, lenderB requests 300k PT redemption
await advanceToDay(startTime, 8);
await pool.connect(lenderB).requestRedeem(300_000_000_000);

Expand Down
Loading