Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
b4ce8d9
Add `ERC7984Freezable` extension.
james-toussaint Jul 25, 2025
f04162b
Update pragma
james-toussaint Jul 25, 2025
ec16cdf
Merge remote-tracking branch 'origin/master' into feature/confidentia…
james-toussaint Aug 6, 2025
ff2a74f
Add freezable test
james-toussaint Aug 6, 2025
f485ec0
Remove unused functions in freezable mock
james-toussaint Aug 6, 2025
a961e33
Bring back previous HandleAccessManager
james-toussaint Aug 19, 2025
3c759fb
Move allow available to access function in mock
james-toussaint Aug 19, 2025
cd81483
Swap event & error order
james-toussaint Aug 19, 2025
3bb3f2e
Update inline documentation
james-toussaint Aug 19, 2025
ac9ae06
Remove useless var
james-toussaint Aug 19, 2025
4095083
Merge branch 'master' into feature/confidential-freezable-token
arr00 Aug 19, 2025
0286f57
Apply suggestions from review
james-toussaint Aug 20, 2025
c790dc5
Move freezable test file to extensions dir
james-toussaint Aug 20, 2025
b5f2812
ERC7984Freezable extension behave like ERC7984
james-toussaint Aug 20, 2025
45c9ba3
Allow past total supply access in ERC7984 test
james-toussaint Aug 20, 2025
754ecec
update tests
arr00 Aug 20, 2025
8e08500
Apply suggestions
james-toussaint Aug 21, 2025
7e45893
Remove account from `_validateHandleAllowance` (#178)
arr00 Aug 21, 2025
ed13e2f
Call internal when setting frozen with proof
james-toussaint Aug 22, 2025
9ae4074
Update doc
james-toussaint Aug 22, 2025
6a52710
Update pragma & remove import in freezable mock
james-toussaint Aug 22, 2025
bc71379
Base freezable mock on ERC7984Mock
james-toussaint Aug 22, 2025
04d6023
Merge remote-tracking branch 'origin/feature/confidential-freezable-t…
james-toussaint Aug 22, 2025
f51acb1
No wait
james-toussaint Aug 22, 2025
df84dc2
Merge remote-tracking branch 'origin/master' into feature/confidentia…
james-toussaint Aug 27, 2025
b111a13
Order imports
james-toussaint Aug 27, 2025
c8afdb1
Reduce diff
james-toussaint Aug 27, 2025
5ab8888
Lighten shouldBehaveLike calling
james-toussaint Aug 27, 2025
27c50c6
Keep only tests related to ERC in behaviour
james-toussaint Aug 28, 2025
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
2 changes: 1 addition & 1 deletion contracts/mocks/token/ERC7984FreezableMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ contract ERC7984FreezableMock is ERC7984Mock, ERC7984Freezable, AccessControl, H
address from,
address to,
euint64 amount
) internal virtual override(ERC7984Mock, ERC7984Freezable) returns (euint64) {
) internal virtual override(ERC7984, ERC7984Freezable) returns (euint64) {
return super._update(from, to, amount);
}

Expand Down
6 changes: 3 additions & 3 deletions contracts/mocks/token/ERC7984Mock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ contract ERC7984Mock is ERC7984, SepoliaConfig {
_OWNER = msg.sender;
}

function _update(address from, address to, euint64 amount) internal virtual override returns (euint64 transferred) {
transferred = super._update(from, to, amount);
FHE.allow(confidentialTotalSupply(), _OWNER);
function confidentialTotalSupplyAccess() public {
require(msg.sender == _OWNER);
FHE.allow(confidentialTotalSupply(), msg.sender);
}

function $_mint(
Expand Down
3 changes: 2 additions & 1 deletion contracts/mocks/token/ERC7984ObserverAccessMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pragma solidity ^0.8.27;

import {SepoliaConfig} from "@fhevm/solidity/config/ZamaConfig.sol";
import {FHE, euint64, externalEuint64} from "@fhevm/solidity/lib/FHE.sol";
import {ERC7984} from "../../token/ERC7984/ERC7984.sol";
import {ERC7984ObserverAccess} from "../../token/ERC7984/extensions/ERC7984ObserverAccess.sol";
import {ERC7984Mock} from "./ERC7984Mock.sol";

Expand All @@ -18,7 +19,7 @@ contract ERC7984ObserverAccessMock is ERC7984ObserverAccess, ERC7984Mock {
address from,
address to,
euint64 amount
) internal virtual override(ERC7984ObserverAccess, ERC7984Mock) returns (euint64) {
) internal virtual override(ERC7984ObserverAccess, ERC7984) returns (euint64) {
return super._update(from, to, amount);
}
}
7 changes: 6 additions & 1 deletion contracts/mocks/token/ERC7984VotesMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,16 @@ abstract contract ERC7984VotesMock is ERC7984Mock, ERC7984Votes {
return super.confidentialTotalSupply();
}

function getPastTotalSupplyAccess(uint256 timepoint) public {
require(msg.sender == _OWNER);
FHE.allow(getPastTotalSupply(timepoint), msg.sender);
}

function _update(
address from,
address to,
euint64 amount
) internal virtual override(ERC7984Mock, ERC7984Votes) returns (euint64) {
) internal virtual override(ERC7984, ERC7984Votes) returns (euint64) {
return super._update(from, to, amount);
}

Expand Down
10 changes: 3 additions & 7 deletions contracts/token/ERC7984/extensions/ERC7984Freezable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {FHESafeMath} from "../../../utils/FHESafeMath.sol";
import {ERC7984} from "../ERC7984.sol";

/**
* @dev Extension of {ERC7984} that implements a confidential
* @dev Extension of {ERC7984} that allows to implement a confidential
* freezing mechanism that can be managed by an authorized account with
* {setConfidentialFrozen} functions.
*
Expand All @@ -31,12 +31,8 @@ abstract contract ERC7984Freezable is ERC7984 {
}

/// @dev Returns the confidential available (unfrozen) balance of an account. Up to {confidentialBalanceOf}.
function confidentialAvailable(address account) public virtual returns (euint64) {
(ebool success, euint64 unfrozen) = FHESafeMath.tryDecrease(
confidentialBalanceOf(account),
confidentialFrozen(account)
);
return FHE.select(success, unfrozen, FHE.asEuint64(0));
function confidentialAvailable(address account) public virtual returns (euint64 unfrozen) {
(, unfrozen) = FHESafeMath.tryDecrease(confidentialBalanceOf(account), confidentialFrozen(account));
}

/// @dev Freezes a confidential amount of tokens for an account with a proof.
Expand Down
12 changes: 10 additions & 2 deletions contracts/utils/FHESafeMath.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,15 @@ library FHESafeMath {
* and `updated` will be the original value.
*/
function tryDecrease(euint64 oldValue, euint64 delta) internal returns (ebool success, euint64 updated) {
success = FHE.ge(oldValue, delta);
updated = FHE.select(success, FHE.sub(oldValue, delta), oldValue);
if (!FHE.isInitialized(oldValue)) {
success = FHE.asEbool(false);
updated = FHE.asEuint64(0);
} else if (!FHE.isInitialized(delta)) {
success = FHE.asEbool(true);
updated = oldValue;
} else {
success = FHE.ge(oldValue, delta);
updated = FHE.select(success, FHE.sub(oldValue, delta), oldValue);
}
}
}
Loading