-
Notifications
You must be signed in to change notification settings - Fork 1
/
erc20.sol
83 lines (61 loc) · 2.56 KB
/
erc20.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// SPDX-License-Identifier: BSD-3-Clause-Clear
pragma solidity ^0.8.20;
import "fhevm/lib/TFHE.sol";
import "./eip712-reencrypt.sol";
contract EncryptedERC20 is EIP712Reencrypt {
address public contractOwner;
uint64 public totalSupply;
constructor() {
contractOwner = msg.sender;
}
mapping(address => euint64) internal balances;
function balanceOf(
address wallet,
bytes32 publicKey,
bytes calldata signature
)
public
view
signedBySender(publicKey, signature)
returns (bytes memory)
{
require(wallet == msg.sender);
return TFHE.reencrypt(balances[msg.sender], publicKey, 0);
}
function mint(uint64 amount) public {
require(msg.sender == contractOwner);
balances[contractOwner] = TFHE.add(balances[contractOwner], amount);
totalSupply = totalSupply + amount;
}
function transfer(address to, bytes calldata amountCiphertext) public returns (bool) {
return transfer_reverting(to, amountCiphertext);
// return transfer_leaking(to, amountCiphertext);
// return transfer_nonleaking(to, amountCiphertext);
}
function transfer_reverting(address to, bytes calldata amountCiphertext) internal returns (bool) {
euint64 amount = TFHE.asEuint64(amountCiphertext);
ebool sufficient = TFHE.le(amount, balances[msg.sender]);
bool decrypted_sufficient = TFHE.decrypt(sufficient);
require(decrypted_sufficient);
balances[to] = balances[to] + amount;
balances[msg.sender] = balances[msg.sender] - amount;
return true;
}
function transfer_leaking(address to, bytes calldata amountCiphertext) internal returns (bool) {
euint64 amount = TFHE.asEuint64(amountCiphertext);
ebool sufficient = TFHE.le(amount, balances[msg.sender]);
bool decrypted_sufficient = TFHE.decrypt(sufficient);
if (decrypted_sufficient) {
balances[to] = balances[to] + amount;
balances[msg.sender] = balances[msg.sender] - amount;
}
return decrypted_sufficient;
}
function transfer_nonleaking(address to, bytes calldata amountCiphertext) internal returns (bool) {
euint64 amount = TFHE.asEuint64(amountCiphertext);
ebool sufficient = TFHE.le(amount, balances[msg.sender]);
balances[to] = balances[to] + TFHE.select(sufficient, amount, TFHE.asEuint64(0));
balances[msg.sender] = balances[msg.sender] - TFHE.select(sufficient, amount, TFHE.asEuint64(0));
return true;
}
}