@openzeppelin/confidential-contracts 0.4.0 → 0.5.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/contracts/BatcherConfidential.json +5 -0
- package/build/contracts/CheckpointsConfidential.json +2 -2
- package/build/contracts/ERC7984.json +6 -28
- package/build/contracts/ERC7984BalanceCapHookModule.json +277 -0
- package/build/contracts/ERC7984ERC20Wrapper.json +6 -28
- package/build/contracts/ERC7984Freezable.json +6 -28
- package/build/contracts/ERC7984HolderCapHookModule.json +291 -0
- package/build/contracts/ERC7984HookModule.json +200 -0
- package/build/contracts/ERC7984Hooked.json +832 -0
- package/build/contracts/ERC7984IdentityCheck.json +691 -0
- package/build/contracts/ERC7984ObserverAccess.json +6 -28
- package/build/contracts/ERC7984Omnibus.json +6 -28
- package/build/contracts/ERC7984Restricted.json +6 -28
- package/build/contracts/ERC7984Rwa.json +61 -29
- package/build/contracts/ERC7984Utils.json +2 -2
- package/build/contracts/ERC7984Votes.json +6 -28
- package/build/contracts/FHESafeMath.json +2 -2
- package/build/contracts/IERC7984HookModule.json +151 -0
- package/build/contracts/IERC7984Rwa.json +87 -0
- package/build/contracts/IIdentityRegistry.json +30 -0
- package/finance/BatcherConfidential.sol +7 -3
- package/governance/utils/VotesConfidential.sol +2 -2
- package/interfaces/IERC7984HookModule.sol +39 -0
- package/interfaces/IERC7984Receiver.sol +3 -1
- package/interfaces/IERC7984Rwa.sol +28 -1
- package/package.json +1 -1
- package/token/ERC7984/ERC7984.sol +39 -28
- package/token/ERC7984/extensions/ERC7984ERC20Wrapper.sol +3 -3
- package/token/ERC7984/extensions/ERC7984Freezable.sol +3 -7
- package/token/ERC7984/extensions/ERC7984Hooked.sol +158 -0
- package/token/ERC7984/extensions/ERC7984IdentityCheck.sol +58 -0
- package/token/ERC7984/extensions/ERC7984Restricted.sol +3 -3
- package/token/ERC7984/extensions/ERC7984Rwa.sol +65 -28
- package/token/ERC7984/utils/ERC7984BalanceCapHookModule.sol +92 -0
- package/token/ERC7984/utils/ERC7984HolderCapHookModule.sol +145 -0
- package/token/ERC7984/utils/ERC7984HookModule.sol +170 -0
- package/utils/FHESafeMath.sol +26 -1
- package/utils/HandleAccessManager.sol +5 -3
- package/utils/structs/CheckpointsConfidential.sol +1 -2
|
@@ -72,6 +72,31 @@
|
|
|
72
72
|
"name": "OperatorSet",
|
|
73
73
|
"type": "event"
|
|
74
74
|
},
|
|
75
|
+
{
|
|
76
|
+
"anonymous": false,
|
|
77
|
+
"inputs": [
|
|
78
|
+
{
|
|
79
|
+
"indexed": true,
|
|
80
|
+
"internalType": "address",
|
|
81
|
+
"name": "lostAccount",
|
|
82
|
+
"type": "address"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"indexed": true,
|
|
86
|
+
"internalType": "address",
|
|
87
|
+
"name": "newAccount",
|
|
88
|
+
"type": "address"
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"indexed": false,
|
|
92
|
+
"internalType": "euint64",
|
|
93
|
+
"name": "amount",
|
|
94
|
+
"type": "bytes32"
|
|
95
|
+
}
|
|
96
|
+
],
|
|
97
|
+
"name": "TokensRecovered",
|
|
98
|
+
"type": "event"
|
|
99
|
+
},
|
|
75
100
|
{
|
|
76
101
|
"inputs": [
|
|
77
102
|
{
|
|
@@ -621,6 +646,44 @@
|
|
|
621
646
|
"stateMutability": "nonpayable",
|
|
622
647
|
"type": "function"
|
|
623
648
|
},
|
|
649
|
+
{
|
|
650
|
+
"inputs": [
|
|
651
|
+
{
|
|
652
|
+
"internalType": "address",
|
|
653
|
+
"name": "account",
|
|
654
|
+
"type": "address"
|
|
655
|
+
}
|
|
656
|
+
],
|
|
657
|
+
"name": "isAdmin",
|
|
658
|
+
"outputs": [
|
|
659
|
+
{
|
|
660
|
+
"internalType": "bool",
|
|
661
|
+
"name": "",
|
|
662
|
+
"type": "bool"
|
|
663
|
+
}
|
|
664
|
+
],
|
|
665
|
+
"stateMutability": "view",
|
|
666
|
+
"type": "function"
|
|
667
|
+
},
|
|
668
|
+
{
|
|
669
|
+
"inputs": [
|
|
670
|
+
{
|
|
671
|
+
"internalType": "address",
|
|
672
|
+
"name": "account",
|
|
673
|
+
"type": "address"
|
|
674
|
+
}
|
|
675
|
+
],
|
|
676
|
+
"name": "isAgent",
|
|
677
|
+
"outputs": [
|
|
678
|
+
{
|
|
679
|
+
"internalType": "bool",
|
|
680
|
+
"name": "",
|
|
681
|
+
"type": "bool"
|
|
682
|
+
}
|
|
683
|
+
],
|
|
684
|
+
"stateMutability": "view",
|
|
685
|
+
"type": "function"
|
|
686
|
+
},
|
|
624
687
|
{
|
|
625
688
|
"inputs": [
|
|
626
689
|
{
|
|
@@ -678,6 +741,30 @@
|
|
|
678
741
|
"stateMutability": "view",
|
|
679
742
|
"type": "function"
|
|
680
743
|
},
|
|
744
|
+
{
|
|
745
|
+
"inputs": [
|
|
746
|
+
{
|
|
747
|
+
"internalType": "address",
|
|
748
|
+
"name": "lostAccount",
|
|
749
|
+
"type": "address"
|
|
750
|
+
},
|
|
751
|
+
{
|
|
752
|
+
"internalType": "address",
|
|
753
|
+
"name": "newAccount",
|
|
754
|
+
"type": "address"
|
|
755
|
+
}
|
|
756
|
+
],
|
|
757
|
+
"name": "recoverAddress",
|
|
758
|
+
"outputs": [
|
|
759
|
+
{
|
|
760
|
+
"internalType": "euint64",
|
|
761
|
+
"name": "",
|
|
762
|
+
"type": "bytes32"
|
|
763
|
+
}
|
|
764
|
+
],
|
|
765
|
+
"stateMutability": "nonpayable",
|
|
766
|
+
"type": "function"
|
|
767
|
+
},
|
|
681
768
|
{
|
|
682
769
|
"inputs": [
|
|
683
770
|
{
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_format": "hh-sol-artifact-1",
|
|
3
|
+
"contractName": "IIdentityRegistry",
|
|
4
|
+
"sourceName": "contracts/token/ERC7984/extensions/ERC7984IdentityCheck.sol",
|
|
5
|
+
"abi": [
|
|
6
|
+
{
|
|
7
|
+
"inputs": [
|
|
8
|
+
{
|
|
9
|
+
"internalType": "address",
|
|
10
|
+
"name": "account",
|
|
11
|
+
"type": "address"
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
"name": "isVerified",
|
|
15
|
+
"outputs": [
|
|
16
|
+
{
|
|
17
|
+
"internalType": "bool",
|
|
18
|
+
"name": "",
|
|
19
|
+
"type": "bool"
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"stateMutability": "view",
|
|
23
|
+
"type": "function"
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
"bytecode": "0x",
|
|
27
|
+
"deployedBytecode": "0x",
|
|
28
|
+
"linkReferences": {},
|
|
29
|
+
"deployedLinkReferences": {}
|
|
30
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Confidential Contracts (last updated v0.
|
|
2
|
+
// OpenZeppelin Confidential Contracts (last updated v0.5.0-rc.0) (finance/BatcherConfidential.sol)
|
|
3
3
|
|
|
4
4
|
pragma solidity ^0.8.27;
|
|
5
5
|
|
|
@@ -16,8 +16,8 @@ import {FHESafeMath} from "./../utils/FHESafeMath.sol";
|
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* @dev `BatcherConfidential` is a batching primitive that enables routing between two {ERC7984ERC20Wrapper} contracts
|
|
19
|
-
* via a non-confidential route. Users deposit {fromToken} into the batcher and receive
|
|
20
|
-
* made by using `ERC7984` transfer and call functions such as {ERC7984-confidentialTransferAndCall}.
|
|
19
|
+
* (with distinct underlying tokens) via a non-confidential route. Users deposit {fromToken} into the batcher and receive
|
|
20
|
+
* {toToken} in exchange. Deposits are made by using `ERC7984` transfer and call functions such as {ERC7984-confidentialTransferAndCall}.
|
|
21
21
|
*
|
|
22
22
|
* Developers must implement the virtual function {_executeRoute} to perform the batch's route. This function is called
|
|
23
23
|
* once the batch deposits are unwrapped into the underlying tokens. The function should swap the underlying {fromToken} for
|
|
@@ -110,6 +110,9 @@ abstract contract BatcherConfidential is ReentrancyGuardTransient, IERC7984Recei
|
|
|
110
110
|
/// @dev The given `token` does not support `IERC7984ERC20Wrapper` via `ERC165`.
|
|
111
111
|
error InvalidWrapperToken(address token);
|
|
112
112
|
|
|
113
|
+
/// @dev The underlying wrapper tokens are the same.
|
|
114
|
+
error DuplicateUnderlyingTokens();
|
|
115
|
+
|
|
113
116
|
constructor(IERC7984ERC20Wrapper fromToken_, IERC7984ERC20Wrapper toToken_) {
|
|
114
117
|
require(
|
|
115
118
|
ERC165Checker.supportsInterface(address(fromToken_), type(IERC7984ERC20Wrapper).interfaceId),
|
|
@@ -119,6 +122,7 @@ abstract contract BatcherConfidential is ReentrancyGuardTransient, IERC7984Recei
|
|
|
119
122
|
ERC165Checker.supportsInterface(address(toToken_), type(IERC7984ERC20Wrapper).interfaceId),
|
|
120
123
|
InvalidWrapperToken(address(toToken_))
|
|
121
124
|
);
|
|
125
|
+
require(fromToken_.underlying() != toToken_.underlying(), DuplicateUnderlyingTokens());
|
|
122
126
|
|
|
123
127
|
_fromToken = fromToken_;
|
|
124
128
|
_toToken = toToken_;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Confidential Contracts (last updated v0.
|
|
2
|
+
// OpenZeppelin Confidential Contracts (last updated v0.5.0-rc.0) (governance/utils/VotesConfidential.sol)
|
|
3
3
|
|
|
4
4
|
pragma solidity ^0.8.26;
|
|
5
5
|
|
|
6
|
-
import {FHE,
|
|
6
|
+
import {FHE, euint64} from "@fhevm/solidity/lib/FHE.sol";
|
|
7
7
|
import {IERC6372} from "@openzeppelin/contracts/interfaces/IERC6372.sol";
|
|
8
8
|
import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
|
|
9
9
|
import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// OpenZeppelin Confidential Contracts (last updated v0.5.0-rc.0) (interfaces/IERC7984HookModule.sol)
|
|
3
|
+
|
|
4
|
+
pragma solidity ^0.8.24;
|
|
5
|
+
|
|
6
|
+
import {euint64, ebool} from "@fhevm/solidity/lib/FHE.sol";
|
|
7
|
+
import {IERC165} from "@openzeppelin/contracts/interfaces/IERC165.sol";
|
|
8
|
+
|
|
9
|
+
/// @dev Interface for an ERC-7984 hook module.
|
|
10
|
+
interface IERC7984HookModule is IERC165 {
|
|
11
|
+
/// @dev Optionally emitted by a module to indicate the result of its validation (pre-transfer) hook.
|
|
12
|
+
event ERC7984HookModuleResult(
|
|
13
|
+
address indexed token,
|
|
14
|
+
address indexed from,
|
|
15
|
+
address indexed to,
|
|
16
|
+
euint64 encryptedAmount,
|
|
17
|
+
ebool result,
|
|
18
|
+
bytes32 context
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @dev Hook that runs before a transfer. Should not mutate token state. Module is already
|
|
23
|
+
* granted transient access to `encryptedAmount`.
|
|
24
|
+
*/
|
|
25
|
+
function preTransfer(address from, address to, euint64 encryptedAmount) external returns (ebool);
|
|
26
|
+
|
|
27
|
+
/// @dev Performs operation after transfer.
|
|
28
|
+
function postTransfer(address from, address to, euint64 encryptedAmount) external;
|
|
29
|
+
|
|
30
|
+
/// @dev Performs operations after installation.
|
|
31
|
+
function onInstall(bytes calldata initData) external;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @dev Performs operations after uninstallation.
|
|
35
|
+
*
|
|
36
|
+
* NOTE: The module uninstallation will succeed even if this function reverts.
|
|
37
|
+
*/
|
|
38
|
+
function onUninstall(bytes calldata deinitData) external;
|
|
39
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Confidential Contracts (last updated v0.
|
|
2
|
+
// OpenZeppelin Confidential Contracts (last updated v0.5.0-rc.0) (interfaces/IERC7984Receiver.sol)
|
|
3
3
|
pragma solidity ^0.8.24;
|
|
4
4
|
|
|
5
5
|
import {ebool, euint64} from "@fhevm/solidity/lib/FHE.sol";
|
|
@@ -10,6 +10,8 @@ interface IERC7984Receiver {
|
|
|
10
10
|
* @dev Called upon receiving a confidential token transfer. Returns an encrypted boolean indicating success
|
|
11
11
|
* of the callback. If false is returned, the token contract will attempt to refund the transfer.
|
|
12
12
|
*
|
|
13
|
+
* NOTE: The calling contract (token) must be granted ACL allowance to read the confidential return value.
|
|
14
|
+
*
|
|
13
15
|
* WARNING: Do not manually refund the transfer AND return false, as this can lead to double refunds.
|
|
14
16
|
*/
|
|
15
17
|
function onConfidentialTransferReceived(
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Confidential Contracts (last updated v0.
|
|
2
|
+
// OpenZeppelin Confidential Contracts (last updated v0.5.0-rc.0) (interfaces/IERC7984Rwa.sol)
|
|
3
3
|
pragma solidity ^0.8.24;
|
|
4
4
|
|
|
5
5
|
import {externalEuint64, euint64} from "@fhevm/solidity/lib/FHE.sol";
|
|
@@ -7,46 +7,69 @@ import {IERC7984} from "./IERC7984.sol";
|
|
|
7
7
|
|
|
8
8
|
/// @dev Interface for confidential RWA contracts.
|
|
9
9
|
interface IERC7984Rwa is IERC7984 {
|
|
10
|
+
/// @dev Emitted when the balance `amount` of `lostAccount` is recovered to `newAccount`.
|
|
11
|
+
event TokensRecovered(address indexed lostAccount, address indexed newAccount, euint64 amount);
|
|
12
|
+
|
|
10
13
|
/// @dev Returns true if the contract is paused, false otherwise.
|
|
11
14
|
function paused() external view returns (bool);
|
|
15
|
+
|
|
16
|
+
/// @dev Returns true if has admin role, false otherwise.
|
|
17
|
+
function isAdmin(address account) external view returns (bool);
|
|
18
|
+
|
|
19
|
+
/// @dev Returns true if agent, false otherwise.
|
|
20
|
+
function isAgent(address account) external view returns (bool);
|
|
21
|
+
|
|
12
22
|
/// @dev Returns whether an account is allowed to interact with the token.
|
|
13
23
|
function canTransact(address account) external view returns (bool);
|
|
24
|
+
|
|
14
25
|
/// @dev Returns the confidential frozen balance of an account.
|
|
15
26
|
function confidentialFrozen(address account) external view returns (euint64);
|
|
27
|
+
|
|
16
28
|
/// @dev Returns the confidential available (unfrozen) balance of an account. Up to {IERC7984-confidentialBalanceOf}.
|
|
17
29
|
function confidentialAvailable(address account) external returns (euint64);
|
|
30
|
+
|
|
18
31
|
/// @dev Pauses contract.
|
|
19
32
|
function pause() external;
|
|
33
|
+
|
|
20
34
|
/// @dev Unpauses contract.
|
|
21
35
|
function unpause() external;
|
|
36
|
+
|
|
22
37
|
/// @dev Blocks a user account.
|
|
23
38
|
function blockUser(address account) external;
|
|
39
|
+
|
|
24
40
|
/// @dev Unblocks a user account.
|
|
25
41
|
function unblockUser(address account) external;
|
|
42
|
+
|
|
26
43
|
/// @dev Sets confidential amount of token for an account as frozen with proof.
|
|
27
44
|
function setConfidentialFrozen(
|
|
28
45
|
address account,
|
|
29
46
|
externalEuint64 encryptedAmount,
|
|
30
47
|
bytes calldata inputProof
|
|
31
48
|
) external;
|
|
49
|
+
|
|
32
50
|
/// @dev Sets confidential amount of token for an account as frozen.
|
|
33
51
|
function setConfidentialFrozen(address account, euint64 encryptedAmount) external;
|
|
52
|
+
|
|
34
53
|
/// @dev Mints confidential amount of tokens to account with proof.
|
|
35
54
|
function confidentialMint(
|
|
36
55
|
address to,
|
|
37
56
|
externalEuint64 encryptedAmount,
|
|
38
57
|
bytes calldata inputProof
|
|
39
58
|
) external returns (euint64);
|
|
59
|
+
|
|
40
60
|
/// @dev Mints confidential amount of tokens to account.
|
|
41
61
|
function confidentialMint(address to, euint64 encryptedAmount) external returns (euint64);
|
|
62
|
+
|
|
42
63
|
/// @dev Burns confidential amount of tokens from account with proof.
|
|
43
64
|
function confidentialBurn(
|
|
44
65
|
address account,
|
|
45
66
|
externalEuint64 encryptedAmount,
|
|
46
67
|
bytes calldata inputProof
|
|
47
68
|
) external returns (euint64);
|
|
69
|
+
|
|
48
70
|
/// @dev Burns confidential amount of tokens from account.
|
|
49
71
|
function confidentialBurn(address account, euint64 encryptedAmount) external returns (euint64);
|
|
72
|
+
|
|
50
73
|
/// @dev Forces transfer of confidential amount of tokens from account to account with proof by skipping compliance checks.
|
|
51
74
|
function forceConfidentialTransferFrom(
|
|
52
75
|
address from,
|
|
@@ -54,10 +77,14 @@ interface IERC7984Rwa is IERC7984 {
|
|
|
54
77
|
externalEuint64 encryptedAmount,
|
|
55
78
|
bytes calldata inputProof
|
|
56
79
|
) external returns (euint64);
|
|
80
|
+
|
|
57
81
|
/// @dev Forces transfer of confidential amount of tokens from account to account by skipping compliance checks.
|
|
58
82
|
function forceConfidentialTransferFrom(
|
|
59
83
|
address from,
|
|
60
84
|
address to,
|
|
61
85
|
euint64 encryptedAmount
|
|
62
86
|
) external returns (euint64);
|
|
87
|
+
|
|
88
|
+
/// @dev Recovers the address of a lost account to a new account.
|
|
89
|
+
function recoverAddress(address lostAccount, address newAccount) external returns (euint64);
|
|
63
90
|
}
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Confidential Contracts (last updated v0.
|
|
2
|
+
// OpenZeppelin Confidential Contracts (last updated v0.5.0-rc.0) (token/ERC7984/ERC7984.sol)
|
|
3
3
|
pragma solidity ^0.8.27;
|
|
4
4
|
|
|
5
5
|
import {FHE, externalEuint64, ebool, euint64} from "@fhevm/solidity/lib/FHE.sol";
|
|
@@ -44,9 +44,6 @@ abstract contract ERC7984 is IERC7984, ERC165 {
|
|
|
44
44
|
/// @dev The given holder `holder` is not authorized to spend on behalf of `spender`.
|
|
45
45
|
error ERC7984UnauthorizedSpender(address holder, address spender);
|
|
46
46
|
|
|
47
|
-
/// @dev The holder `holder` is trying to send tokens but has a balance of 0.
|
|
48
|
-
error ERC7984ZeroBalance(address holder);
|
|
49
|
-
|
|
50
47
|
/**
|
|
51
48
|
* @dev The caller `user` does not have access to the encrypted amount `amount`.
|
|
52
49
|
*
|
|
@@ -57,9 +54,6 @@ abstract contract ERC7984 is IERC7984, ERC165 {
|
|
|
57
54
|
/// @dev The given caller `caller` is not authorized for the current operation.
|
|
58
55
|
error ERC7984UnauthorizedCaller(address caller);
|
|
59
56
|
|
|
60
|
-
/// @dev The given gateway request ID `requestId` is invalid.
|
|
61
|
-
error ERC7984InvalidGatewayRequest(uint256 requestId);
|
|
62
|
-
|
|
63
57
|
constructor(string memory name_, string memory symbol_, string memory contractURI_) {
|
|
64
58
|
_name = name_;
|
|
65
59
|
_symbol = symbol_;
|
|
@@ -132,22 +126,20 @@ abstract contract ERC7984 is IERC7984, ERC165 {
|
|
|
132
126
|
address to,
|
|
133
127
|
externalEuint64 encryptedAmount,
|
|
134
128
|
bytes calldata inputProof
|
|
135
|
-
) public virtual returns (euint64
|
|
129
|
+
) public virtual returns (euint64) {
|
|
136
130
|
require(isOperator(from, msg.sender), ERC7984UnauthorizedSpender(from, msg.sender));
|
|
137
|
-
transferred = _transfer(from, to, FHE.fromExternal(encryptedAmount, inputProof));
|
|
131
|
+
euint64 transferred = _transfer(from, to, FHE.fromExternal(encryptedAmount, inputProof));
|
|
138
132
|
FHE.allowTransient(transferred, msg.sender);
|
|
133
|
+
return transferred;
|
|
139
134
|
}
|
|
140
135
|
|
|
141
136
|
/// @inheritdoc IERC7984
|
|
142
|
-
function confidentialTransferFrom(
|
|
143
|
-
address from,
|
|
144
|
-
address to,
|
|
145
|
-
euint64 amount
|
|
146
|
-
) public virtual returns (euint64 transferred) {
|
|
137
|
+
function confidentialTransferFrom(address from, address to, euint64 amount) public virtual returns (euint64) {
|
|
147
138
|
require(FHE.isAllowed(amount, msg.sender), ERC7984UnauthorizedUseOfEncryptedAmount(amount, msg.sender));
|
|
148
139
|
require(isOperator(from, msg.sender), ERC7984UnauthorizedSpender(from, msg.sender));
|
|
149
|
-
transferred = _transfer(from, to, amount);
|
|
140
|
+
euint64 transferred = _transfer(from, to, amount);
|
|
150
141
|
FHE.allowTransient(transferred, msg.sender);
|
|
142
|
+
return transferred;
|
|
151
143
|
}
|
|
152
144
|
|
|
153
145
|
/// @inheritdoc IERC7984
|
|
@@ -156,9 +148,8 @@ abstract contract ERC7984 is IERC7984, ERC165 {
|
|
|
156
148
|
externalEuint64 encryptedAmount,
|
|
157
149
|
bytes calldata inputProof,
|
|
158
150
|
bytes calldata data
|
|
159
|
-
) public virtual returns (euint64
|
|
160
|
-
|
|
161
|
-
FHE.allowTransient(transferred, msg.sender);
|
|
151
|
+
) public virtual returns (euint64) {
|
|
152
|
+
return _transferAndCall(msg.sender, to, FHE.fromExternal(encryptedAmount, inputProof), data);
|
|
162
153
|
}
|
|
163
154
|
|
|
164
155
|
/// @inheritdoc IERC7984
|
|
@@ -166,10 +157,9 @@ abstract contract ERC7984 is IERC7984, ERC165 {
|
|
|
166
157
|
address to,
|
|
167
158
|
euint64 amount,
|
|
168
159
|
bytes calldata data
|
|
169
|
-
) public virtual returns (euint64
|
|
160
|
+
) public virtual returns (euint64) {
|
|
170
161
|
require(FHE.isAllowed(amount, msg.sender), ERC7984UnauthorizedUseOfEncryptedAmount(amount, msg.sender));
|
|
171
|
-
|
|
172
|
-
FHE.allowTransient(transferred, msg.sender);
|
|
162
|
+
return _transferAndCall(msg.sender, to, amount, data);
|
|
173
163
|
}
|
|
174
164
|
|
|
175
165
|
/// @inheritdoc IERC7984
|
|
@@ -179,10 +169,9 @@ abstract contract ERC7984 is IERC7984, ERC165 {
|
|
|
179
169
|
externalEuint64 encryptedAmount,
|
|
180
170
|
bytes calldata inputProof,
|
|
181
171
|
bytes calldata data
|
|
182
|
-
) public virtual returns (euint64
|
|
172
|
+
) public virtual returns (euint64) {
|
|
183
173
|
require(isOperator(from, msg.sender), ERC7984UnauthorizedSpender(from, msg.sender));
|
|
184
|
-
|
|
185
|
-
FHE.allowTransient(transferred, msg.sender);
|
|
174
|
+
return _transferAndCall(from, to, FHE.fromExternal(encryptedAmount, inputProof), data);
|
|
186
175
|
}
|
|
187
176
|
|
|
188
177
|
/// @inheritdoc IERC7984
|
|
@@ -191,11 +180,10 @@ abstract contract ERC7984 is IERC7984, ERC165 {
|
|
|
191
180
|
address to,
|
|
192
181
|
euint64 amount,
|
|
193
182
|
bytes calldata data
|
|
194
|
-
) public virtual returns (euint64
|
|
183
|
+
) public virtual returns (euint64) {
|
|
195
184
|
require(FHE.isAllowed(amount, msg.sender), ERC7984UnauthorizedUseOfEncryptedAmount(amount, msg.sender));
|
|
196
185
|
require(isOperator(from, msg.sender), ERC7984UnauthorizedSpender(from, msg.sender));
|
|
197
|
-
|
|
198
|
-
FHE.allowTransient(transferred, msg.sender);
|
|
186
|
+
return _transferAndCall(from, to, amount, data);
|
|
199
187
|
}
|
|
200
188
|
|
|
201
189
|
/**
|
|
@@ -255,6 +243,25 @@ abstract contract ERC7984 is IERC7984, ERC165 {
|
|
|
255
243
|
return _update(from, to, amount);
|
|
256
244
|
}
|
|
257
245
|
|
|
246
|
+
/**
|
|
247
|
+
* @dev Transfers the given amount of tokens from `from` to `to` and calls the `onConfidentialTransferReceived`
|
|
248
|
+
* function on the recipient.
|
|
249
|
+
*
|
|
250
|
+
* The token contract initiates a second transfer refunding the tokens from the recipient to the sender--the
|
|
251
|
+
* amount is 0 if the callback succeeds, otherwise the amount is the amount that was transferred.
|
|
252
|
+
*
|
|
253
|
+
* The returned `transferred` amount is a fresh ciphertext computed as `sent - refund`
|
|
254
|
+
* and `msg.sender` only receives a transient FHE allowance for it. This value is generally
|
|
255
|
+
* intended to be processed only in the same transaction. Event observers see `sent` and `refund` individually.
|
|
256
|
+
*
|
|
257
|
+
* WARNING: The refund triggered when {IERC7984Receiver-onConfidentialTransferReceived} returns an encrypted
|
|
258
|
+
* false is best-effort only. A receiver that transfers, burns, or otherwise reduces its balance during
|
|
259
|
+
* the hook can still return false, in which case the refund transfers zero tokens. The sender's tokens
|
|
260
|
+
* end up with the recipient rather than being refunded.
|
|
261
|
+
*
|
|
262
|
+
* WARNING: Refunds are subject to the same validation flow as a normal transfer--they may fail for a variety of
|
|
263
|
+
* reasons (such as failed hook validation in {ERC7984Hooked}). In these cases, the tokens do not return to the sender.
|
|
264
|
+
*/
|
|
258
265
|
function _transferAndCall(
|
|
259
266
|
address from,
|
|
260
267
|
address to,
|
|
@@ -270,8 +277,13 @@ abstract contract ERC7984 is IERC7984, ERC165 {
|
|
|
270
277
|
// Try to refund if callback fails
|
|
271
278
|
euint64 refund = _update(to, from, FHE.select(success, FHE.asEuint64(0), sent));
|
|
272
279
|
transferred = FHE.sub(sent, refund);
|
|
280
|
+
FHE.allowTransient(transferred, msg.sender);
|
|
273
281
|
}
|
|
274
282
|
|
|
283
|
+
/**
|
|
284
|
+
* @dev Safely moves up to `amount` from `from` to `to`, or mints/burns if `from`/`to` is the zero address.
|
|
285
|
+
* Emits a {ConfidentialTransfer} event with the successfully transferred amount.
|
|
286
|
+
*/
|
|
275
287
|
function _update(address from, address to, euint64 amount) internal virtual returns (euint64 transferred) {
|
|
276
288
|
ebool success;
|
|
277
289
|
euint64 ptr;
|
|
@@ -282,7 +294,6 @@ abstract contract ERC7984 is IERC7984, ERC165 {
|
|
|
282
294
|
_totalSupply = ptr;
|
|
283
295
|
} else {
|
|
284
296
|
euint64 fromBalance = _balances[from];
|
|
285
|
-
require(FHE.isInitialized(fromBalance), ERC7984ZeroBalance(from));
|
|
286
297
|
(success, ptr) = FHESafeMath.tryDecrease(fromBalance, amount);
|
|
287
298
|
FHE.allowThis(ptr);
|
|
288
299
|
FHE.allow(ptr, from);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Confidential Contracts (last updated v0.
|
|
2
|
+
// OpenZeppelin Confidential Contracts (last updated v0.5.0-rc.0) (token/ERC7984/extensions/ERC7984ERC20Wrapper.sol)
|
|
3
3
|
|
|
4
4
|
pragma solidity ^0.8.27;
|
|
5
5
|
|
|
@@ -180,8 +180,8 @@ abstract contract ERC7984ERC20Wrapper is ERC7984, IERC7984ERC20Wrapper, IERC1363
|
|
|
180
180
|
}
|
|
181
181
|
|
|
182
182
|
/**
|
|
183
|
-
* @dev
|
|
184
|
-
* unwrap request
|
|
183
|
+
* @dev Gets the address that will receive the ERC-20 tokens associated with a pending unwrap request identified by
|
|
184
|
+
* `unwrapRequestId`. Returns `address(0)` if there is no pending unwrap request with id `unwrapRequestId`.
|
|
185
185
|
*/
|
|
186
186
|
function unwrapRequester(bytes32 unwrapRequestId) public view virtual returns (address) {
|
|
187
187
|
return _unwrapRequests[unwrapRequestId];
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Confidential Contracts (last updated v0.
|
|
2
|
+
// OpenZeppelin Confidential Contracts (last updated v0.5.0-rc.0) (token/ERC7984/extensions/ERC7984Freezable.sol)
|
|
3
3
|
|
|
4
4
|
pragma solidity ^0.8.27;
|
|
5
5
|
|
|
6
|
-
import {FHE, ebool, euint64
|
|
6
|
+
import {FHE, ebool, euint64} from "@fhevm/solidity/lib/FHE.sol";
|
|
7
7
|
import {FHESafeMath} from "../../../utils/FHESafeMath.sol";
|
|
8
8
|
import {ERC7984} from "../ERC7984.sol";
|
|
9
9
|
|
|
@@ -40,11 +40,7 @@ abstract contract ERC7984Freezable is ERC7984 {
|
|
|
40
40
|
|
|
41
41
|
/// @dev Internal function to calculate the available balance of an account. Does not give any allowances.
|
|
42
42
|
function _confidentialAvailable(address account) internal virtual returns (euint64) {
|
|
43
|
-
(
|
|
44
|
-
confidentialBalanceOf(account),
|
|
45
|
-
confidentialFrozen(account)
|
|
46
|
-
);
|
|
47
|
-
return FHE.select(success, unfrozen, FHE.asEuint64(0));
|
|
43
|
+
return FHESafeMath.saturatingSub(confidentialBalanceOf(account), confidentialFrozen(account));
|
|
48
44
|
}
|
|
49
45
|
|
|
50
46
|
/// @dev Internal function to freeze a confidential amount of tokens for an account.
|