Skip to content

Commit 7f0eccc

Browse files
committed
🖋️ Introduce Signature module
1 parent 2ed521a commit 7f0eccc

File tree

5 files changed

+123
-49
lines changed

5 files changed

+123
-49
lines changed

erc/IERC20Permit.sol

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@ interface IERC20Permit is IERC20 {
1010

1111
function nonces(address owner) external view returns (uint256);
1212

13-
function DOMAIN_SEPARATOR() external view returns (bytes32);
13+
function DOMAIN_SEPARATOR() external pure returns (bytes32);
1414
}

kimlikdao/IDIDSigners.sol

+59-20
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,11 @@
22

33
pragma solidity ^0.8.0;
44

5+
import {Signature} from "../types/Signature.sol";
56
import {uint128x2} from "../types/uint128x2.sol";
67

7-
struct Signature {
8-
bytes32 r;
9-
uint256 yParityAndS;
10-
}
11-
12-
uint256 constant SIGNER_INFO_DEPOSIT_OFFSET = 64;
13-
14-
uint256 constant SIGNER_INFO_END_TS_OFFSET = 112;
15-
168
uint256 constant SIGNER_INFO_END_TS_MASK = uint256(type(uint64).max) << 112;
179

18-
uint256 constant SIGNER_INFO_WITHDRAW_OFFSET = 176;
19-
2010
uint256 constant SIGNER_INFO_WITHDRAW_MASK = uint256(type(uint48).max) << 176;
2111

2212
/**
@@ -27,27 +17,72 @@ uint256 constant SIGNER_INFO_WITHDRAW_MASK = uint256(type(uint48).max) << 176;
2717
*/
2818
type SignerInfo is uint256;
2919

20+
function SignerInfoFrom(uint256 _color, uint256 _deposit, uint256 _startTs) pure returns (SignerInfo) {
21+
return SignerInfo.wrap((_color << 224) | (_deposit << 64) | _startTs);
22+
}
23+
3024
function deposit(SignerInfo self) pure returns (uint256) {
3125
return uint48(SignerInfo.unwrap(self) >> 64);
3226
}
3327

34-
using {deposit} for SignerInfo global;
28+
function startTs(SignerInfo self) pure returns (uint256) {
29+
return uint64(SignerInfo.unwrap(self));
30+
}
31+
32+
function endTs(SignerInfo self) pure returns (uint256) {
33+
return uint64(SignerInfo.unwrap(self) >> 112);
34+
}
3535

36-
interface IDIDSigners {
37-
function authenticateExposureReportID3Sigs(
38-
bytes32 exposureReportID,
39-
uint128x2 weightThresholdAndSignatureTs,
40-
Signature[3] calldata sigs
41-
) external view;
36+
function hasEndTs(SignerInfo self) pure returns (bool) {
37+
return (SignerInfo.unwrap(self) & SIGNER_INFO_END_TS_MASK) != 0;
38+
}
4239

43-
function authenticateHumanID3Sigs(
40+
function addEndTs(SignerInfo self, uint256 _endTs) pure returns (SignerInfo) {
41+
return SignerInfo.wrap(SignerInfo.unwrap(self) | (_endTs << 112));
42+
}
43+
44+
function withdraw(SignerInfo self) pure returns (uint256) {
45+
return uint48(SignerInfo.unwrap(self) >> 176);
46+
}
47+
48+
function addWithdraw(SignerInfo self, uint256 _withdraw) pure returns (SignerInfo) {
49+
return SignerInfo.wrap(SignerInfo.unwrap(self) | (_withdraw << 176));
50+
}
51+
52+
function clearWithdraw(SignerInfo self) pure returns (SignerInfo) {
53+
return SignerInfo.wrap(SignerInfo.unwrap(self) & ~SIGNER_INFO_WITHDRAW_MASK);
54+
}
55+
56+
function color(SignerInfo self) pure returns (uint256) {
57+
return SignerInfo.unwrap(self) >> 224;
58+
}
59+
60+
function isZero(SignerInfo self) pure returns (bool) {
61+
return SignerInfo.unwrap(self) == 0;
62+
}
63+
64+
using {
65+
color,
66+
withdraw,
67+
addWithdraw,
68+
clearWithdraw,
69+
endTs,
70+
addEndTs,
71+
deposit,
72+
startTs,
73+
hasEndTs,
74+
isZero
75+
} for SignerInfo global;
76+
77+
interface IDIDSigners {
78+
function authenticateHumanIDv1(
4479
bytes32 exposureReportID,
4580
uint128x2 weightThresholdAndSignatureTs,
4681
bytes32 commitmentR,
4782
Signature[3] calldata sigs
4883
) external view;
4984

50-
function authenticateHumanID5Sigs(
85+
function authenticateHumanIDv1(
5186
bytes32 humanID,
5287
uint128x2 weightThresholdAndSignatureTs,
5388
bytes32 commitmentR,
@@ -59,3 +94,7 @@ interface IDIDSigners {
5994
*/
6095
function signerInfo(address signer) external view returns (SignerInfo);
6196
}
97+
98+
interface IDIDSignersExposureReport {
99+
function reportExposure(bytes32 exposureReportID, uint256 signatureTs, Signature[3] calldata sigs) external;
100+
}

testing/MockERC20Permit.sol

+4-26
Original file line numberDiff line numberDiff line change
@@ -4,39 +4,15 @@ pragma solidity ^0.8.0;
44

55
import {IERC20Permit} from "../erc/IERC20Permit.sol";
66

7-
contract MockERC20Permit is IERC20Permit {
7+
abstract contract MockERC20Permit is IERC20Permit {
88
// keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
99
bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
10-
bytes32 public immutable override DOMAIN_SEPARATOR;
11-
uint8 public immutable override decimals;
1210

13-
string public override name;
14-
string public override symbol;
1511
uint256 public override totalSupply;
1612
mapping(address => uint256) public override balanceOf;
1713
mapping(address => mapping(address => uint256)) public override allowance;
1814
mapping(address => uint256) public override nonces;
1915

20-
constructor(string memory tokenSymbol, string memory tokenName, uint8 tokenDecimals) {
21-
name = tokenName;
22-
symbol = tokenSymbol;
23-
decimals = tokenDecimals;
24-
uint256 toMint = 100 * 10 ** decimals;
25-
balanceOf[msg.sender] = toMint;
26-
totalSupply = toMint;
27-
28-
emit Transfer(address(this), msg.sender, toMint);
29-
DOMAIN_SEPARATOR = keccak256(
30-
abi.encode(
31-
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
32-
keccak256(bytes(tokenSymbol)),
33-
keccak256(bytes("1")),
34-
block.chainid,
35-
address(this)
36-
)
37-
);
38-
}
39-
4016
function approve(address spender, uint256 amount) external returns (bool) {
4117
allowance[msg.sender][spender] = amount;
4218
emit Approval(msg.sender, spender, amount);
@@ -71,7 +47,7 @@ contract MockERC20Permit is IERC20Permit {
7147
bytes32 digest = keccak256(
7248
abi.encodePacked(
7349
"\x19\x01",
74-
DOMAIN_SEPARATOR,
50+
DOMAIN_SEPARATOR(),
7551
keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, amount, nonces[owner]++, deadline))
7652
)
7753
);
@@ -82,6 +58,8 @@ contract MockERC20Permit is IERC20Permit {
8258
emit Approval(owner, spender, amount);
8359
}
8460

61+
function DOMAIN_SEPARATOR() public pure virtual override returns (bytes32);
62+
8563
function mint(uint256 amount) external {
8664
balanceOf[msg.sender] += amount;
8765
}

types/Signature.sol

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// SPDX-License-Identifier: MIT
2+
3+
pragma solidity ^0.8.0;
4+
5+
type YParityAndS is uint256;
6+
7+
function yParity(YParityAndS self) pure returns (uint8) {
8+
unchecked {
9+
return uint8((YParityAndS.unwrap(self) >> 255) + 27);
10+
}
11+
}
12+
13+
function s(YParityAndS self) pure returns (bytes32) {
14+
unchecked {
15+
return bytes32(YParityAndS.unwrap(self) & ((1 << 255) - 1));
16+
}
17+
}
18+
19+
using {yParity, s} for YParityAndS global;
20+
21+
struct Signature {
22+
bytes32 r;
23+
YParityAndS yParityAndS;
24+
}

zksync/mockTokens.sol

+35-2
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,49 @@ pragma solidity ^0.8.0;
44

55
import {IERC20Permit} from "../erc/IERC20Permit.sol";
66
import {MockERC20Permit} from "../testing/MockERC20Permit.sol";
7+
import {USDT} from "./addresses.sol";
78
import {Vm} from "forge-std/Vm.sol";
89
import {console2} from "forge-std/console2.sol";
910

1011
address constant USDT_DEPLOYER = 0x493257fD37EDB34451f62EDf8D2a0C418852bA4C;
1112

13+
contract USDTImpl is MockERC20Permit {
14+
function DOMAIN_SEPARATOR() public pure override returns (bytes32) {
15+
return keccak256(
16+
abi.encode(
17+
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
18+
keccak256(bytes("KPASS")),
19+
keccak256(bytes("1")),
20+
0x144,
21+
address(USDT)
22+
)
23+
);
24+
}
25+
26+
function name() public pure returns (string memory) {
27+
return "Tether";
28+
}
29+
30+
function symbol() public pure returns (string memory) {
31+
return "USDT";
32+
}
33+
34+
function decimals() public pure override returns (uint8) {
35+
return 6;
36+
}
37+
38+
constructor() {
39+
uint256 toMint = 100 * 10e6;
40+
balanceOf[msg.sender] = toMint;
41+
totalSupply = toMint;
42+
emit Transfer(address(this), msg.sender, toMint);
43+
}
44+
}
45+
1246
function deployMockTokens() {
1347
Vm vm = Vm(address(uint160(uint256(keccak256("hevm cheat code")))));
1448

1549
vm.setNonce(USDT_DEPLOYER, 4);
1650
vm.prank(USDT_DEPLOYER);
17-
IERC20Permit usdc = new MockERC20Permit("USDC", "USD Coin", 6);
18-
console2.log("USDC:", address(usdc));
51+
new USDTImpl();
1952
}

0 commit comments

Comments
 (0)