Skip to content

Commit

Permalink
feat: expiration timestamp for citizen (#72)
Browse files Browse the repository at this point in the history
  • Loading branch information
aahna-ashina committed Oct 21, 2023
1 parent ff8301f commit d914b59
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 18 deletions.
22 changes: 16 additions & 6 deletions contracts/mock/VotingEscrowMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,29 @@ pragma solidity ^0.8.17;

import "../governance/IVotingEscrow.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "hardhat/console.sol";

contract VotingEscrowMock is ERC20, IVotingEscrow {
mapping(address => LockedBalance) locks;

constructor() ERC20("Vote-escrowed NATION", "veNATION") {
_mint(msg.sender, 100 * 1e18);
}

function locked(
address
) public view returns (LockedBalance memory lockedBalance) {
function create_lock(int128 _value, uint256 _unlock_time) public {
console.log("create_lock");
console.log("uint256(int256(_value)):", uint256(int256(_value)));
console.log("_unlock_time:", _unlock_time);
LockedBalance memory lockedBalance = LockedBalance({
amount: 1,
end: block.timestamp
amount: _value,
end: _unlock_time
});
return lockedBalance;
locks[msg.sender] = lockedBalance;
}

function locked(
address account
) public view returns (LockedBalance memory lockedBalance) {
return locks[account];
}
}
22 changes: 18 additions & 4 deletions contracts/utils/PassportUtils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,19 @@ pragma solidity ^0.8.17;

import "./IPassportUtils.sol";
import "../passport/IPassportIssuer.sol";
import "../governance/IVotingEscrow.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "hardhat/console.sol";

contract PassportUtils is IPassportUtils {
using SafeERC20 for IERC20;

IPassportIssuer public passportIssuer;
IERC20 public votingEscrow;
IVotingEscrow public votingEscrow;

constructor(address passportIssuerAddress, address votingEscrowAddress) {
passportIssuer = IPassportIssuer(passportIssuerAddress);
votingEscrow = IERC20(votingEscrowAddress);
votingEscrow = IVotingEscrow(votingEscrowAddress);
}

function isExpired(address citizen) public view returns (bool) {
Expand All @@ -28,8 +29,21 @@ contract PassportUtils is IPassportUtils {
function getExpirationTimestamp(
address citizen
) public view returns (uint256) {
// TO DO
return 0;
IVotingEscrow.LockedBalance memory lockedBalance = votingEscrow.locked(
citizen
);
uint256 lockAmount = uint256(int256(lockedBalance.amount));
console.log("lockAmount:", lockAmount);
uint256 lockEnd = lockedBalance.end;
console.log("lockEnd:", lockEnd);
uint256 revokeUnderBalance = passportIssuer.revokeUnderBalance();
console.log("revokeUnderBalance:", revokeUnderBalance);
return
calculateThresholdTimestamp(
lockAmount,
lockEnd,
revokeUnderBalance
);
}

function calculateThresholdTimestamp(
Expand Down
86 changes: 78 additions & 8 deletions test/PassportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ describe("PassportUtils", function () {
});

it("should return true if voting escrow balance is 1.4999", async function () {
const { votingEscrow, passportUtils, otherAccount } = await loadFixture(
const { votingEscrow, passportUtils, owner, otherAccount } = await loadFixture(

Check failure on line 41 in test/PassportUtils.ts

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 16.x)

'owner' is assigned a value but never used

Check failure on line 41 in test/PassportUtils.ts

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 16.x)

Replace `·await·loadFixture(⏎········deploymentFixture⏎······` with `⏎········await·loadFixture(deploymentFixture`
deploymentFixture
);

Expand All @@ -54,7 +54,7 @@ describe("PassportUtils", function () {
});

it("should return false if voting escrow balance is 1.5000", async function () {
const { votingEscrow, passportUtils, otherAccount } = await loadFixture(
const { votingEscrow, passportUtils, owner, otherAccount } = await loadFixture(

Check failure on line 57 in test/PassportUtils.ts

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 16.x)

'owner' is assigned a value but never used

Check failure on line 57 in test/PassportUtils.ts

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 16.x)

Replace `·await·loadFixture(⏎········deploymentFixture⏎······` with `⏎········await·loadFixture(deploymentFixture`
deploymentFixture
);

Expand All @@ -71,8 +71,8 @@ describe("PassportUtils", function () {
});

describe("calculateThresholdTimestamp", function () {
it("votingEscrowThreshold 1.5 - should return 2 years into the future if 3 $NATION locked for 4 years", async function () {
const { votingEscrow, passportUtils, otherAccount } = await loadFixture(
it("votingEscrowThreshold 1.5 - 3 $NATION locked for 4 years", async function () {
const { votingEscrow, passportUtils, owner, otherAccount } = await loadFixture(

Check failure on line 75 in test/PassportUtils.ts

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 16.x)

'votingEscrow' is assigned a value but never used

Check failure on line 75 in test/PassportUtils.ts

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 16.x)

'owner' is assigned a value but never used

Check failure on line 75 in test/PassportUtils.ts

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 16.x)

'otherAccount' is assigned a value but never used

Check failure on line 75 in test/PassportUtils.ts

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 16.x)

Replace `·await·loadFixture(⏎········deploymentFixture⏎······` with `⏎········await·loadFixture(deploymentFixture`
deploymentFixture
);

Expand Down Expand Up @@ -115,16 +115,16 @@ describe("PassportUtils", function () {
);
});

it("votingEscrowThreshold 1.5 - should return 3 years into the future if 6 $NATION locked for 4 years", async function () {
const { votingEscrow, passportUtils, otherAccount } = await loadFixture(
it("votingEscrowThreshold 1.5 - 6 $NATION locked for 4 years", async function () {
const { votingEscrow, passportUtils, owner, otherAccount } = await loadFixture(

Check failure on line 119 in test/PassportUtils.ts

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 16.x)

'votingEscrow' is assigned a value but never used

Check failure on line 119 in test/PassportUtils.ts

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 16.x)

'owner' is assigned a value but never used
deploymentFixture
);

const lockAmount = ethers.utils.parseUnits("6");
const oneYearInMilliseconds = 365 * 24 * 60 * 60 * 1_000;

const lockEnd = new Date(
new Date().getTime() + 4 * oneYearInMilliseconds
new Date().getTime() + (4 * oneYearInMilliseconds)
);
console.log("lockEnd:", lockEnd);
const lockEndInSeconds = Math.round(lockEnd.getTime() / 1_000);
Expand All @@ -133,7 +133,7 @@ describe("PassportUtils", function () {
const votingEscrowThreshold = ethers.utils.parseUnits("1.5");

const expectedThresholdDate = new Date(
new Date().getTime() + 3 * oneYearInMilliseconds
new Date().getTime() + (3 * oneYearInMilliseconds)
);
console.log("expectedThresholdDate:", expectedThresholdDate);
const expectedThresholdDateInSeconds = Math.round(
Expand All @@ -159,4 +159,74 @@ describe("PassportUtils", function () {
);
});
});

describe("getExpirationTimestamp", function() {
it("votingEscrowThreshold 1.5 - 3 $NATION locked for 4 years", async function () {
const { votingEscrow, passportUtils, owner, otherAccount } = await loadFixture(
deploymentFixture
);

const oneYearInMilliseconds = 365 * 24 * 60 * 60 * 1_000;
const initialLockDate = new Date();
console.log('initialLockDate:', initialLockDate);

// Lock 3 $NATION for 4 years
const lockAmount = ethers.utils.parseUnits('3');
const lockEnd = new Date(initialLockDate.getTime() + (4 * oneYearInMilliseconds));
console.log('lockEnd:', lockEnd);
const lockEndInSeconds = Math.round(lockEnd.getTime() / 1_000);
await votingEscrow.create_lock(lockAmount, ethers.BigNumber.from(lockEndInSeconds));

const expectedExpirationDate = new Date(
initialLockDate.getTime() + (2 * oneYearInMilliseconds)
);
console.log("expectedExpirationDate:", expectedExpirationDate);
const expectedExpirationDateInSeconds = Math.round(
expectedExpirationDate.getTime() / 1_000
);
console.log(
"expectedExpirationDateInSeconds:",
expectedExpirationDateInSeconds
);

const expirationTimestamp = await passportUtils.getExpirationTimestamp(owner.address);
console.log("expirationTimestamp:", expirationTimestamp);
console.log("expirationTimestamp (Date):", new Date(expirationTimestamp * 1_000));
expect(expirationTimestamp).to.equal(ethers.BigNumber.from(expectedExpirationDateInSeconds));
});

it("votingEscrowThreshold 1.5 - 6 $NATION locked for 4 years", async function () {
const { votingEscrow, passportUtils, owner, otherAccount } = await loadFixture(
deploymentFixture
);

const oneYearInMilliseconds = 365 * 24 * 60 * 60 * 1_000;
const initialLockDate = new Date();
console.log('initialLockDate:', initialLockDate);

// Lock 6 $NATION for 4 years
const lockAmount = ethers.utils.parseUnits('6');
const lockEnd = new Date(initialLockDate.getTime() + (4 * oneYearInMilliseconds));
console.log('lockEnd:', lockEnd);
const lockEndInSeconds = Math.round(lockEnd.getTime() / 1_000);
await votingEscrow.create_lock(lockAmount, ethers.BigNumber.from(lockEndInSeconds));

const expectedExpirationDate = new Date(
initialLockDate.getTime() + (3 * oneYearInMilliseconds)
);
console.log("expectedExpirationDate:", expectedExpirationDate);
const expectedExpirationDateInSeconds = Math.round(
expectedExpirationDate.getTime() / 1_000
);
console.log(
"expectedExpirationDateInSeconds:",
expectedExpirationDateInSeconds
);

const expirationTimestamp = await passportUtils.getExpirationTimestamp(owner.address);
console.log("expirationTimestamp:", expirationTimestamp);
console.log("expirationTimestamp (Date):", new Date(expirationTimestamp * 1_000));
expect(expirationTimestamp).to.equal(ethers.BigNumber.from(expectedExpirationDateInSeconds));
});
});
});

0 comments on commit d914b59

Please sign in to comment.