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

test: events for all contracts #74

Merged
merged 5 commits into from
Dec 2, 2024
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
4 changes: 0 additions & 4 deletions contracts/governance/Comp.sol
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,6 @@ abstract contract Comp is IComp, EncryptedERC20, EIP712, Ownable2Step {
/// @notice Emitted when an `account` (i.e. `delegator`) changes its delegate.
event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);

/// @notice Emitted when a `delegate` account's vote balance changes.
event DelegateVotesChanged(address indexed delegate);

/// @notice Emitted when the governor contract that can reencrypt votes changes.
/// @dev WARNING: it can be set to a malicious contract, which could reencrypt all user votes.
event NewGovernor(address indexed governor);
Expand Down Expand Up @@ -296,6 +293,5 @@ abstract contract Comp is IComp, EncryptedERC20, EIP712, Ownable2Step {

TFHE.allowThis(newVotes);
TFHE.allow(newVotes, delegatee);
emit DelegateVotesChanged(delegatee);
}
}
14 changes: 7 additions & 7 deletions contracts/governance/GovernorAlphaZama.sol
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ abstract contract GovernorAlphaZama is Ownable2Step, GatewayCaller {
string description
);

/// @notice Emitted when a proposal is defeated either by lack of votes or by
/// more votes against.
/// @notice Emitted when a proposal is defeated either by (1) number of `for` votes inferior to the
/// quorum, (2) the number of `for` votes equal or inferior to `against` votes.
event ProposalDefeated(uint256 id);

/// @notice Emitted when a proposal has been executed in the Timelock.
Expand All @@ -79,12 +79,12 @@ abstract contract GovernorAlphaZama is Ownable2Step, GatewayCaller {
/// @notice Emitted when a proposal has been queued in the Timelock.
event ProposalQueued(uint256 id, uint256 eta);

/// @notice Emitted when a proposal has been rejected since the number of votes is lower
/// than the required threshold.
/// @notice Emitted when a proposal has been rejected since the number of votes of the proposer
/// is lower than the required threshold.
event ProposalRejected(uint256 id);

/// @notice Emitted when a proposal has been rejected since the number of votes is lower
/// than the required threshold.
/// @notice Emitted when a proposal has succeeded since the number of `for` votes is higher
/// than quorum and strictly higher than `against` votes.
event ProposalSucceeded(uint256 id);

/// @notice Emitted when a vote has been cast on a proposal.
Expand All @@ -99,7 +99,7 @@ abstract contract GovernorAlphaZama is Ownable2Step, GatewayCaller {
* @param PendingResults Proposal is not active and the result decryption is in progress.
* @param Canceled Proposal has been canceled by the proposer or by this contract's owner.
* @param Defeated Proposal has been defeated
* (either not reaching the quorum or `againstVotes` > `forVotes`).
* (either not reaching the quorum or `againstVotes` >= `forVotes`).
* @param Succeeded Proposal has succeeded (`forVotes` > `againstVotes`).
* @param Queued Proposal has been queued in the `Timelock`.
* @param Expired Proposal has expired (@dev This state exists only in read-only functions).
Expand Down
36 changes: 26 additions & 10 deletions test/encryptedERC20/EncryptedERC20.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import { getSigners, initSigners } from "../signers";
import { deployEncryptedERC20Fixture, reencryptAllowance, reencryptBalance } from "./EncryptedERC20.fixture";

describe("EncryptedERC20", function () {
// @dev The placeholder is type(uint256).max --> 2**256 - 1.
const PLACEHOLDER = 2n ** 256n - 1n;

before(async function () {
await initSigners(2);
this.signers = await getSigners();
Expand All @@ -27,7 +30,7 @@ describe("EncryptedERC20", function () {
it("should mint the contract", async function () {
const mintAmount = 1000;
const tx = await this.encryptedERC20.connect(this.signers.alice).mint(mintAmount);
await tx.wait();
await expect(tx).to.emit(this.encryptedERC20, "Mint").withArgs(this.signers.alice, mintAmount);

expect(
await reencryptBalance(this.signers, this.instances, "alice", this.encryptedERC20, this.encryptedERC20Address),
Expand All @@ -47,13 +50,15 @@ describe("EncryptedERC20", function () {
input.add64(transferAmount);
const encryptedTransferAmount = await input.encrypt();

tx = await this.encryptedERC20["transfer(address,bytes32,bytes)"](
this.signers.bob.address,
encryptedTransferAmount.handles[0],
encryptedTransferAmount.inputProof,
);
tx = await this.encryptedERC20
.connect(this.signers.alice)
[
"transfer(address,bytes32,bytes)"
](this.signers.bob.address, encryptedTransferAmount.handles[0], encryptedTransferAmount.inputProof);

await tx.wait();
await expect(tx)
.to.emit(this.encryptedERC20, "Transfer")
.withArgs(this.signers.alice, this.signers.bob, PLACEHOLDER);

// Decrypt Alice's balance
expect(
Expand All @@ -78,12 +83,17 @@ describe("EncryptedERC20", function () {
const input = this.instances.alice.createEncryptedInput(this.encryptedERC20Address, this.signers.alice.address);
input.add64(transferAmount);
const encryptedTransferAmount = await input.encrypt();

tx = await this.encryptedERC20["transfer(address,bytes32,bytes)"](
this.signers.bob.address,
encryptedTransferAmount.handles[0],
encryptedTransferAmount.inputProof,
);
await tx.wait();

// @dev There is no error-handling in this version of EncryptedERC20.
await expect(tx)
.to.emit(this.encryptedERC20, "Transfer")
.withArgs(this.signers.alice, this.signers.bob, PLACEHOLDER);

// Decrypt Alice's balance
expect(
Expand Down Expand Up @@ -117,7 +127,10 @@ describe("EncryptedERC20", function () {
encryptedAllowanceAmount.handles[0],
encryptedAllowanceAmount.inputProof,
);
await tx.wait();

await expect(tx)
.to.emit(this.encryptedERC20, "Approval")
.withArgs(this.signers.alice, this.signers.bob, PLACEHOLDER);

// @dev The allowance amount is set to be equal to the transfer amount.
expect(
Expand All @@ -142,7 +155,10 @@ describe("EncryptedERC20", function () {
encryptedTransferAmount.handles[0],
encryptedTransferAmount.inputProof,
);
await tx2.wait();

await expect(tx2)
.to.emit(this.encryptedERC20, "Transfer")
.withArgs(this.signers.alice, this.signers.bob, PLACEHOLDER);

// Decrypt Alice's balance
expect(
Expand Down
6 changes: 3 additions & 3 deletions test/encryptedERC20/EncryptedERC20WithErrors.fixture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ export async function checkErrorCode(
const errorCodeHandle = await token.getErrorCodeForTransferId(transferId);
const errorCode = await reencryptEuint8(signers, instances, account, errorCodeHandle, tokenAddress);
switch (errorCode) {
case BigInt(0): {
case 0n: {
return "NO_ERROR";
}
case BigInt(1): {
case 1n: {
return "UNSUFFICIENT_BALANCE";
}
case BigInt(2): {
case 2n: {
return "UNSUFFICIENT_APPROVAL";
}
default: {
Expand Down
78 changes: 51 additions & 27 deletions test/encryptedERC20/EncryptedERC20WithErrors.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { reencryptAllowance, reencryptBalance } from "./EncryptedERC20.fixture";
import { checkErrorCode, deployEncryptedERC20WithErrorsFixture } from "./EncryptedERC20WithErrors.fixture";

describe("EncryptedERC20WithErrors", function () {
const DEFAULT_TRANSFER_ID = BigInt(0);
const DEFAULT_SECOND_TRANSFER_ID = BigInt(1);
// @dev The placeholder is type(uint256).max --> 2**256 - 1.
const PLACEHOLDER = 2n ** 256n - 1n;

before(async function () {
await initSigners(2);
Expand All @@ -31,7 +31,7 @@ describe("EncryptedERC20WithErrors", function () {
it("should mint the contract", async function () {
const mintAmount = 1000;
const tx = await this.encryptedERC20.connect(this.signers.alice).mint(mintAmount);
await tx.wait();
await expect(tx).to.emit(this.encryptedERC20, "Mint").withArgs(this.signers.alice, mintAmount);

expect(
await reencryptBalance(this.signers, this.instances, "alice", this.encryptedERC20, this.encryptedERC20Address),
Expand All @@ -43,6 +43,7 @@ describe("EncryptedERC20WithErrors", function () {
it("should transfer tokens between two users", async function () {
const mintAmount = 10_000;
const transferAmount = 1337;
const expectedTransferId = 0n;

let tx = await this.encryptedERC20.connect(this.signers.alice).mint(mintAmount);
await tx.wait();
Expand All @@ -57,7 +58,9 @@ describe("EncryptedERC20WithErrors", function () {
"transfer(address,bytes32,bytes)"
](this.signers.bob.address, encryptedTransferAmount.handles[0], encryptedTransferAmount.inputProof);

await tx.wait();
await expect(tx)
.to.emit(this.encryptedERC20, "Transfer")
.withArgs(this.signers.alice, this.signers.bob, expectedTransferId);

// Decrypt Alice's balance
expect(
Expand All @@ -75,7 +78,7 @@ describe("EncryptedERC20WithErrors", function () {
this.signers,
this.instances,
"alice",
DEFAULT_TRANSFER_ID,
expectedTransferId,
this.encryptedERC20,
this.encryptedERC20Address,
),
Expand All @@ -87,7 +90,7 @@ describe("EncryptedERC20WithErrors", function () {
this.signers,
this.instances,
"bob",
DEFAULT_TRANSFER_ID,
expectedTransferId,
this.encryptedERC20,
this.encryptedERC20Address,
),
Expand All @@ -99,19 +102,24 @@ describe("EncryptedERC20WithErrors", function () {
// amount.
const mintAmount = 1000;
const transferAmount = 1337;
const expectedTransferId = 0n;

let tx = await this.encryptedERC20.connect(this.signers.alice).mint(mintAmount);
await tx.wait();

const input = this.instances.alice.createEncryptedInput(this.encryptedERC20Address, this.signers.alice.address);
input.add64(transferAmount);
const encryptedTransferAmount = await input.encrypt();

tx = await this.encryptedERC20["transfer(address,bytes32,bytes)"](
this.signers.bob.address,
encryptedTransferAmount.handles[0],
encryptedTransferAmount.inputProof,
);
await tx.wait();

await expect(tx)
.to.emit(this.encryptedERC20, "Transfer")
.withArgs(this.signers.alice, this.signers.bob, expectedTransferId);

// Decrypt Alice's balance
expect(
Expand All @@ -129,7 +137,7 @@ describe("EncryptedERC20WithErrors", function () {
this.signers,
this.instances,
"bob",
DEFAULT_TRANSFER_ID,
expectedTransferId,
this.encryptedERC20,
this.encryptedERC20Address,
),
Expand Down Expand Up @@ -157,7 +165,10 @@ describe("EncryptedERC20WithErrors", function () {
encryptedAllowanceAmount.handles[0],
encryptedAllowanceAmount.inputProof,
);
await tx.wait();

await expect(tx)
.to.emit(this.encryptedERC20, "Approval")
.withArgs(this.signers.alice, this.signers.bob, PLACEHOLDER);

// @dev The allowance amount is set to be equal to the transfer amount.
expect(
Expand All @@ -171,18 +182,21 @@ describe("EncryptedERC20WithErrors", function () {
),
).to.equal(transferAmount);

const bobErc20 = this.encryptedERC20.connect(this.signers.bob);
const expectedTransferId1 = 0n;

const inputBob1 = this.instances.bob.createEncryptedInput(this.encryptedERC20Address, this.signers.bob.address);
inputBob1.add64(transferAmount + 1); // above allowance so next tx should actually not send any token
const encryptedTransferAmount = await inputBob1.encrypt();

const tx2 = await bobErc20["transferFrom(address,address,bytes32,bytes)"](
this.signers.alice.address,
this.signers.bob.address,
encryptedTransferAmount.handles[0],
encryptedTransferAmount.inputProof,
);
await tx2.wait();
const tx2 = await this.encryptedERC20
.connect(this.signers.bob)
[
"transferFrom(address,address,bytes32,bytes)"
](this.signers.alice.address, this.signers.bob.address, encryptedTransferAmount.handles[0], encryptedTransferAmount.inputProof);

await expect(tx2)
.to.emit(this.encryptedERC20, "Transfer")
.withArgs(this.signers.alice, this.signers.bob, expectedTransferId1);

// Decrypt Alice's balance
expect(
Expand All @@ -200,23 +214,27 @@ describe("EncryptedERC20WithErrors", function () {
this.signers,
this.instances,
"bob",
DEFAULT_TRANSFER_ID,
expectedTransferId1,
this.encryptedERC20,
this.encryptedERC20Address,
),
).to.equal("UNSUFFICIENT_APPROVAL");

const expectedTransferId2 = 1n;

const inputBob2 = this.instances.bob.createEncryptedInput(this.encryptedERC20Address, this.signers.bob.address);
inputBob2.add64(transferAmount); // below allowance so next tx should send token
const encryptedTransferAmount2 = await inputBob2.encrypt();

const tx3 = await bobErc20["transferFrom(address,address,bytes32,bytes)"](
this.signers.alice.address,
this.signers.bob.address,
encryptedTransferAmount2.handles[0],
encryptedTransferAmount2.inputProof,
);
await tx3.wait();
const tx3 = await await this.encryptedERC20
.connect(this.signers.bob)
[
"transferFrom(address,address,bytes32,bytes)"
](this.signers.alice.address, this.signers.bob.address, encryptedTransferAmount2.handles[0], encryptedTransferAmount2.inputProof);

await expect(tx3)
.to.emit(this.encryptedERC20, "Transfer")
.withArgs(this.signers.alice, this.signers.bob, expectedTransferId2);

// Decrypt Alice's balance
expect(
Expand Down Expand Up @@ -246,7 +264,7 @@ describe("EncryptedERC20WithErrors", function () {
this.signers,
this.instances,
"bob",
DEFAULT_SECOND_TRANSFER_ID,
expectedTransferId2,
this.encryptedERC20,
this.encryptedERC20Address,
),
Expand Down Expand Up @@ -439,6 +457,8 @@ describe("EncryptedERC20WithErrors", function () {
it("cannot reencrypt errors if the account is not a participant of the transfer", async function () {
const mintAmount = 10_000;
const transferAmount = 1337;
const expectedTransferId = 0;

let tx = await this.encryptedERC20.connect(this.signers.alice).mint(mintAmount);
await tx.wait();

Expand All @@ -452,7 +472,11 @@ describe("EncryptedERC20WithErrors", function () {
"transfer(address,bytes32,bytes)"
](this.signers.bob.address, encryptedTransferAmount.handles[0], encryptedTransferAmount.inputProof);

const errorCodeHandle = await this.encryptedERC20.getErrorCodeForTransferId(DEFAULT_TRANSFER_ID);
await expect(tx)
.to.emit(this.encryptedERC20, "Transfer")
.withArgs(this.signers.alice, this.signers.bob, expectedTransferId);

const errorCodeHandle = await this.encryptedERC20.getErrorCodeForTransferId(expectedTransferId);

const { publicKey: publicKeyCarol, privateKey: privateKeyCarol } = this.instances.carol.generateKeypair();
const eip712Carol = this.instances.carol.createEIP712(publicKeyCarol, this.encryptedERC20Address);
Expand Down
Loading