Skip to content
This repository was archived by the owner on Dec 18, 2025. It is now read-only.
Open
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
24 changes: 24 additions & 0 deletions contract-hardhat/contracts/mocks/MockPermit2.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.30;

contract MockPermit2 {
// Minimal storage to simulate approvals
mapping(address => mapping(address => uint256)) public allowance;

function permitTransferFrom(
address from,
address to,
uint256 amount
) external {
// naive "transfer" simulation
require(allowance[from][msg.sender] >= amount, "Not permitted");
allowance[from][msg.sender] -= amount;
}

function approve(
address spender,
uint256 amount
) external {
allowance[msg.sender][spender] = amount;
}
}
1 change: 1 addition & 0 deletions contract-hardhat/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"@graphprotocol/graph-ts": "^0.38.1",
"@openzeppelin/contracts": "^5.3.0",
"@openzeppelin/merkle-tree": "^1.0.8",
"@uniswap/permit2-sdk": "^1.4.0",
"dotenv": "^17.0.1",
"web3": "1.10.0"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ import { deployERC20DividendAndVerifyed, deployGPMAndVerifyed, deployUSDTieredST
import { initializeContracts } from "../scripts/polymath-deploy";
import { StandardMerkleTree } from "@openzeppelin/merkle-tree";
import { time } from "@nomicfoundation/hardhat-network-helpers";
import {
PERMIT2_ADDRESS,
SignatureTransfer,
PermitTransferFrom,
} from "@uniswap/permit2-sdk";

const functionSignature = {
name: "configure",
Expand Down Expand Up @@ -219,6 +224,7 @@ describe("Trading restriction Manager", function() {
// MockOracle USD prices
let USDETH: bigint; // 500 USD/ETH
let USDPOLY: bigint; // 0.25 USD/POLY
let mockPermit2: any;

const DividendParameters = ["address"];
const checkpointKey = 4;
Expand Down Expand Up @@ -251,6 +257,42 @@ describe("Trading restriction Manager", function() {
return 0n;
}

async function generatePermit2Data(
tokenAddress: string,
amountInWei: string,
spenderAddress: string,
signer: any,
chainId: number
): Promise<{ permit: PermitTransferFrom; permitSignature: string }> {
const currentTime = Math.floor(Date.now() / 1000);
const deadline = currentTime + 3600;
const nonce = Math.floor(Math.random() * 1e15);

const permit: PermitTransferFrom = {
permitted: {
token: tokenAddress,
amount: amountInWei,
},
spender: spenderAddress,
nonce,
deadline,
};

const { domain, types, values } = SignatureTransfer.getPermitData(
permit,
PERMIT2_ADDRESS,
chainId
);

// ethers v6 signTypedData
const signature = await signer.signTypedData(domain, types, values);

return {
permit,
permitSignature: signature,
};
}

before(async () => {

await initializeContracts();
Expand Down Expand Up @@ -306,6 +348,8 @@ describe("Trading restriction Manager", function() {

GeneralTransferManager = await ethers.getContractFactory("GeneralTransferManager");
PolyTokenFaucetFactory = await ethers.getContractFactory("PolyTokenFaucet");
const MockPermit2 = await ethers.getContractFactory("MockPermit2");
mockPermit2 = await MockPermit2.deploy();


// Step 1: Deploy the general PM ecosystem
Expand Down Expand Up @@ -678,8 +722,34 @@ describe("Trading restriction Manager", function() {
const init_WalletPOLYBal = await I_PolyToken.balanceOf(account_issuer.address);
const init_WalletDAIBal = await I_DaiToken.balanceOf(account_issuer.address);

const requiredAmount = ethers.parseEther("10");

const { permit, permitSignature } = await generatePermit2Data(
stoAddress,
requiredAmount.toString(),
token_owner.address,
account_investor1.address,
31337
);

expect(permit.permitted.token).to.eq(stoAddress);
expect(permit.permitted.amount).to.eq(requiredAmount.toString());
expect(permit.spender).to.eq(token_owner.address);
expect(permitSignature).to.be.properHexString;

// Buy With DAI
const tx2 = await I_USDTieredSTO_Array[stoId].connect(account_investor1).buyWithUSD(account_investor1.address, investment_DAI, daiAddress, proof1, ltime, isAccredited1, InvestorClass.NonUS);
const tx2 = await I_USDTieredSTO_Array[stoId].connect(account_investor1).buyWithUSD(
null,
await mockPermit2.getAddress(),
account_investor1.address,
requiredAmount,
investment_DAI,
daiAddress,
proof1,
ltime,
isAccredited1,
InvestorClass.NonUS
);
const receipt2 = await tx2.wait();
const gasCost2 = receipt2.gasUsed * receipt2.gasPrice;
console.log(`Gas buyWithUSD: ${receipt2.gasUsed}`);
Expand Down
15 changes: 14 additions & 1 deletion contract-hardhat/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1451,6 +1451,14 @@
dependencies:
"@types/node" "*"

"@uniswap/permit2-sdk@^1.4.0":
version "1.4.0"
resolved "https://registry.yarnpkg.com/@uniswap/permit2-sdk/-/permit2-sdk-1.4.0.tgz#eafb48e89bd747b893a88d3cabd2422a81528b80"
integrity sha512-l/aGhfhB93M76vXs4eB8QNwhELE6bs66kh7F1cyobaPtINaVpMmlJv+j3KmHeHwAZIsh7QXyYzhDxs07u0Pe4Q==
dependencies:
ethers "^5.7.0"
tiny-invariant "^1.1.0"

"@whatwg-node/events@^0.0.3":
version "0.0.3"
resolved "https://registry.yarnpkg.com/@whatwg-node/events/-/events-0.0.3.tgz#13a65dd4f5893f55280f766e29ae48074927acad"
Expand Down Expand Up @@ -3190,7 +3198,7 @@ ethereumjs-util@^7.1.0, ethereumjs-util@^7.1.1, ethereumjs-util@^7.1.2, ethereum
ethereum-cryptography "^0.1.3"
rlp "^2.2.4"

ethers@^5.7.2:
ethers@^5.7.0, ethers@^5.7.2:
version "5.8.0"
resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.8.0.tgz#97858dc4d4c74afce83ea7562fe9493cedb4d377"
integrity sha512-DUq+7fHrCg1aPDFCHx6UIPb3nmt2XMpM7Y/g2gLhsl3lIBqeAfOJIl1qEvRf2uq3BiKxmh6Fh5pfp2ieyek7Kg==
Expand Down Expand Up @@ -6765,6 +6773,11 @@ timeout-abort-controller@^2.0.0:
native-abort-controller "^1.0.4"
retimer "^3.0.0"

tiny-invariant@^1.1.0:
version "1.3.3"
resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.3.tgz#46680b7a873a0d5d10005995eb90a70d74d60127"
integrity sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==

tinyglobby@^0.2.6:
version "0.2.14"
resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.14.tgz#5280b0cf3f972b050e74ae88406c0a6a58f4079d"
Expand Down