From 8d8fd93b8b58487d459d265d2d6d8a3d3753a381 Mon Sep 17 00:00:00 2001 From: Nuno Date: Thu, 11 Sep 2025 10:56:13 +0100 Subject: [PATCH 01/29] feat: replacing require by errors --- packages/foundry/contracts/RaylsHook.sol | 45 +++++++++++++++++++----- packages/foundry/test/RaylsHook.t.sol | 18 +++++++--- 2 files changed, 50 insertions(+), 13 deletions(-) diff --git a/packages/foundry/contracts/RaylsHook.sol b/packages/foundry/contracts/RaylsHook.sol index f4ccfed..2aee751 100644 --- a/packages/foundry/contracts/RaylsHook.sol +++ b/packages/foundry/contracts/RaylsHook.sol @@ -35,6 +35,16 @@ contract RaylsHook is BaseHook { event CommitmentStored(uint256 id, address indexed sender); event Revealed(uint256 id, address indexed revealer); + // Errors + error CommitmentMismatch(bytes pubId, uint256 expectedId); + error NotMarkedAsExecuted(uint256 signal); + error CommitmentNotReady(uint256 notBefore, uint256 currentTime); + error InvalidWallet(address provided, address expected); + error InvalidSuitabilityProof(); + error AlreadyExecuted(uint256 id); + error InvalidPrivateSwapIntentProof(); + error AlreadyExists(uint256 id); + struct Commitment { bytes ciphertext; // AES/GCM ciphertext (includes tag) bytes encKeyForAuditor; // encrypted symmetric key for auditor @@ -83,10 +93,14 @@ contract RaylsHook is BaseHook { uint256 walletInProof = pubSignals[2]; // index 2 because it's the 3rd public signal address origin = _determineOrigin(msg.sender); - require(walletInProof == uint256(uint160(origin)), "Invalid wallet for this proof"); + if (walletInProof != uint256(uint160(origin))) { + revert InvalidWallet(address(uint160(walletInProof)), origin); + } bool suitabilityOk = suitabilityVerifier.verifyProof(pA, pB, pC, pubSignals); - require(suitabilityOk, "Invalid Suitability proof"); + if (!suitabilityOk) { + revert InvalidSuitabilityProof(); + } return (BaseHook.beforeSwap.selector, BeforeSwapDeltaLibrary.ZERO_DELTA, 0); } @@ -136,7 +150,9 @@ contract RaylsHook is BaseHook { } function executeCommitment(uint256 id, bytes calldata data) external { - require(!commitments[id].executed, "already executed"); + if (commitments[id].executed) { + revert AlreadyExecuted(id); + } (uint256[2] memory pA, uint256[2][2] memory pB, uint256[2] memory pC, uint256[5] memory pubSignals) = abi.decode(data, (uint256[2], uint256[2][2], uint256[2], uint256[5])); @@ -147,17 +163,30 @@ contract RaylsHook is BaseHook { commitments[id].ciphertext, commitments[id].encKeyForAuditor ); - require(uint256(keccak256(pubId)) == id, "commitment mismatch"); - require(pubSignals[2] == 1, "Not marked as executed"); - require(pubSignals[4] <= block.timestamp, "Commitment can not be executed yet"); + + if (uint256(keccak256(pubId)) != id) { + revert CommitmentMismatch(pubId, id); + } + + if (pubSignals[2] != 1) { + revert NotMarkedAsExecuted(pubSignals[2]); + } + + if (pubSignals[4] > block.timestamp) { + revert CommitmentNotReady(pubSignals[4], block.timestamp); + } bool privateVerifierOk = privateSwapIntentVerifier.verifyProof(pA, pB, pC, pubSignals); - require(privateVerifierOk, "Invalid PrivateSwapIntent proof"); + if (!privateVerifierOk) { + revert InvalidPrivateSwapIntentProof(); + } commitments[id].executed = true; } function storeCommitment(uint256 id, bytes calldata ciphertext, bytes calldata encKeyForAuditor) external { - require(!commitments[id].exists, "already exists"); + if (commitments[id].exists) { + revert AlreadyExists(id); + } commitments[id] = Commitment({ ciphertext: ciphertext, encKeyForAuditor: encKeyForAuditor, exists: true, executed: false }); emit CommitmentStored(id, msg.sender); diff --git a/packages/foundry/test/RaylsHook.t.sol b/packages/foundry/test/RaylsHook.t.sol index 44f5126..e95f286 100644 --- a/packages/foundry/test/RaylsHook.t.sol +++ b/packages/foundry/test/RaylsHook.t.sol @@ -201,14 +201,11 @@ contract RaylsHookTest is Test, Deployers { bytes memory encKeyForAuditor = RaylsHookHelper.hexStringToBytes(encKeyForAuditorStr); bytes memory ciphertext = RaylsHookHelper.hexStringToBytes(ciphertextStr); - vm.warp(pubSignals[4]); - console.log("Block timestamp:", block.timestamp); - uint256 id = uint256( keccak256( abi.encodePacked( - pubSignals[0], // Poseidon hash of (amount, recipient, nonce) - ciphertext, // AES-encrypted message (always present) + pubSignals[0], // Poseidon hash of (amountIn, zeroForOne, sender, timestamp) + ciphertext, // AES-encrypted message optional encKeyForAuditor // optional: can be empty bytes ) ) @@ -216,7 +213,18 @@ contract RaylsHookTest is Test, Deployers { vm.startPrank(proofSender, proofSender); hook.storeCommitment(id, ciphertext, encKeyForAuditor); + + // Move time forward but not enough to be able to execute the commitment + vm.warp(pubSignals[4] - 1); + bytes memory expectedRevert = + abi.encodeWithSelector(RaylsHook.CommitmentNotReady.selector, pubSignals[4], block.timestamp); + vm.expectRevert(expectedRevert); hook.executeCommitment(id, proofData); + + // Move time forward to be able to execute the commitment + vm.warp(pubSignals[4]); + hook.executeCommitment(id, proofData); + vm.stopPrank(); (bytes memory onChainCiphertext, bytes memory onChainEncKeyForAuditor,, bool executed) = hook.commitments(id); From 1442690ac0c669cf38d472b86566061637ba5097 Mon Sep 17 00:00:00 2001 From: Nuno Date: Thu, 11 Sep 2025 19:04:05 +0100 Subject: [PATCH 02/29] feat: adding actual swap logic, permit, plus some improvements --- packages/foundry/contracts/RaylsHook.sol | 161 +++++++++++++++--- packages/foundry/foundry.toml | 2 +- packages/foundry/test/RaylsHook.t.sol | 31 ++-- .../foundry/test/utils/RaylsHookHelper.sol | 41 +++++ 4 files changed, 204 insertions(+), 31 deletions(-) diff --git a/packages/foundry/contracts/RaylsHook.sol b/packages/foundry/contracts/RaylsHook.sol index 2aee751..0fb17e9 100644 --- a/packages/foundry/contracts/RaylsHook.sol +++ b/packages/foundry/contracts/RaylsHook.sol @@ -13,9 +13,19 @@ import { SuitabilityAssessmentVerifier } from "./SuitabilityAssessmentVerifier.s import { console } from "forge-std/console.sol"; import { PrivateSwapIntentVerifier } from "./PrivateSwapIntentVerifier.sol"; +import { BalanceDelta } from "@uniswap/v4-core/src/types/BalanceDelta.sol"; +import { TickMath } from "@uniswap/v4-core/src/libraries/TickMath.sol"; +import { Currency } from "@uniswap/v4-core/src/types/Currency.sol"; +import { IUnlockCallback } from "@uniswap/v4-core/src/interfaces/callback/IUnlockCallback.sol"; +import { IERC20Permit } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol"; +import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import { ReentrancyGuard } from "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; +import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import { console } from "forge-std/console.sol"; -contract RaylsHook is BaseHook { +contract RaylsHook is BaseHook, IUnlockCallback, ReentrancyGuard { using PoolIdLibrary for PoolKey; + using SafeERC20 for IERC20; // NOTE: --------------------------------------------------------- // state variables should typically be unique to a pool @@ -30,7 +40,7 @@ contract RaylsHook is BaseHook { SuitabilityAssessmentVerifier public suitabilityVerifier; PrivateSwapIntentVerifier public privateSwapIntentVerifier; - mapping(uint256 => Commitment) public commitments; + mapping(PoolId poolId => mapping(uint256 => Commitment)) public commitments; event CommitmentStored(uint256 id, address indexed sender); event Revealed(uint256 id, address indexed revealer); @@ -48,6 +58,7 @@ contract RaylsHook is BaseHook { struct Commitment { bytes ciphertext; // AES/GCM ciphertext (includes tag) bytes encKeyForAuditor; // encrypted symmetric key for auditor + bytes permit; bool exists; bool executed; } @@ -149,46 +160,156 @@ contract RaylsHook is BaseHook { } } - function executeCommitment(uint256 id, bytes calldata data) external { - if (commitments[id].executed) { + function executeCommitment(PoolKey calldata key, uint256 id, bytes calldata data) + external + nonReentrant + returns (BalanceDelta) + { + if (commitments[key.toId()][id].executed) { revert AlreadyExecuted(id); } (uint256[2] memory pA, uint256[2][2] memory pB, uint256[2] memory pC, uint256[5] memory pubSignals) = abi.decode(data, (uint256[2], uint256[2][2], uint256[2], uint256[5])); - // Making sure we are executing the right commitment - bytes memory pubId = abi.encodePacked( - pubSignals[0], // Poseidon hash of (amount, recipient, nonce) - commitments[id].ciphertext, - commitments[id].encKeyForAuditor - ); - - if (uint256(keccak256(pubId)) != id) { - revert CommitmentMismatch(pubId, id); + if (pubSignals[4] > block.timestamp) { + revert CommitmentNotReady(pubSignals[4], block.timestamp); } if (pubSignals[2] != 1) { revert NotMarkedAsExecuted(pubSignals[2]); } - if (pubSignals[4] > block.timestamp) { - revert CommitmentNotReady(pubSignals[4], block.timestamp); + // Making sure we are executing the right commitment + bytes memory pubId = abi.encode( + pubSignals[0], // Poseidon hash of (amount, recipient, nonce) + commitments[key.toId()][id].ciphertext, + commitments[key.toId()][id].encKeyForAuditor + ); + + if (keccak256(pubId) != bytes32(id)) { + revert CommitmentMismatch(pubId, id); } bool privateVerifierOk = privateSwapIntentVerifier.verifyProof(pA, pB, pC, pubSignals); if (!privateVerifierOk) { revert InvalidPrivateSwapIntentProof(); } - commitments[id].executed = true; + + // We can swap now + + // Mark as executed before any external transfer/call + commitments[key.toId()][id].executed = true; + + // Run the permit if needed + if (commitments[key.toId()][id].permit.length > 0) { + (uint8 v, bytes32 r, bytes32 s) = splitSig(commitments[key.toId()][id].permit); + IERC20Permit(Currency.unwrap(key.currency0)).permit( + address(uint160(pubSignals[3])), address(this), pubSignals[1], pubSignals[4] + 1 days, v, r, s + ); + } + + // First transfer the tokens to the hook contract + IERC20(Currency.unwrap(key.currency0)).safeTransferFrom( + address(uint160(pubSignals[3])), address(this), pubSignals[1] + ); + + // Then unlock the PoolManager to execute the swap + bool zeroForOne = pubSignals[2] == 1 ? true : false; + bytes memory callbackReturn = poolManager.unlock( + abi.encode( + key, + SwapParams({ + zeroForOne: zeroForOne, + // We provide a negative value here to signify an "exact input for output" swap + amountSpecified: -int256(pubSignals[1]), + // No slippage limits (maximum slippage possible) + sqrtPriceLimitX96: zeroForOne ? TickMath.MIN_SQRT_PRICE + 1 : TickMath.MAX_SQRT_PRICE - 1 + }) + ) + ); + + (BalanceDelta delta) = abi.decode(callbackReturn, (BalanceDelta)); + // emit Executed(keyId, id, owner, /*...*/); + return delta; } - function storeCommitment(uint256 id, bytes calldata ciphertext, bytes calldata encKeyForAuditor) external { - if (commitments[id].exists) { + function storeCommitment( + PoolKey calldata key, + uint256 id, + bytes calldata ciphertext, + bytes calldata encKeyForAuditor, + bytes calldata permit + ) external { + if (commitments[key.toId()][id].exists) { revert AlreadyExists(id); } - commitments[id] = - Commitment({ ciphertext: ciphertext, encKeyForAuditor: encKeyForAuditor, exists: true, executed: false }); + commitments[key.toId()][id] = Commitment({ + ciphertext: ciphertext, + encKeyForAuditor: encKeyForAuditor, + permit: permit, + exists: true, + executed: false + }); emit CommitmentStored(id, msg.sender); } + + function swapAndSettleBalances(PoolKey memory key, SwapParams memory params) internal returns (BalanceDelta) { + // Conduct the swap inside the Pool Manager + BalanceDelta delta = poolManager.swap(key, params, ""); + + // If we just did a zeroForOne swap + // We need to send Token 0 to PM, and receive Token 1 from PM + if (params.zeroForOne) { + // Negative Value => Money leaving user's wallet + // Settle with PoolManager + if (delta.amount0() < 0) { + _settle(key.currency0, uint128(-delta.amount0())); + } + + // Positive Value => Money coming into user's wallet + // Take from PM + if (delta.amount1() > 0) { + _take(key.currency1, uint128(delta.amount1())); + } + } else { + if (delta.amount1() < 0) { + _settle(key.currency1, uint128(-delta.amount1())); + } + + if (delta.amount0() > 0) { + _take(key.currency0, uint128(delta.amount0())); + } + } + + return delta; + } + + function _settle(Currency currency, uint128 amount) internal { + // Transfer tokens to PM and let it know + poolManager.sync(currency); + currency.transfer(address(poolManager), amount); + poolManager.settle(); + } + + function _take(Currency currency, uint128 amount) internal { + // Take tokens out of PM to our hook contract + poolManager.take(currency, address(this), amount); + } + + function unlockCallback(bytes calldata data) external returns (bytes memory) { + (PoolKey memory key, SwapParams memory params) = abi.decode(data, (PoolKey, SwapParams)); + BalanceDelta delta = swapAndSettleBalances(key, params); + return abi.encode(delta); + } + + function splitSig(bytes memory sig) internal pure returns (uint8 v, bytes32 r, bytes32 s) { + require(sig.length == 65, "bad sig length"); + + assembly { + r := mload(add(sig, 32)) + s := mload(add(sig, 64)) + v := byte(0, mload(add(sig, 96))) + } + } } diff --git a/packages/foundry/foundry.toml b/packages/foundry/foundry.toml index ab30ed6..bcfd5e4 100644 --- a/packages/foundry/foundry.toml +++ b/packages/foundry/foundry.toml @@ -7,7 +7,7 @@ fs_permissions = [{ access = "read-write", path = "./"}] solc_version = '0.8.26' evm_version = "cancun" # hard fork that enabled EIP-1153 optimizer_runs = 800 -via_ir = false +via_ir = true ffi = true diff --git a/packages/foundry/test/RaylsHook.t.sol b/packages/foundry/test/RaylsHook.t.sol index e95f286..b492ddc 100644 --- a/packages/foundry/test/RaylsHook.t.sol +++ b/packages/foundry/test/RaylsHook.t.sol @@ -36,8 +36,12 @@ contract RaylsHookTest is Test, Deployers { using CurrencyLibrary for Currency; using StateLibrary for IPoolManager; - address proofSender = 0x1234567890AbcdEF1234567890aBcdef12345678; address invalidProofSender = 0x876543210FedCBa9876543210fedcBA987654321; + + // Private key for proofSender for wallet 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 + uint256 proofSenderPk = 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d; + address proofSender = vm.addr(proofSenderPk); + // Private key for Auditor for wallet 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 string auditorPk = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; @@ -187,13 +191,13 @@ contract RaylsHookTest is Test, Deployers { assertTrue(ok); // this will fail if verifyProof==false } - function testPrivateSwap() public { + function testAPrivateSwap() public { (uint256[2] memory pA, uint256[2][2] memory pB, uint256[2] memory pC, uint256[5] memory pubSignals) = RaylsHookHelper.loadPrivateSwapIntentProof(jsonPrivateSwap); bytes memory proofData = abi.encode(pA, pB, pC, pubSignals); - uint256 amountIn = 1e16; - IERC20Minimal(Currency.unwrap(currency0)).approve(address(swapRouter), amountIn); + uint256 amountIn = pubSignals[1]; + uint256 timestamp = pubSignals[4]; string memory encKeyForAuditorStr = jsonEncryptedPayload.readString(".encKeyForAuditor"); string memory ciphertextStr = jsonEncryptedPayload.readString(".ciphertext"); @@ -203,7 +207,7 @@ contract RaylsHookTest is Test, Deployers { uint256 id = uint256( keccak256( - abi.encodePacked( + abi.encode( pubSignals[0], // Poseidon hash of (amountIn, zeroForOne, sender, timestamp) ciphertext, // AES-encrypted message optional encKeyForAuditor // optional: can be empty bytes @@ -212,22 +216,29 @@ contract RaylsHookTest is Test, Deployers { ); vm.startPrank(proofSender, proofSender); - hook.storeCommitment(id, ciphertext, encKeyForAuditor); + bytes memory permitSignature = RaylsHookHelper.buildPermitSignature( + vm, proofSenderPk, Currency.unwrap(currency0), timestamp, proofSender, address(hook), amountIn + ); + hook.storeCommitment(poolKey, id, ciphertext, encKeyForAuditor, permitSignature); + + // For now we just approve the swapRouter to spend the tokens + // IERC20Minimal(Currency.unwrap(currency0)).approve(address(hook), amountIn); // Move time forward but not enough to be able to execute the commitment vm.warp(pubSignals[4] - 1); bytes memory expectedRevert = abi.encodeWithSelector(RaylsHook.CommitmentNotReady.selector, pubSignals[4], block.timestamp); vm.expectRevert(expectedRevert); - hook.executeCommitment(id, proofData); + hook.executeCommitment(poolKey, id, proofData); // Move time forward to be able to execute the commitment vm.warp(pubSignals[4]); - hook.executeCommitment(id, proofData); - + BalanceDelta delta = hook.executeCommitment(poolKey, id, proofData); + assertEq(int256(delta.amount0()), -int256(amountIn)); vm.stopPrank(); - (bytes memory onChainCiphertext, bytes memory onChainEncKeyForAuditor,, bool executed) = hook.commitments(id); + (bytes memory onChainCiphertext, bytes memory onChainEncKeyForAuditor,, bool executed,) = + hook.commitments(poolKey.toId(), id); assertEq(executed, true); assertEq(onChainCiphertext, ciphertext); diff --git a/packages/foundry/test/utils/RaylsHookHelper.sol b/packages/foundry/test/utils/RaylsHookHelper.sol index 40f2646..b5cae35 100644 --- a/packages/foundry/test/utils/RaylsHookHelper.sol +++ b/packages/foundry/test/utils/RaylsHookHelper.sol @@ -4,6 +4,7 @@ pragma solidity ^0.8.21; import { console } from "forge-std/console.sol"; import "forge-std/StdJson.sol"; import { Vm } from "forge-std/Test.sol"; +import { IERC20Permit } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol"; library RaylsHookHelper { using stdJson for string; @@ -140,4 +141,44 @@ library RaylsHookHelper { if (c >= 97 && c <= 102) return c - 87; // 'a'-'f' revert("invalid hex char"); } + + function splitSig(bytes memory sig) internal pure returns (uint8 v, bytes32 r, bytes32 s) { + require(sig.length == 65, "bad sig length"); + + assembly { + r := mload(add(sig, 32)) + s := mload(add(sig, 64)) + v := byte(0, mload(add(sig, 96))) + } + } + + function buildPermitSignature( + Vm vm, + uint256 privateKey, + address token, + uint256 timestamp, + address sender, + address receiver, + uint256 amount + ) public view returns (bytes memory) { + uint256 nonce = IERC20Permit(token).nonces(sender); + uint256 deadline = timestamp + 1 days; + + // EIP-712 domain separator + bytes32 DOMAIN_SEPARATOR = IERC20Permit(token).DOMAIN_SEPARATOR(); + + // Permit typehash (same as OZ ERC20Permit) + bytes32 PERMIT_TYPEHASH = + keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); + + // Build struct hash + bytes32 structHash = keccak256(abi.encode(PERMIT_TYPEHASH, sender, address(receiver), amount, nonce, deadline)); + + // Final digest (EIP-712) + bytes32 digest = keccak256(abi.encodePacked("\x19\x01", DOMAIN_SEPARATOR, structHash)); + + // Sign with Foundry’s vm.sign + (uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, digest); + return abi.encodePacked(r, s, v); + } } From 8af635186ea6de1d78cae67cc351ff0b8e936ada Mon Sep 17 00:00:00 2001 From: Nuno Date: Fri, 12 Sep 2025 11:19:15 +0100 Subject: [PATCH 03/29] feat: adding cancel commitment and cleaning up a bit --- .../scripts/PrivateSwapIntent_input.json | 6 + .../circom/scripts/Suitability_input.json | 12 ++ packages/foundry/contracts/RaylsHook.sol | 117 ++++++++++-------- packages/foundry/test/RaylsHook.t.sol | 9 +- 4 files changed, 87 insertions(+), 57 deletions(-) create mode 100644 packages/circom/scripts/PrivateSwapIntent_input.json create mode 100644 packages/circom/scripts/Suitability_input.json diff --git a/packages/circom/scripts/PrivateSwapIntent_input.json b/packages/circom/scripts/PrivateSwapIntent_input.json new file mode 100644 index 0000000..16bd6c6 --- /dev/null +++ b/packages/circom/scripts/PrivateSwapIntent_input.json @@ -0,0 +1,6 @@ +{ + "amountIn": "1000000000000000", + "zeroForOne": "1", + "sender": "0x70997970C51812dc3A010C7d01b50e0d17dc79C8", + "timestamp": "1697052800" +} diff --git a/packages/circom/scripts/Suitability_input.json b/packages/circom/scripts/Suitability_input.json new file mode 100644 index 0000000..d1965f0 --- /dev/null +++ b/packages/circom/scripts/Suitability_input.json @@ -0,0 +1,12 @@ +{ + "answer1": 3, + "answer2": 2, + "answer3": 1, + "answer4": 2, + "answer5": 3, + "wallet": "0x1234567890AbcdEF1234567890aBcdef12345678", + "thresholdScaled": 20, + "isSuitablePub": 1 +} + + \ No newline at end of file diff --git a/packages/foundry/contracts/RaylsHook.sol b/packages/foundry/contracts/RaylsHook.sol index 0fb17e9..5fbab8c 100644 --- a/packages/foundry/contracts/RaylsHook.sol +++ b/packages/foundry/contracts/RaylsHook.sol @@ -42,25 +42,34 @@ contract RaylsHook is BaseHook, IUnlockCallback, ReentrancyGuard { mapping(PoolId poolId => mapping(uint256 => Commitment)) public commitments; - event CommitmentStored(uint256 id, address indexed sender); - event Revealed(uint256 id, address indexed revealer); + event CommitmentStored(uint256 indexed id, address indexed sender, bytes, bytes, bytes); + event CommitmentExecuted(uint256 indexed id, address indexed sender); + event CommitmentCanceled(uint256 indexed id, address indexed canceller); // Errors error CommitmentMismatch(bytes pubId, uint256 expectedId); - error NotMarkedAsExecuted(uint256 signal); error CommitmentNotReady(uint256 notBefore, uint256 currentTime); error InvalidWallet(address provided, address expected); error InvalidSuitabilityProof(); error AlreadyExecuted(uint256 id); error InvalidPrivateSwapIntentProof(); error AlreadyExists(uint256 id); + error CommitmentNotActive(uint256 id); + error CommitmentNotFound(uint256 id); + + enum CommitmentStatus { + None, // default, not stored + Active, // stored but not yet executed + Executed, // executed successfully + Canceled // canceled by creator + + } struct Commitment { bytes ciphertext; // AES/GCM ciphertext (includes tag) bytes encKeyForAuditor; // encrypted symmetric key for auditor bytes permit; - bool exists; - bool executed; + CommitmentStatus status; } constructor(IPoolManager _poolManager, address _suitabilityVerifier, address _privateSwapIntentVerifier) @@ -74,12 +83,12 @@ contract RaylsHook is BaseHook, IUnlockCallback, ReentrancyGuard { return Hooks.Permissions({ beforeInitialize: false, afterInitialize: false, - beforeAddLiquidity: true, + beforeAddLiquidity: false, afterAddLiquidity: false, - beforeRemoveLiquidity: true, + beforeRemoveLiquidity: false, afterRemoveLiquidity: false, beforeSwap: true, - afterSwap: true, + afterSwap: false, beforeDonate: false, afterDonate: false, beforeSwapReturnDelta: false, @@ -116,32 +125,6 @@ contract RaylsHook is BaseHook, IUnlockCallback, ReentrancyGuard { return (BaseHook.beforeSwap.selector, BeforeSwapDeltaLibrary.ZERO_DELTA, 0); } - function _afterSwap(address, PoolKey calldata key, SwapParams calldata, BalanceDelta, bytes calldata) - internal - override - returns (bytes4, int128) - { - return (BaseHook.afterSwap.selector, 0); - } - - function _beforeAddLiquidity(address, PoolKey calldata key, ModifyLiquidityParams calldata, bytes calldata) - internal - override - returns (bytes4) - { - beforeAddLiquidityCount[key.toId()]++; - return BaseHook.beforeAddLiquidity.selector; - } - - function _beforeRemoveLiquidity(address, PoolKey calldata key, ModifyLiquidityParams calldata, bytes calldata) - internal - override - returns (bytes4) - { - beforeRemoveLiquidityCount[key.toId()]++; - return BaseHook.beforeRemoveLiquidity.selector; - } - /** * Determines the origin of the transaction. * @@ -165,8 +148,12 @@ contract RaylsHook is BaseHook, IUnlockCallback, ReentrancyGuard { nonReentrant returns (BalanceDelta) { - if (commitments[key.toId()][id].executed) { - revert AlreadyExecuted(id); + Commitment storage commitment = commitments[key.toId()][id]; + if (commitment.status == CommitmentStatus.None) { + revert CommitmentNotFound(id); + } + if (commitment.status != CommitmentStatus.Active) { + revert CommitmentNotActive(id); } (uint256[2] memory pA, uint256[2][2] memory pB, uint256[2] memory pC, uint256[5] memory pubSignals) = @@ -176,15 +163,11 @@ contract RaylsHook is BaseHook, IUnlockCallback, ReentrancyGuard { revert CommitmentNotReady(pubSignals[4], block.timestamp); } - if (pubSignals[2] != 1) { - revert NotMarkedAsExecuted(pubSignals[2]); - } - // Making sure we are executing the right commitment bytes memory pubId = abi.encode( pubSignals[0], // Poseidon hash of (amount, recipient, nonce) - commitments[key.toId()][id].ciphertext, - commitments[key.toId()][id].encKeyForAuditor + commitment.ciphertext, + commitment.encKeyForAuditor ); if (keccak256(pubId) != bytes32(id)) { @@ -197,13 +180,12 @@ contract RaylsHook is BaseHook, IUnlockCallback, ReentrancyGuard { } // We can swap now - // Mark as executed before any external transfer/call - commitments[key.toId()][id].executed = true; + commitment.status = CommitmentStatus.Executed; // Run the permit if needed - if (commitments[key.toId()][id].permit.length > 0) { - (uint8 v, bytes32 r, bytes32 s) = splitSig(commitments[key.toId()][id].permit); + if (commitment.permit.length > 0) { + (uint8 v, bytes32 r, bytes32 s) = splitSig(commitment.permit); IERC20Permit(Currency.unwrap(key.currency0)).permit( address(uint160(pubSignals[3])), address(this), pubSignals[1], pubSignals[4] + 1 days, v, r, s ); @@ -230,7 +212,7 @@ contract RaylsHook is BaseHook, IUnlockCallback, ReentrancyGuard { ); (BalanceDelta delta) = abi.decode(callbackReturn, (BalanceDelta)); - // emit Executed(keyId, id, owner, /*...*/); + emit CommitmentExecuted(id, msg.sender); return delta; } @@ -241,17 +223,50 @@ contract RaylsHook is BaseHook, IUnlockCallback, ReentrancyGuard { bytes calldata encKeyForAuditor, bytes calldata permit ) external { - if (commitments[key.toId()][id].exists) { + if (commitments[key.toId()][id].status != CommitmentStatus.None) { revert AlreadyExists(id); } + commitments[key.toId()][id] = Commitment({ ciphertext: ciphertext, encKeyForAuditor: encKeyForAuditor, permit: permit, - exists: true, - executed: false + status: CommitmentStatus.Active }); - emit CommitmentStored(id, msg.sender); + emit CommitmentStored(id, msg.sender, ciphertext, encKeyForAuditor, permit); + } + + function cancelCommitment(PoolKey calldata key, uint256 id, bytes calldata data) external { + Commitment storage c = commitments[key.toId()][id]; + if (c.status != CommitmentStatus.Active) { + revert CommitmentNotActive(id); + } + + (uint256[2] memory pA, uint256[2][2] memory pB, uint256[2] memory pC, uint256[5] memory pubSignals) = + abi.decode(data, (uint256[2], uint256[2][2], uint256[2], uint256[5])); + + // Making sure we are executing the right commitment + bytes memory pubId = abi.encode( + pubSignals[0], // Poseidon hash of (amount, recipient, nonce) + c.ciphertext, + c.encKeyForAuditor + ); + + if (keccak256(pubId) != bytes32(id)) { + revert CommitmentMismatch(pubId, id); + } + + bool privateVerifierOk = privateSwapIntentVerifier.verifyProof(pA, pB, pC, pubSignals); + if (!privateVerifierOk) { + revert InvalidPrivateSwapIntentProof(); + } + + // We can cancel now + c.status = CommitmentStatus.Canceled; + delete c.ciphertext; + delete c.encKeyForAuditor; + delete c.permit; + emit CommitmentCanceled(id, msg.sender); } function swapAndSettleBalances(PoolKey memory key, SwapParams memory params) internal returns (BalanceDelta) { diff --git a/packages/foundry/test/RaylsHook.t.sol b/packages/foundry/test/RaylsHook.t.sol index b492ddc..a141c33 100644 --- a/packages/foundry/test/RaylsHook.t.sol +++ b/packages/foundry/test/RaylsHook.t.sol @@ -88,10 +88,7 @@ contract RaylsHookTest is Test, Deployers { // Deploy the hook to an address with the correct flags address flags = address( - uint160( - Hooks.BEFORE_SWAP_FLAG | Hooks.AFTER_SWAP_FLAG | Hooks.BEFORE_ADD_LIQUIDITY_FLAG - | Hooks.BEFORE_REMOVE_LIQUIDITY_FLAG - ) ^ (0x4444 << 144) // Namespace the hook to avoid collisions + uint160(Hooks.BEFORE_SWAP_FLAG) ^ (0x4444 << 144) // Namespace the hook to avoid collisions ); bytes memory constructorArgs = abi.encode(poolManager, suitabilityVerifier, privateSwapIntentVerifier); // Add all the necessary constructor arguments from the hook deployCodeTo("RaylsHook.sol:RaylsHook", constructorArgs, flags); @@ -237,10 +234,10 @@ contract RaylsHookTest is Test, Deployers { assertEq(int256(delta.amount0()), -int256(amountIn)); vm.stopPrank(); - (bytes memory onChainCiphertext, bytes memory onChainEncKeyForAuditor,, bool executed,) = + (bytes memory onChainCiphertext, bytes memory onChainEncKeyForAuditor,, RaylsHook.CommitmentStatus status) = hook.commitments(poolKey.toId(), id); - assertEq(executed, true); + assertEq(uint8(status), uint8(RaylsHook.CommitmentStatus.Executed)); assertEq(onChainCiphertext, ciphertext); assertEq(onChainEncKeyForAuditor, encKeyForAuditor); string memory hexOnChainCiphertext = vm.toString(onChainCiphertext); From e49deb0066ec2ea9a6dbdff288c2edb539e6e9d6 Mon Sep 17 00:00:00 2001 From: Nuno Date: Fri, 12 Sep 2025 15:39:03 +0100 Subject: [PATCH 04/29] feat: changing to direct encryption using ECIES. adding comments etc --- packages/encryption/decrypt.cjs | 29 +-- packages/encryption/encrypt.js | 25 +-- packages/foundry/contracts/RaylsHook.sol | 178 ++++++++++-------- packages/foundry/test/RaylsHook.t.sol | 33 +--- .../foundry/test/utils/RaylsHookHelper.sol | 13 +- 5 files changed, 128 insertions(+), 150 deletions(-) diff --git a/packages/encryption/decrypt.cjs b/packages/encryption/decrypt.cjs index 2f04726..41f66ea 100644 --- a/packages/encryption/decrypt.cjs +++ b/packages/encryption/decrypt.cjs @@ -7,17 +7,14 @@ const eccrypto = require("eccrypto"); const crypto = require("crypto"); const { buildPoseidon } = require("circomlibjs"); - - // ECIES encrypted symmetric key (from encrypt.js) -if (process.argv.length !== 5) { - console.error("Usage: node decrypt.cjs "); +if (process.argv.length !== 4) { + console.error("Usage: node decrypt.cjs "); process.exit(1); } const auditorPrivKey = process.argv[2]; -const ciphertextHex = process.argv[3]; -const encKeyForAuditor = process.argv[4]; +const encKeyForAuditor = process.argv[3]; // Auditor private key (Buffer) const auditorPriv = Buffer.from( @@ -25,7 +22,6 @@ const auditorPriv = Buffer.from( "hex" ); -const ciphertextBuffer = Buffer.from(ciphertextHex.replace(/^0x/, ""), "hex"); const encKeyForAuditorBuffer = Buffer.from(encKeyForAuditor.replace(/^0x/, ""), "hex"); // ---------------------- @@ -44,18 +40,6 @@ async function decryptSymmetricKey(encKeyForAuditorBuffer, auditorPriv) { return K; } -// 2️⃣ Decrypt AES-GCM ciphertext -function decryptMessage(K, ciphertextBuffer) { - const iv = ciphertextBuffer.slice(0, 12); - const tag = ciphertextBuffer.slice(12, 28); // 16 bytes tag - const enc = ciphertextBuffer.slice(28); - - const decipher = crypto.createDecipheriv("aes-256-gcm", K, iv); - decipher.setAuthTag(tag); - const plaintext = Buffer.concat([decipher.update(enc), decipher.final()]); - return plaintext; -} - // 3️⃣ Parse plaintext buffer into circuit inputs function parseMessage(plaintext) { let offset = 0; @@ -97,13 +81,10 @@ async function computeCommitmentId(amountIn, zeroForOne, sender, timestamp) { // ---------------------- (async () => { // Recover symmetric key - const K = await decryptSymmetricKey(encKeyForAuditorBuffer, auditorPriv); - - // Decrypt message - const plaintext = decryptMessage(K, ciphertextBuffer); + const decryptedMessage = await decryptSymmetricKey(encKeyForAuditorBuffer, auditorPriv); // Parse back to circuit inputs - const parsed = parseMessage(plaintext); + const parsed = parseMessage(decryptedMessage); // Compute commitment ID const commitmentId = await computeCommitmentId( diff --git a/packages/encryption/encrypt.js b/packages/encryption/encrypt.js index 4bc8678..7d16ab7 100644 --- a/packages/encryption/encrypt.js +++ b/packages/encryption/encrypt.js @@ -34,32 +34,21 @@ async function main() { const message = Buffer.concat([amountBuf, zeroForOneBuf, senderBuf, timestampBuf]); - // Symmetric key K - const K = crypto.randomBytes(32); - - // Encrypt the message with AES-GCM - const ciphertext = aesGcmEncrypt(K, message); - // Encrypt K with auditor’s public key (ECIES) - const encKeyForAuditor = await eccrypto.encrypt( + const encForAuditor = await eccrypto.encrypt( Buffer.from(pubKeyUncompressed.slice(2), "hex"), // drop 0x - K + message ); const encryptedBuffer = Buffer.concat([ - encKeyForAuditor.iv, // 16 bytes - encKeyForAuditor.ephemPublicKey, // 65 bytes - encKeyForAuditor.ciphertext, // variable - encKeyForAuditor.mac // 32 bytes + encForAuditor.iv, // 16 bytes + encForAuditor.ephemPublicKey, // 65 bytes + encForAuditor.ciphertext, // variable + encForAuditor.mac // 32 bytes ]); - // Convert to BytesLike - const encKeyForAuditorBytes = ethers.getBytes(encryptedBuffer); - const ciphertextBytes = ethers.getBytes("0x" + ciphertext.toString("hex")); - const jsonData = { - encKeyForAuditor: ethers.hexlify(encKeyForAuditorBytes), - ciphertext: ethers.hexlify(ciphertextBytes) + ciphertextForAuditor: ethers.hexlify(encryptedBuffer) }; await fs.writeFile("../foundry/inputs/encryptedPayload.json", JSON.stringify(jsonData, null, 2)); diff --git a/packages/foundry/contracts/RaylsHook.sol b/packages/foundry/contracts/RaylsHook.sol index 5fbab8c..ee5ff9e 100644 --- a/packages/foundry/contracts/RaylsHook.sol +++ b/packages/foundry/contracts/RaylsHook.sol @@ -42,7 +42,7 @@ contract RaylsHook is BaseHook, IUnlockCallback, ReentrancyGuard { mapping(PoolId poolId => mapping(uint256 => Commitment)) public commitments; - event CommitmentStored(uint256 indexed id, address indexed sender, bytes, bytes, bytes); + event CommitmentStored(uint256 indexed id, address indexed sender, bytes, bytes); event CommitmentExecuted(uint256 indexed id, address indexed sender); event CommitmentCanceled(uint256 indexed id, address indexed canceller); @@ -66,8 +66,7 @@ contract RaylsHook is BaseHook, IUnlockCallback, ReentrancyGuard { } struct Commitment { - bytes ciphertext; // AES/GCM ciphertext (includes tag) - bytes encKeyForAuditor; // encrypted symmetric key for auditor + bytes ciphertextForAuditor; //ECIES-encrypted swap details for auditor bytes permit; CommitmentStatus status; } @@ -98,10 +97,10 @@ contract RaylsHook is BaseHook, IUnlockCallback, ReentrancyGuard { }); } - // ----------------------------------------------- - // NOTE: see IHooks.sol for function documentation - // ----------------------------------------------- - + /** + * Here we verify the suitability proof and that the wallet in the proof matches the transaction origin + * + */ function _beforeSwap(address, PoolKey calldata key, SwapParams calldata, bytes calldata data) internal override @@ -111,12 +110,16 @@ contract RaylsHook is BaseHook, IUnlockCallback, ReentrancyGuard { abi.decode(data, (uint256[2], uint256[2][2], uint256[2], uint256[5])); uint256 walletInProof = pubSignals[2]; // index 2 because it's the 3rd public signal + + // We want to identify the originator of the transaction address origin = _determineOrigin(msg.sender); + // Verify the wallet address in the proof matches the transaction origin if (walletInProof != uint256(uint160(origin))) { revert InvalidWallet(address(uint160(walletInProof)), origin); } + // Verify the Suitability proof bool suitabilityOk = suitabilityVerifier.verifyProof(pA, pB, pC, pubSignals); if (!suitabilityOk) { revert InvalidSuitabilityProof(); @@ -126,24 +129,82 @@ contract RaylsHook is BaseHook, IUnlockCallback, ReentrancyGuard { } /** - * Determines the origin of the transaction. - * - * @param _sender The sender of the transaction - * - * @return origin_ The origin of the transaction + * @notice Stores a new encrypted swap commitment onchain. + * @dev Each commitment is uniquely identified by `id` under a specific pool key. + * Reverts if a commitment with the same `id` already exists. + * The ciphertextForAuditor allows a designated auditor to decrypt the swap parameters offchain. + * @param key Pool key identifying the Uniswap v4 pool this commitment belongs to. + * @param id Unique identifier for the commitment (Poseidon/keccak hash). + * @param ciphertextForAuditor Encrypted swap data for the auditor + * @param permit ERC20 permit signature data, allowing token transfers at execution. + * Emits a {CommitmentStored} event. */ - function _determineOrigin(address _sender) internal returns (address origin_) { - // Set our default origin to the `tx.origin` - origin_ = tx.origin; + function storeCommitment( + PoolKey calldata key, + uint256 id, + bytes calldata ciphertextForAuditor, + bytes calldata permit + ) external { + if (commitments[key.toId()][id].status != CommitmentStatus.None) { + revert AlreadyExists(id); + } - // If the sender has a `msgSender` function, then we use that to determine the origin - (bool success, bytes memory data) = _sender.call(abi.encodeWithSignature("msgSender()")); - if (success && data.length >= 32) { - origin_ = abi.decode(data, (address)); + commitments[key.toId()][id] = + Commitment({ ciphertextForAuditor: ciphertextForAuditor, permit: permit, status: CommitmentStatus.Active }); + emit CommitmentStored(id, msg.sender, ciphertextForAuditor, permit); + } + + /** + * @notice Cancels a previously stored commitment before execution. + * @dev Marks the commitment as canceled so it cannot be executed. + * Reverts if the commitment does not exist, was already executed, or already canceled. + * Large storage fields may be cleared to save gas, but the status is retained for auditability. + * @param key Pool key identifying the Uniswap v4 pool this commitment belongs to. + * @param id Unique identifier of the commitment to cancel. + * @param zkProof ABI-encoded zkSNARK proof data (pA, pB, pC, pubSignals) to authorize the cancellation. + * Emits a {CommitmentCanceled} event. + */ + function cancelCommitment(PoolKey calldata key, uint256 id, bytes calldata zkProof) external { + Commitment storage c = commitments[key.toId()][id]; + if (c.status != CommitmentStatus.Active) { + revert CommitmentNotActive(id); + } + + (uint256[2] memory pA, uint256[2][2] memory pB, uint256[2] memory pC, uint256[5] memory pubSignals) = + abi.decode(zkProof, (uint256[2], uint256[2][2], uint256[2], uint256[5])); + + // Making sure we are executing the right commitment + bytes memory pubId = abi.encode(pubSignals[0], c.ciphertextForAuditor); + + if (keccak256(pubId) != bytes32(id)) { + revert CommitmentMismatch(pubId, id); + } + + bool privateVerifierOk = privateSwapIntentVerifier.verifyProof(pA, pB, pC, pubSignals); + if (!privateVerifierOk) { + revert InvalidPrivateSwapIntentProof(); } + + // We can cancel now + c.status = CommitmentStatus.Canceled; + delete c.ciphertextForAuditor; + delete c.permit; + emit CommitmentCanceled(id, msg.sender); } - function executeCommitment(PoolKey calldata key, uint256 id, bytes calldata data) + /** + * @notice Executes a previously stored encrypted swap commitment once its conditions are met. + * @dev Verifies a zkSNARK proof to ensure the executor knows the commitment’s plaintext + * and that the onchain commitment matches the provided proof. Uses ERC20 permit to + * pull tokens from the original sender, then executes a Uniswap v4 swap through + * the PoolManager. Marks the commitment as executed to prevent replay. + * @param key Pool key identifying the Uniswap v4 pool this commitment belongs to. + * @param id Unique identifier of the commitment to execute. + * @param zkProof ABI-encoded zkSNARK proof data (pA, pB, pC, pubSignals) to authorize the execution. + * @return delta Net balance delta returned from the swap execution. + * Emits a {CommitmentExecuted} event (if you add one). + */ + function executeCommitment(PoolKey calldata key, uint256 id, bytes calldata zkProof) external nonReentrant returns (BalanceDelta) @@ -157,7 +218,7 @@ contract RaylsHook is BaseHook, IUnlockCallback, ReentrancyGuard { } (uint256[2] memory pA, uint256[2][2] memory pB, uint256[2] memory pC, uint256[5] memory pubSignals) = - abi.decode(data, (uint256[2], uint256[2][2], uint256[2], uint256[5])); + abi.decode(zkProof, (uint256[2], uint256[2][2], uint256[2], uint256[5])); if (pubSignals[4] > block.timestamp) { revert CommitmentNotReady(pubSignals[4], block.timestamp); @@ -166,8 +227,7 @@ contract RaylsHook is BaseHook, IUnlockCallback, ReentrancyGuard { // Making sure we are executing the right commitment bytes memory pubId = abi.encode( pubSignals[0], // Poseidon hash of (amount, recipient, nonce) - commitment.ciphertext, - commitment.encKeyForAuditor + commitment.ciphertextForAuditor ); if (keccak256(pubId) != bytes32(id)) { @@ -203,7 +263,6 @@ contract RaylsHook is BaseHook, IUnlockCallback, ReentrancyGuard { key, SwapParams({ zeroForOne: zeroForOne, - // We provide a negative value here to signify an "exact input for output" swap amountSpecified: -int256(pubSignals[1]), // No slippage limits (maximum slippage possible) sqrtPriceLimitX96: zeroForOne ? TickMath.MIN_SQRT_PRICE + 1 : TickMath.MAX_SQRT_PRICE - 1 @@ -216,59 +275,6 @@ contract RaylsHook is BaseHook, IUnlockCallback, ReentrancyGuard { return delta; } - function storeCommitment( - PoolKey calldata key, - uint256 id, - bytes calldata ciphertext, - bytes calldata encKeyForAuditor, - bytes calldata permit - ) external { - if (commitments[key.toId()][id].status != CommitmentStatus.None) { - revert AlreadyExists(id); - } - - commitments[key.toId()][id] = Commitment({ - ciphertext: ciphertext, - encKeyForAuditor: encKeyForAuditor, - permit: permit, - status: CommitmentStatus.Active - }); - emit CommitmentStored(id, msg.sender, ciphertext, encKeyForAuditor, permit); - } - - function cancelCommitment(PoolKey calldata key, uint256 id, bytes calldata data) external { - Commitment storage c = commitments[key.toId()][id]; - if (c.status != CommitmentStatus.Active) { - revert CommitmentNotActive(id); - } - - (uint256[2] memory pA, uint256[2][2] memory pB, uint256[2] memory pC, uint256[5] memory pubSignals) = - abi.decode(data, (uint256[2], uint256[2][2], uint256[2], uint256[5])); - - // Making sure we are executing the right commitment - bytes memory pubId = abi.encode( - pubSignals[0], // Poseidon hash of (amount, recipient, nonce) - c.ciphertext, - c.encKeyForAuditor - ); - - if (keccak256(pubId) != bytes32(id)) { - revert CommitmentMismatch(pubId, id); - } - - bool privateVerifierOk = privateSwapIntentVerifier.verifyProof(pA, pB, pC, pubSignals); - if (!privateVerifierOk) { - revert InvalidPrivateSwapIntentProof(); - } - - // We can cancel now - c.status = CommitmentStatus.Canceled; - delete c.ciphertext; - delete c.encKeyForAuditor; - delete c.permit; - emit CommitmentCanceled(id, msg.sender); - } - function swapAndSettleBalances(PoolKey memory key, SwapParams memory params) internal returns (BalanceDelta) { // Conduct the swap inside the Pool Manager BalanceDelta delta = poolManager.swap(key, params, ""); @@ -327,4 +333,22 @@ contract RaylsHook is BaseHook, IUnlockCallback, ReentrancyGuard { v := byte(0, mload(add(sig, 96))) } } + + /** + * Determines the origin of the transaction. + * + * @param _sender The sender of the transaction + * + * @return origin_ The origin of the transaction + */ + function _determineOrigin(address _sender) internal returns (address origin_) { + // Set our default origin to the `tx.origin` + origin_ = tx.origin; + + // If the sender has a `msgSender` function, then we use that to determine the origin + (bool success, bytes memory data) = _sender.call(abi.encodeWithSignature("msgSender()")); + if (success && data.length >= 32) { + origin_ = abi.decode(data, (address)); + } + } } diff --git a/packages/foundry/test/RaylsHook.t.sol b/packages/foundry/test/RaylsHook.t.sol index a141c33..efaa031 100644 --- a/packages/foundry/test/RaylsHook.t.sol +++ b/packages/foundry/test/RaylsHook.t.sol @@ -196,27 +196,17 @@ contract RaylsHookTest is Test, Deployers { uint256 amountIn = pubSignals[1]; uint256 timestamp = pubSignals[4]; - string memory encKeyForAuditorStr = jsonEncryptedPayload.readString(".encKeyForAuditor"); - string memory ciphertextStr = jsonEncryptedPayload.readString(".ciphertext"); - - bytes memory encKeyForAuditor = RaylsHookHelper.hexStringToBytes(encKeyForAuditorStr); - bytes memory ciphertext = RaylsHookHelper.hexStringToBytes(ciphertextStr); - - uint256 id = uint256( - keccak256( - abi.encode( - pubSignals[0], // Poseidon hash of (amountIn, zeroForOne, sender, timestamp) - ciphertext, // AES-encrypted message optional - encKeyForAuditor // optional: can be empty bytes - ) - ) - ); + string memory ciphertextForAuditorStr = jsonEncryptedPayload.readString(".ciphertextForAuditor"); + + bytes memory ciphertextForAuditor = RaylsHookHelper.hexStringToBytes(ciphertextForAuditorStr); + + uint256 id = uint256(keccak256(abi.encode(pubSignals[0], ciphertextForAuditor))); vm.startPrank(proofSender, proofSender); bytes memory permitSignature = RaylsHookHelper.buildPermitSignature( vm, proofSenderPk, Currency.unwrap(currency0), timestamp, proofSender, address(hook), amountIn ); - hook.storeCommitment(poolKey, id, ciphertext, encKeyForAuditor, permitSignature); + hook.storeCommitment(poolKey, id, ciphertextForAuditor, permitSignature); // For now we just approve the swapRouter to spend the tokens // IERC20Minimal(Currency.unwrap(currency0)).approve(address(hook), amountIn); @@ -234,19 +224,16 @@ contract RaylsHookTest is Test, Deployers { assertEq(int256(delta.amount0()), -int256(amountIn)); vm.stopPrank(); - (bytes memory onChainCiphertext, bytes memory onChainEncKeyForAuditor,, RaylsHook.CommitmentStatus status) = - hook.commitments(poolKey.toId(), id); + (bytes memory onChainCiphertext,, RaylsHook.CommitmentStatus status) = hook.commitments(poolKey.toId(), id); assertEq(uint8(status), uint8(RaylsHook.CommitmentStatus.Executed)); - assertEq(onChainCiphertext, ciphertext); - assertEq(onChainEncKeyForAuditor, encKeyForAuditor); + assertEq(onChainCiphertext, ciphertextForAuditor); + string memory hexOnChainCiphertext = vm.toString(onChainCiphertext); - string memory hexOnChainEncKeyForAuditor = vm.toString(onChainEncKeyForAuditor); // Decrypt off-chain and use the private values to calculate the commitment ID // It must match to the one stored on-chain created by the circuit. - uint256 decryptedCommitmentId = - RaylsHookHelper.decryptCiphertext(vm, auditorPk, hexOnChainCiphertext, hexOnChainEncKeyForAuditor); + uint256 decryptedCommitmentId = RaylsHookHelper.decryptCiphertext(vm, auditorPk, hexOnChainCiphertext); // Check that commitmentId is correct assertEq(pubSignals[0], decryptedCommitmentId); diff --git a/packages/foundry/test/utils/RaylsHookHelper.sol b/packages/foundry/test/utils/RaylsHookHelper.sol index b5cae35..c8503a2 100644 --- a/packages/foundry/test/utils/RaylsHookHelper.sol +++ b/packages/foundry/test/utils/RaylsHookHelper.sol @@ -9,21 +9,18 @@ import { IERC20Permit } from "@openzeppelin/contracts/token/ERC20/extensions/IER library RaylsHookHelper { using stdJson for string; - function decryptCiphertext( - Vm vm, - string memory _auditorPk, - string memory ciphertext, - string memory encKeyForAuditor - ) public returns (uint256 output) { + function decryptCiphertext(Vm vm, string memory _auditorPk, string memory ciphertext) + public + returns (uint256 output) + { // You can implement this function to validate the encryption on-chain if needed. // For example, you might want to check the length of the ciphertext or other properties. // Enable FFI - string[] memory cmds = new string[](5); + string[] memory cmds = new string[](4); cmds[0] = "node"; cmds[1] = "../encryption/decrypt.cjs"; cmds[2] = _auditorPk; cmds[3] = cmds[3] = ciphertext; - cmds[4] = encKeyForAuditor; bytes memory result = vm.ffi(cmds); From fd2c13e9b384e55290cb45c503e44b4ca440eee7 Mon Sep 17 00:00:00 2001 From: Nuno Date: Fri, 12 Sep 2025 18:41:11 +0100 Subject: [PATCH 05/29] feat: removing comment --- packages/foundry/contracts/RaylsHook.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/foundry/contracts/RaylsHook.sol b/packages/foundry/contracts/RaylsHook.sol index ee5ff9e..a83cb38 100644 --- a/packages/foundry/contracts/RaylsHook.sol +++ b/packages/foundry/contracts/RaylsHook.sol @@ -226,7 +226,7 @@ contract RaylsHook is BaseHook, IUnlockCallback, ReentrancyGuard { // Making sure we are executing the right commitment bytes memory pubId = abi.encode( - pubSignals[0], // Poseidon hash of (amount, recipient, nonce) + pubSignals[0], // Poseidon hash commitment.ciphertextForAuditor ); From 68b2ba500bb10814f79300afe7f755c68c437fd7 Mon Sep 17 00:00:00 2001 From: Nuno Date: Mon, 15 Sep 2025 15:43:01 +0100 Subject: [PATCH 06/29] feat: adding more tests, reorganizing --- .gitignore | 6 +- packages/foundry/contracts/RaylsHook.sol | 43 ++--- packages/foundry/contracts/YourContract.sol | 88 --------- packages/foundry/foundry.toml | 2 +- packages/foundry/script/Deploy.s.sol | 4 - .../foundry/script/DeployYourContract.s.sol | 30 --- packages/foundry/test/RaylsHook.t.sol | 179 ++++++++++++++++-- packages/foundry/test/YourContract.t.sol | 17 -- .../foundry/test/utils/RaylsHookHelper.sol | 33 ++++ 9 files changed, 218 insertions(+), 184 deletions(-) delete mode 100644 packages/foundry/contracts/YourContract.sol delete mode 100644 packages/foundry/script/DeployYourContract.s.sol delete mode 100644 packages/foundry/test/YourContract.t.sol diff --git a/.gitignore b/.gitignore index 8bbbbd5..c6a3ff9 100644 --- a/.gitignore +++ b/.gitignore @@ -24,4 +24,8 @@ dist # artifacts packages/circom/artifacts -packages/foundry/inputs \ No newline at end of file +packages/foundry/inputs + +# coverage +packages/foundry/coverage +lcov.info \ No newline at end of file diff --git a/packages/foundry/contracts/RaylsHook.sol b/packages/foundry/contracts/RaylsHook.sol index a83cb38..8fb0f4d 100644 --- a/packages/foundry/contracts/RaylsHook.sol +++ b/packages/foundry/contracts/RaylsHook.sol @@ -44,14 +44,13 @@ contract RaylsHook is BaseHook, IUnlockCallback, ReentrancyGuard { event CommitmentStored(uint256 indexed id, address indexed sender, bytes, bytes); event CommitmentExecuted(uint256 indexed id, address indexed sender); - event CommitmentCanceled(uint256 indexed id, address indexed canceller); + event CommitmentCancelled(uint256 indexed id, address indexed canceller); // Errors error CommitmentMismatch(bytes pubId, uint256 expectedId); error CommitmentNotReady(uint256 notBefore, uint256 currentTime); error InvalidWallet(address provided, address expected); error InvalidSuitabilityProof(); - error AlreadyExecuted(uint256 id); error InvalidPrivateSwapIntentProof(); error AlreadyExists(uint256 id); error CommitmentNotActive(uint256 id); @@ -61,7 +60,7 @@ contract RaylsHook is BaseHook, IUnlockCallback, ReentrancyGuard { None, // default, not stored Active, // stored but not yet executed Executed, // executed successfully - Canceled // canceled by creator + Cancelled // canceled by creator } @@ -130,7 +129,7 @@ contract RaylsHook is BaseHook, IUnlockCallback, ReentrancyGuard { /** * @notice Stores a new encrypted swap commitment onchain. - * @dev Each commitment is uniquely identified by `id` under a specific pool key. + * @dev Each commitment is uniquely identified by a commitment `id` under a specific pool key. * Reverts if a commitment with the same `id` already exists. * The ciphertextForAuditor allows a designated auditor to decrypt the swap parameters offchain. * @param key Pool key identifying the Uniswap v4 pool this commitment belongs to. @@ -161,23 +160,23 @@ contract RaylsHook is BaseHook, IUnlockCallback, ReentrancyGuard { * Large storage fields may be cleared to save gas, but the status is retained for auditability. * @param key Pool key identifying the Uniswap v4 pool this commitment belongs to. * @param id Unique identifier of the commitment to cancel. - * @param zkProof ABI-encoded zkSNARK proof data (pA, pB, pC, pubSignals) to authorize the cancellation. - * Emits a {CommitmentCanceled} event. + * @param zkSnarkProof ABI-encoded zkSNARK proof data (pA, pB, pC, pubSignals) to authorize the cancellation. + * Emits a {CommitmentCancelled} event. */ - function cancelCommitment(PoolKey calldata key, uint256 id, bytes calldata zkProof) external { + function cancelCommitment(PoolKey calldata key, uint256 id, bytes calldata zkSnarkProof) external { Commitment storage c = commitments[key.toId()][id]; if (c.status != CommitmentStatus.Active) { revert CommitmentNotActive(id); } (uint256[2] memory pA, uint256[2][2] memory pB, uint256[2] memory pC, uint256[5] memory pubSignals) = - abi.decode(zkProof, (uint256[2], uint256[2][2], uint256[2], uint256[5])); + abi.decode(zkSnarkProof, (uint256[2], uint256[2][2], uint256[2], uint256[5])); // Making sure we are executing the right commitment - bytes memory pubId = abi.encode(pubSignals[0], c.ciphertextForAuditor); + bytes memory commitmentId = abi.encode(pubSignals[0], c.ciphertextForAuditor); - if (keccak256(pubId) != bytes32(id)) { - revert CommitmentMismatch(pubId, id); + if (keccak256(commitmentId) != bytes32(id)) { + revert CommitmentMismatch(commitmentId, id); } bool privateVerifierOk = privateSwapIntentVerifier.verifyProof(pA, pB, pC, pubSignals); @@ -186,25 +185,25 @@ contract RaylsHook is BaseHook, IUnlockCallback, ReentrancyGuard { } // We can cancel now - c.status = CommitmentStatus.Canceled; + c.status = CommitmentStatus.Cancelled; delete c.ciphertextForAuditor; delete c.permit; - emit CommitmentCanceled(id, msg.sender); + emit CommitmentCancelled(id, msg.sender); } /** * @notice Executes a previously stored encrypted swap commitment once its conditions are met. - * @dev Verifies a zkSNARK proof to ensure the executor knows the commitment’s plaintext - * and that the onchain commitment matches the provided proof. Uses ERC20 permit to - * pull tokens from the original sender, then executes a Uniswap v4 swap through + * @dev Verifies a zkSNARK proof to ensure the executor knows the swap commitment’s plaintext + * and that the onchain commitment id is the result of the provided proof + encryption for auditor. + * It uses ERC20 permit to pull tokens from the original sender, then executes a Uniswap v4 swap through * the PoolManager. Marks the commitment as executed to prevent replay. * @param key Pool key identifying the Uniswap v4 pool this commitment belongs to. * @param id Unique identifier of the commitment to execute. - * @param zkProof ABI-encoded zkSNARK proof data (pA, pB, pC, pubSignals) to authorize the execution. + * @param zkSnarkProof ABI-encoded zkSNARK proof data (pA, pB, pC, pubSignals) to authorize the execution. * @return delta Net balance delta returned from the swap execution. * Emits a {CommitmentExecuted} event (if you add one). */ - function executeCommitment(PoolKey calldata key, uint256 id, bytes calldata zkProof) + function executeCommitment(PoolKey calldata key, uint256 id, bytes calldata zkSnarkProof) external nonReentrant returns (BalanceDelta) @@ -218,20 +217,20 @@ contract RaylsHook is BaseHook, IUnlockCallback, ReentrancyGuard { } (uint256[2] memory pA, uint256[2][2] memory pB, uint256[2] memory pC, uint256[5] memory pubSignals) = - abi.decode(zkProof, (uint256[2], uint256[2][2], uint256[2], uint256[5])); + abi.decode(zkSnarkProof, (uint256[2], uint256[2][2], uint256[2], uint256[5])); if (pubSignals[4] > block.timestamp) { revert CommitmentNotReady(pubSignals[4], block.timestamp); } // Making sure we are executing the right commitment - bytes memory pubId = abi.encode( + bytes memory commitmentId = abi.encode( pubSignals[0], // Poseidon hash commitment.ciphertextForAuditor ); - if (keccak256(pubId) != bytes32(id)) { - revert CommitmentMismatch(pubId, id); + if (keccak256(commitmentId) != bytes32(id)) { + revert CommitmentMismatch(commitmentId, id); } bool privateVerifierOk = privateSwapIntentVerifier.verifyProof(pA, pB, pC, pubSignals); diff --git a/packages/foundry/contracts/YourContract.sol b/packages/foundry/contracts/YourContract.sol deleted file mode 100644 index b653427..0000000 --- a/packages/foundry/contracts/YourContract.sol +++ /dev/null @@ -1,88 +0,0 @@ -//SPDX-License-Identifier: MIT -pragma solidity >=0.8.0 <0.9.0; - -// Useful for debugging. Remove when deploying to a live network. -import "forge-std/console.sol"; - -// Use openzeppelin to inherit battle-tested implementations (ERC20, ERC721, etc) -// import "@openzeppelin/contracts/access/Ownable.sol"; - -/** - * A smart contract that allows changing a state variable of the contract and tracking the changes - * It also allows the owner to withdraw the Ether in the contract - * @author BuidlGuidl - */ -contract YourContract { - // State Variables - address public immutable owner; - string public greeting = "Building Unstoppable Apps!!!"; - bool public premium = false; - uint256 public totalCounter = 0; - mapping(address => uint256) public userGreetingCounter; - address public delegate; - - // Events: a way to emit log statements from smart contract that can be listened to by external parties - event GreetingChange(address indexed greetingSetter, string newGreeting, bool premium, uint256 value); - - event DelegateChanged(address indexed newDelegate, address indexed oldDelegate); - - // Constructor: Called once on contract deployment - // Check packages/foundry/deploy/Deploy.s.sol - constructor(address _owner) { - owner = _owner; - } - - // Modifier: used to define a set of rules that must be met before or after a function is executed - // Check the withdraw() function - modifier isOwner() { - // msg.sender: predefined variable that represents address of the account that called the current function - require(msg.sender == owner, "Not the Owner"); - _; - } - - function setDelegate(address _delegate) public isOwner { - address oldDelegate = delegate; - delegate = _delegate; - emit DelegateChanged(_delegate, oldDelegate); - } - - /** - * Function that allows anyone to change the state variable "greeting" of the contract and increase the counters - * - * @param _newGreeting (string memory) - new greeting to save on the contract - */ - function setGreeting(string memory _newGreeting) public payable { - // Print data to the anvil chain console. Remove when deploying to a live network. - - console.logString("Setting new greeting"); - console.logString(_newGreeting); - - greeting = _newGreeting; - totalCounter += 1; - userGreetingCounter[msg.sender] += 1; - - // msg.value: built-in global variable that represents the amount of ether sent with the transaction - if (msg.value > 0) { - premium = true; - } else { - premium = false; - } - - // emit: keyword used to trigger an event - emit GreetingChange(msg.sender, _newGreeting, msg.value > 0, msg.value); - } - - /** - * Function that allows the owner to withdraw all the Ether in the contract - * The function can only be called by the owner of the contract as defined by the isOwner modifier - */ - function withdraw() public isOwner { - (bool success,) = owner.call{ value: address(this).balance }(""); - require(success, "Failed to send Ether"); - } - - /** - * Function that allows the contract to receive ETH - */ - receive() external payable { } -} diff --git a/packages/foundry/foundry.toml b/packages/foundry/foundry.toml index bcfd5e4..0ac6812 100644 --- a/packages/foundry/foundry.toml +++ b/packages/foundry/foundry.toml @@ -6,11 +6,11 @@ fs_permissions = [{ access = "read-write", path = "./"}] solc_version = '0.8.26' evm_version = "cancun" # hard fork that enabled EIP-1153 +optimizer = true optimizer_runs = 800 via_ir = true ffi = true - [rpc_endpoints] default_network = "http://127.0.0.1:8545" diff --git a/packages/foundry/script/Deploy.s.sol b/packages/foundry/script/Deploy.s.sol index 2ad973b..97945b6 100644 --- a/packages/foundry/script/Deploy.s.sol +++ b/packages/foundry/script/Deploy.s.sol @@ -2,7 +2,6 @@ pragma solidity ^0.8.19; import "./DeployHelpers.s.sol"; -import { DeployYourContract } from "./DeployYourContract.s.sol"; import { DeploySuitabilityVerifier } from "./04_DeploySuitabilityVerifier.s.sol"; /** @@ -16,9 +15,6 @@ contract DeployScript is ScaffoldETHDeploy { // Deploys all your contracts sequentially // Add new deployments here when needed - DeployYourContract deployYourContract = new DeployYourContract(); - deployYourContract.run(); - DeploySuitabilityVerifier deploySuitabilityVerifier = new DeploySuitabilityVerifier(); deploySuitabilityVerifier.run(); diff --git a/packages/foundry/script/DeployYourContract.s.sol b/packages/foundry/script/DeployYourContract.s.sol deleted file mode 100644 index cafa004..0000000 --- a/packages/foundry/script/DeployYourContract.s.sol +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -import "./DeployHelpers.s.sol"; -import "../contracts/YourContract.sol"; - -/** - * @notice Deploy script for YourContract contract - * @dev Inherits ScaffoldETHDeploy which: - * - Includes forge-std/Script.sol for deployment - * - Includes ScaffoldEthDeployerRunner modifier - * - Provides `deployer` variable - * Example: - * yarn deploy --file DeployYourContract.s.sol # local anvil chain - * yarn deploy --file DeployYourContract.s.sol --network optimism # live network (requires keystore) - */ -contract DeployYourContract is ScaffoldETHDeploy { - /** - * @dev Deployer setup based on `ETH_KEYSTORE_ACCOUNT` in `.env`: - * - "scaffold-eth-default": Uses Anvil's account #9 (0xa0Ee7A142d267C1f36714E4a8F75612F20a79720), no password prompt - * - "scaffold-eth-custom": requires password used while creating keystore - * - * Note: Must use ScaffoldEthDeployerRunner modifier to: - * - Setup correct `deployer` account and fund it - * - Export contract addresses & ABIs to `nextjs` packages - */ - function run() external ScaffoldEthDeployerRunner { - new YourContract(0xb5CD58d8d8D3A6138d5a7A68a3E51E1fCC63b3a3); - } -} diff --git a/packages/foundry/test/RaylsHook.t.sol b/packages/foundry/test/RaylsHook.t.sol index efaa031..5e07eeb 100644 --- a/packages/foundry/test/RaylsHook.t.sol +++ b/packages/foundry/test/RaylsHook.t.sol @@ -129,6 +129,31 @@ contract RaylsHookTest is Test, Deployers { currency0.transfer(invalidProofSender, 1e18); } + function testSwapRevertsWithInvalidProof() public { + (uint256[2] memory pA, uint256[2][2] memory pB, uint256[2] memory pC, uint256[5] memory pubSignals) = + RaylsHookHelper.loadSuitabilityProof(jsonSuitability); + + uint256[2] memory fakePA = [uint256(1), pA[1]]; + bytes memory fakeProofData = abi.encode(fakePA, pB, pC, pubSignals); + + uint256 amountIn = 1e16; + vm.startPrank(proofSender, proofSender); + IERC20Minimal(Currency.unwrap(currency0)).approve(address(swapRouter), amountIn); + + vm.expectRevert(); + swapRouter.swapExactTokensForTokens({ + amountIn: amountIn, + amountOutMin: 0, + zeroForOne: true, + poolKey: poolKey, + hookData: fakeProofData, + receiver: address(proofSender), + deadline: block.timestamp + 1 + }); + + vm.stopPrank(); + } + function testVerifyProofInBeforeSwap() public { (uint256[2] memory pA, uint256[2][2] memory pB, uint256[2] memory pC, uint256[5] memory pubSignals) = RaylsHookHelper.loadSuitabilityProof(jsonSuitability); @@ -153,12 +178,13 @@ contract RaylsHookTest is Test, Deployers { vm.startPrank(proofSender, proofSender); IERC20Minimal(Currency.unwrap(currency0)).approve(address(swapRouter), amountIn); + // Sucessful swap BalanceDelta swapDelta = swapRouter.swapExactTokensForTokens({ amountIn: amountIn, amountOutMin: 0, zeroForOne: true, poolKey: poolKey, - hookData: proofData, // pass proof here + hookData: proofData, receiver: address(proofSender), deadline: block.timestamp + 1 }); @@ -176,7 +202,7 @@ contract RaylsHookTest is Test, Deployers { // If your verifier is public in the hook contract, call it directly: bool ok = suitabilityVerifier.verifyProof(pA, pB, pC, pubSignals); - assertTrue(ok); // this will fail if verifyProof==false + assertTrue(ok); } function testPrivateSwapIntentVerifier() public view { @@ -185,43 +211,76 @@ contract RaylsHookTest is Test, Deployers { // If your verifier is public in the hook contract, call it directly: bool ok = privateSwapIntentVerifier.verifyProof(pA, pB, pC, pubSignals); - assertTrue(ok); // this will fail if verifyProof==false + assertTrue(ok); } function testAPrivateSwap() public { - (uint256[2] memory pA, uint256[2][2] memory pB, uint256[2] memory pC, uint256[5] memory pubSignals) = - RaylsHookHelper.loadPrivateSwapIntentProof(jsonPrivateSwap); + // Get the proof and public signals from the json file + (uint256 amountIn, uint256 timestamp, uint256 poseidonHash, bytes memory proofData) = + RaylsHookHelper.getPublicSignalsFromPrivateSwapIntentProof(jsonPrivateSwap, false, false); - bytes memory proofData = abi.encode(pA, pB, pC, pubSignals); - uint256 amountIn = pubSignals[1]; - uint256 timestamp = pubSignals[4]; - - string memory ciphertextForAuditorStr = jsonEncryptedPayload.readString(".ciphertextForAuditor"); + // Get the ciphertext for the auditor from the json file + bytes memory ciphertextForAuditor = RaylsHookHelper.getJsonCiphertext(jsonEncryptedPayload); - bytes memory ciphertextForAuditor = RaylsHookHelper.hexStringToBytes(ciphertextForAuditorStr); - - uint256 id = uint256(keccak256(abi.encode(pubSignals[0], ciphertextForAuditor))); + // Calculate the commitment ID off-chain using both the ZK Snark Poseidon Hash and the ciphertext + uint256 id = uint256(keccak256(abi.encode(poseidonHash, ciphertextForAuditor))); + // Store the commitment on-chain vm.startPrank(proofSender, proofSender); + // Build the permit signature to approve the hook to spend the tokens bytes memory permitSignature = RaylsHookHelper.buildPermitSignature( vm, proofSenderPk, Currency.unwrap(currency0), timestamp, proofSender, address(hook), amountIn ); + + // Call the hook to store the commitment + hook.storeCommitment(poolKey, id, ciphertextForAuditor, permitSignature); + + // Revert if already exsits + bytes memory expectedRevert = abi.encodeWithSelector(RaylsHook.AlreadyExists.selector, id); + vm.expectRevert(expectedRevert); hook.storeCommitment(poolKey, id, ciphertextForAuditor, permitSignature); // For now we just approve the swapRouter to spend the tokens // IERC20Minimal(Currency.unwrap(currency0)).approve(address(hook), amountIn); // Move time forward but not enough to be able to execute the commitment - vm.warp(pubSignals[4] - 1); - bytes memory expectedRevert = - abi.encodeWithSelector(RaylsHook.CommitmentNotReady.selector, pubSignals[4], block.timestamp); + vm.warp(timestamp - 1); + expectedRevert = abi.encodeWithSelector(RaylsHook.CommitmentNotReady.selector, timestamp, block.timestamp); vm.expectRevert(expectedRevert); hook.executeCommitment(poolKey, id, proofData); // Move time forward to be able to execute the commitment - vm.warp(pubSignals[4]); + vm.warp(timestamp); + + // Revert if commitementId is incorrect and doesnt match the proof + uint256 fakeId = 123456; + expectedRevert = abi.encodeWithSelector(RaylsHook.CommitmentNotFound.selector, fakeId); + vm.expectRevert(expectedRevert); + hook.executeCommitment(poolKey, fakeId, proofData); + + // Revert if the public signal poseidon hash is invalid + (,, uint256 fakePoseidonHash, bytes memory fakePoseidonHashProof) = + RaylsHookHelper.getPublicSignalsFromPrivateSwapIntentProof(jsonPrivateSwap, false, true); + bytes memory fakeCommitmentId = abi.encode(fakePoseidonHash, ciphertextForAuditor); + expectedRevert = abi.encodeWithSelector(RaylsHook.CommitmentMismatch.selector, fakeCommitmentId, id); + vm.expectRevert(expectedRevert); + hook.executeCommitment(poolKey, id, fakePoseidonHashProof); + + // Revert if the proof is invalid + (,,, bytes memory fakeProof) = + RaylsHookHelper.getPublicSignalsFromPrivateSwapIntentProof(jsonPrivateSwap, true, false); + expectedRevert = abi.encodeWithSelector(RaylsHook.InvalidPrivateSwapIntentProof.selector); + vm.expectRevert(expectedRevert); + hook.executeCommitment(poolKey, id, fakeProof); + + // Execute the commitment successfully BalanceDelta delta = hook.executeCommitment(poolKey, id, proofData); assertEq(int256(delta.amount0()), -int256(amountIn)); + + // Revert if we want to execute it again + expectedRevert = abi.encodeWithSelector(RaylsHook.CommitmentNotActive.selector, id); + vm.expectRevert(expectedRevert); + hook.executeCommitment(poolKey, id, proofData); vm.stopPrank(); (bytes memory onChainCiphertext,, RaylsHook.CommitmentStatus status) = hook.commitments(poolKey.toId(), id); @@ -233,12 +292,90 @@ contract RaylsHookTest is Test, Deployers { // Decrypt off-chain and use the private values to calculate the commitment ID // It must match to the one stored on-chain created by the circuit. - uint256 decryptedCommitmentId = RaylsHookHelper.decryptCiphertext(vm, auditorPk, hexOnChainCiphertext); + uint256 decryptedPoseidonHash = RaylsHookHelper.decryptCiphertext(vm, auditorPk, hexOnChainCiphertext); // Check that commitmentId is correct - assertEq(pubSignals[0], decryptedCommitmentId); + assertEq(poseidonHash, decryptedPoseidonHash); + } - // assertEq(selector, IHooks.beforeSwap.selector, "selector mismatch"); - // delta and fee are placeholder, assert if needed + /** + * Loads the poseidon hash from the ZK Snark proof, decrypts the ciphertext from the encrypted payload and checks that they are equal. + * This simulates the auditor decrypting the ciphertext and checking that the commitment ID is correct. + * Which proves that the values in the encrypted payload: amountIn, zeroForOne, sender, timestamp are correct. + */ + function test_EncryptedCommitmentForAuditor() public { + // Get the proof and public signals from the json file + (,, uint256 poseidonHash,) = + RaylsHookHelper.getPublicSignalsFromPrivateSwapIntentProof(jsonPrivateSwap, false, false); + + // Get the ciphertext for the auditor from the json file + bytes memory ciphertextForAuditor = RaylsHookHelper.getJsonCiphertext(jsonEncryptedPayload); + string memory hexOnChainCiphertext = vm.toString(ciphertextForAuditor); + + // Decrypt off-chain and use the poseidonHash for comparison + // It must match to the one stored on-chain created by the circuit. + uint256 decryptedPoseidonHash = RaylsHookHelper.decryptCiphertext(vm, auditorPk, hexOnChainCiphertext); + + // Check that hashes are equal + assertEq(poseidonHash, decryptedPoseidonHash); + } + + function test_cancelCommitment() public { + // Get the proof and public signals from the json file + (uint256 amountIn, uint256 timestamp, uint256 poseidonHash, bytes memory proofData) = + RaylsHookHelper.getPublicSignalsFromPrivateSwapIntentProof(jsonPrivateSwap, false, false); + + // Get the ciphertext for the auditor from the json file + bytes memory ciphertextForAuditor = RaylsHookHelper.getJsonCiphertext(jsonEncryptedPayload); + + // Calculate the commitment ID off-chain using both the ZK Snark Poseidon Hash and the ciphertext + uint256 id = uint256(keccak256(abi.encode(poseidonHash, ciphertextForAuditor))); + + // Store the commitment on-chain + vm.startPrank(proofSender, proofSender); + // Build the permit signature to approve the hook to spend the tokens + bytes memory permitSignature = RaylsHookHelper.buildPermitSignature( + vm, proofSenderPk, Currency.unwrap(currency0), timestamp, proofSender, address(hook), amountIn + ); + + // Call the hook to store the commitment + hook.storeCommitment(poolKey, id, ciphertextForAuditor, permitSignature); + + // Revert if the public signal poseidon hash is invalid + (,, uint256 fakePoseidonHash, bytes memory fakePoseidonHashProof) = + RaylsHookHelper.getPublicSignalsFromPrivateSwapIntentProof(jsonPrivateSwap, false, true); + bytes memory fakeCommitmentId = abi.encode(fakePoseidonHash, ciphertextForAuditor); + bytes memory expectedRevert = + abi.encodeWithSelector(RaylsHook.CommitmentMismatch.selector, fakeCommitmentId, id); + vm.expectRevert(expectedRevert); + hook.cancelCommitment(poolKey, id, fakePoseidonHashProof); + + // Revert if the proof is invalid + (,,, bytes memory fakeProof) = + RaylsHookHelper.getPublicSignalsFromPrivateSwapIntentProof(jsonPrivateSwap, true, false); + expectedRevert = abi.encodeWithSelector(RaylsHook.InvalidPrivateSwapIntentProof.selector); + vm.expectRevert(expectedRevert); + hook.cancelCommitment(poolKey, id, fakeProof); + + // Cancel it before it can be executed + hook.cancelCommitment(poolKey, id, proofData); + + // Cancel it again shoule revvert + expectedRevert = abi.encodeWithSelector(RaylsHook.CommitmentNotActive.selector, id); + vm.expectRevert(expectedRevert); + hook.cancelCommitment(poolKey, id, proofData); + + // Move time forward to be able to execute the commitment + vm.warp(timestamp + 1); + + // Revert if we try to execute a cancelled commitment + expectedRevert = abi.encodeWithSelector(RaylsHook.CommitmentNotActive.selector, id); + vm.expectRevert(expectedRevert); + hook.executeCommitment(poolKey, id, proofData); + vm.stopPrank(); + + (,, RaylsHook.CommitmentStatus status) = hook.commitments(poolKey.toId(), id); + + assertEq(uint8(status), uint8(RaylsHook.CommitmentStatus.Cancelled)); } } diff --git a/packages/foundry/test/YourContract.t.sol b/packages/foundry/test/YourContract.t.sol deleted file mode 100644 index 5e6ff10..0000000 --- a/packages/foundry/test/YourContract.t.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; - -import "forge-std/Test.sol"; -import "../contracts/YourContract.sol"; - -contract YourContractTest is Test { - YourContract public yourContract; - - function setUp() public { - yourContract = new YourContract(vm.addr(1)); - } - - function testMessageOnDeployment() public view { - require(keccak256(bytes(yourContract.greeting())) == keccak256("Building Unstoppable Apps!!!")); - } -} diff --git a/packages/foundry/test/utils/RaylsHookHelper.sol b/packages/foundry/test/utils/RaylsHookHelper.sol index c8503a2..2b639a4 100644 --- a/packages/foundry/test/utils/RaylsHookHelper.sol +++ b/packages/foundry/test/utils/RaylsHookHelper.sol @@ -178,4 +178,37 @@ library RaylsHookHelper { (uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, digest); return abi.encodePacked(r, s, v); } + + function getPublicSignalsFromPrivateSwapIntentProof(string memory json, bool fakePa, bool fakeHash) + public + pure + returns (uint256 amountIn, uint256 timestamp, uint256 poseidonHash, bytes memory proofData) + { + (uint256[2] memory pA, uint256[2][2] memory pB, uint256[2] memory pC, uint256[5] memory pubSignals) = + loadPrivateSwapIntentProof(json); + + if (fakePa) { + // Change the poseidon hash to an incorrect one + pA = [uint256(1), pA[1]]; + } + + if (fakeHash) { + // Change the poseidon hash to an incorrect one + pubSignals[0] = 1; + } + + proofData = abi.encode(pA, pB, pC, pubSignals); + poseidonHash = pubSignals[0]; + amountIn = pubSignals[1]; + timestamp = pubSignals[4]; + } + + function getJsonCiphertext(string memory _jsonEncryptedPayload) + public + pure + returns (bytes memory ciphertextForAuditor) + { + string memory ciphertextForAuditorStr = _jsonEncryptedPayload.readString(".ciphertextForAuditor"); + ciphertextForAuditor = RaylsHookHelper.hexStringToBytes(ciphertextForAuditorStr); + } } From 74b398a5be0485b451330db2c5d60017e4f86ba5 Mon Sep 17 00:00:00 2001 From: Nuno Date: Mon, 15 Sep 2025 15:55:03 +0100 Subject: [PATCH 07/29] feat: removing scafold unneeded file --- packages/foundry/script/00_DeployHook.s.sol | 30 --------------------- 1 file changed, 30 deletions(-) delete mode 100644 packages/foundry/script/00_DeployHook.s.sol diff --git a/packages/foundry/script/00_DeployHook.s.sol b/packages/foundry/script/00_DeployHook.s.sol deleted file mode 100644 index 8a84674..0000000 --- a/packages/foundry/script/00_DeployHook.s.sol +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.26; - -import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; -import {HookMiner} from "@uniswap/v4-periphery/src/utils/HookMiner.sol"; - -import {BaseScript} from "./base/BaseScript.sol"; - -import {Counter} from "../contracts/Counter.sol"; - -/// @notice Mines the address and deploys the Counter.sol Hook contract -contract DeployHookScript is BaseScript { - function run() public { - uint160 flags = uint160( - Hooks.BEFORE_SWAP_FLAG | Hooks.AFTER_SWAP_FLAG | Hooks.BEFORE_ADD_LIQUIDITY_FLAG - | Hooks.BEFORE_REMOVE_LIQUIDITY_FLAG - ); - - // Mine a salt that will produce a hook address with the correct flags - bytes memory constructorArgs = abi.encode(poolManager); - (address hookAddress, bytes32 salt) = - HookMiner.find(CREATE2_FACTORY, flags, type(Counter).creationCode, constructorArgs); - - vm.startBroadcast(); - Counter counter = new Counter{salt: salt}(poolManager); - vm.stopBroadcast(); - - require(address(counter) == hookAddress, "DeployHookScript: Hook Address Mismatch"); - } -} \ No newline at end of file From cca064b7b18051c6ac27eeeaff0d9cb1f2c4eb0e Mon Sep 17 00:00:00 2001 From: Nuno Date: Mon, 15 Sep 2025 16:29:24 +0100 Subject: [PATCH 08/29] feat: adding correct example inputs for tests to pass --- packages/circom/package.json | 2 +- .../scripts/Suitability_input.example.json | 2 +- packages/circom/scripts/Suitability_input.json | 18 ++++++++---------- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/packages/circom/package.json b/packages/circom/package.json index 62f390e..e5945d0 100644 --- a/packages/circom/package.json +++ b/packages/circom/package.json @@ -1,5 +1,5 @@ { - "name": "suitability-zk", + "name": "rayls-hook-circom", "version": "1.0.0", "description": "Zero-Knowledge Suitability Assessment System", "main": "index.js", diff --git a/packages/circom/scripts/Suitability_input.example.json b/packages/circom/scripts/Suitability_input.example.json index 568b45b..6560639 100644 --- a/packages/circom/scripts/Suitability_input.example.json +++ b/packages/circom/scripts/Suitability_input.example.json @@ -4,7 +4,7 @@ "answer3": 1, "answer4": 2, "answer5": 3, - "wallet": "0x1234567890AbcdEF1234567890aBcdef12345678", + "wallet": "0x70997970C51812dc3A010C7d01b50e0d17dc79C8", "thresholdScaled": 20, "isSuitablePub": 1 } diff --git a/packages/circom/scripts/Suitability_input.json b/packages/circom/scripts/Suitability_input.json index d1965f0..6560639 100644 --- a/packages/circom/scripts/Suitability_input.json +++ b/packages/circom/scripts/Suitability_input.json @@ -1,12 +1,10 @@ { - "answer1": 3, - "answer2": 2, - "answer3": 1, - "answer4": 2, - "answer5": 3, - "wallet": "0x1234567890AbcdEF1234567890aBcdef12345678", - "thresholdScaled": 20, - "isSuitablePub": 1 + "answer1": 3, + "answer2": 2, + "answer3": 1, + "answer4": 2, + "answer5": 3, + "wallet": "0x70997970C51812dc3A010C7d01b50e0d17dc79C8", + "thresholdScaled": 20, + "isSuitablePub": 1 } - - \ No newline at end of file From 8d694fed5fc41842ecacefa4148c5285abf0db8c Mon Sep 17 00:00:00 2001 From: Nuno Date: Mon, 15 Sep 2025 17:06:25 +0100 Subject: [PATCH 09/29] feat: adding struct in tests --- packages/foundry/package.json | 1 + packages/foundry/test/RaylsHook.t.sol | 75 +++++++++++-------- .../foundry/test/utils/RaylsHookHelper.sol | 17 +++-- 3 files changed, 57 insertions(+), 36 deletions(-) diff --git a/packages/foundry/package.json b/packages/foundry/package.json index be52fdd..b5dbdd4 100644 --- a/packages/foundry/package.json +++ b/packages/foundry/package.json @@ -9,6 +9,7 @@ "account:reveal-pk": "node scripts-js/revealPK.js", "chain": "make chain", "clean": "forge clean", + "coverage": "forge coverage --ir-minimum --report lcov && genhtml lcov.info --output-directory coverage && open coverage/index.html", "compile": "make compile", "deploy": "node scripts-js/parseArgs.js", "flatten": "make flatten", diff --git a/packages/foundry/test/RaylsHook.t.sol b/packages/foundry/test/RaylsHook.t.sol index 1a283da..c658d26 100644 --- a/packages/foundry/test/RaylsHook.t.sol +++ b/packages/foundry/test/RaylsHook.t.sol @@ -216,20 +216,26 @@ contract RaylsHookTest is Test, Deployers { function testAPrivateSwap() public { // Get the proof and public signals from the json file - (uint256 amountIn, uint256 timestamp, uint256 poseidonHash, bytes memory proofData) = + RaylsHookHelper.PrivateSwapPublic memory proofCorrect = RaylsHookHelper.getPublicSignalsFromPrivateSwapIntentProof(jsonPrivateSwap, false, false); // Get the ciphertext for the auditor from the json file bytes memory ciphertextForAuditor = RaylsHookHelper.getJsonCiphertext(jsonEncryptedPayload); // Calculate the commitment ID off-chain using both the ZK Snark Poseidon Hash and the ciphertext - uint256 id = uint256(keccak256(abi.encode(poseidonHash, ciphertextForAuditor))); + uint256 id = uint256(keccak256(abi.encode(proofCorrect.poseidonHash, ciphertextForAuditor))); // Store the commitment on-chain vm.startPrank(proofSender, proofSender); // Build the permit signature to approve the hook to spend the tokens bytes memory permitSignature = RaylsHookHelper.buildPermitSignature( - vm, proofSenderPk, Currency.unwrap(currency0), timestamp, proofSender, address(hook), amountIn + vm, + proofSenderPk, + Currency.unwrap(currency0), + proofCorrect.timestamp, + proofSender, + address(hook), + proofCorrect.amountIn ); // Call the hook to store the commitment @@ -244,43 +250,44 @@ contract RaylsHookTest is Test, Deployers { // IERC20Minimal(Currency.unwrap(currency0)).approve(address(hook), amountIn); // Move time forward but not enough to be able to execute the commitment - vm.warp(timestamp - 1); - expectedRevert = abi.encodeWithSelector(RaylsHook.CommitmentNotReady.selector, timestamp, block.timestamp); + vm.warp(proofCorrect.timestamp - 1); + expectedRevert = + abi.encodeWithSelector(RaylsHook.CommitmentNotReady.selector, proofCorrect.timestamp, block.timestamp); vm.expectRevert(expectedRevert); - hook.executeCommitment(poolKey, id, proofData); + hook.executeCommitment(poolKey, id, proofCorrect.proofData); // Move time forward to be able to execute the commitment - vm.warp(timestamp); + vm.warp(proofCorrect.timestamp); // Revert if commitementId is incorrect and doesnt match the proof uint256 fakeId = 123456; expectedRevert = abi.encodeWithSelector(RaylsHook.CommitmentNotFound.selector, fakeId); vm.expectRevert(expectedRevert); - hook.executeCommitment(poolKey, fakeId, proofData); + hook.executeCommitment(poolKey, fakeId, proofCorrect.proofData); // Revert if the public signal poseidon hash is invalid - (,, uint256 fakePoseidonHash, bytes memory fakePoseidonHashProof) = + RaylsHookHelper.PrivateSwapPublic memory proofWithWrongHash = RaylsHookHelper.getPublicSignalsFromPrivateSwapIntentProof(jsonPrivateSwap, false, true); - bytes memory fakeCommitmentId = abi.encode(fakePoseidonHash, ciphertextForAuditor); + bytes memory fakeCommitmentId = abi.encode(proofWithWrongHash.poseidonHash, ciphertextForAuditor); expectedRevert = abi.encodeWithSelector(RaylsHook.CommitmentMismatch.selector, fakeCommitmentId, id); vm.expectRevert(expectedRevert); - hook.executeCommitment(poolKey, id, fakePoseidonHashProof); + hook.executeCommitment(poolKey, id, proofWithWrongHash.proofData); // Revert if the proof is invalid - (,,, bytes memory fakeProof) = + RaylsHookHelper.PrivateSwapPublic memory proofWithWrongPA = RaylsHookHelper.getPublicSignalsFromPrivateSwapIntentProof(jsonPrivateSwap, true, false); expectedRevert = abi.encodeWithSelector(RaylsHook.InvalidPrivateSwapIntentProof.selector); vm.expectRevert(expectedRevert); - hook.executeCommitment(poolKey, id, fakeProof); + hook.executeCommitment(poolKey, id, proofWithWrongPA.proofData); // Execute the commitment successfully - BalanceDelta delta = hook.executeCommitment(poolKey, id, proofData); - assertEq(int256(delta.amount0()), -int256(amountIn)); + BalanceDelta delta = hook.executeCommitment(poolKey, id, proofCorrect.proofData); + assertEq(int256(delta.amount0()), -int256(proofCorrect.amountIn)); // Revert if we want to execute it again expectedRevert = abi.encodeWithSelector(RaylsHook.CommitmentNotActive.selector, id); vm.expectRevert(expectedRevert); - hook.executeCommitment(poolKey, id, proofData); + hook.executeCommitment(poolKey, id, proofCorrect.proofData); vm.stopPrank(); (bytes memory onChainCiphertext,, RaylsHook.CommitmentStatus status) = hook.commitments(poolKey.toId(), id); @@ -295,7 +302,7 @@ contract RaylsHookTest is Test, Deployers { uint256 decryptedPoseidonHash = RaylsHookHelper.decryptCiphertext(vm, auditorPk, hexOnChainCiphertext); // Check that commitmentId is correct - assertEq(poseidonHash, decryptedPoseidonHash); + assertEq(proofCorrect.poseidonHash, decryptedPoseidonHash); } /** @@ -305,7 +312,7 @@ contract RaylsHookTest is Test, Deployers { */ function test_EncryptedCommitmentForAuditor() public { // Get the proof and public signals from the json file - (,, uint256 poseidonHash,) = + RaylsHookHelper.PrivateSwapPublic memory proofCorrect = RaylsHookHelper.getPublicSignalsFromPrivateSwapIntentProof(jsonPrivateSwap, false, false); // Get the ciphertext for the auditor from the json file @@ -317,61 +324,67 @@ contract RaylsHookTest is Test, Deployers { uint256 decryptedPoseidonHash = RaylsHookHelper.decryptCiphertext(vm, auditorPk, hexOnChainCiphertext); // Check that hashes are equal - assertEq(poseidonHash, decryptedPoseidonHash); + assertEq(proofCorrect.poseidonHash, decryptedPoseidonHash); } function test_cancelCommitment() public { // Get the proof and public signals from the json file - (uint256 amountIn, uint256 timestamp, uint256 poseidonHash, bytes memory proofData) = + RaylsHookHelper.PrivateSwapPublic memory proofCorrect = RaylsHookHelper.getPublicSignalsFromPrivateSwapIntentProof(jsonPrivateSwap, false, false); // Get the ciphertext for the auditor from the json file bytes memory ciphertextForAuditor = RaylsHookHelper.getJsonCiphertext(jsonEncryptedPayload); // Calculate the commitment ID off-chain using both the ZK Snark Poseidon Hash and the ciphertext - uint256 id = uint256(keccak256(abi.encode(poseidonHash, ciphertextForAuditor))); + uint256 id = uint256(keccak256(abi.encode(proofCorrect.poseidonHash, ciphertextForAuditor))); // Store the commitment on-chain vm.startPrank(proofSender, proofSender); // Build the permit signature to approve the hook to spend the tokens bytes memory permitSignature = RaylsHookHelper.buildPermitSignature( - vm, proofSenderPk, Currency.unwrap(currency0), timestamp, proofSender, address(hook), amountIn + vm, + proofSenderPk, + Currency.unwrap(currency0), + proofCorrect.timestamp, + proofSender, + address(hook), + proofCorrect.amountIn ); // Call the hook to store the commitment hook.storeCommitment(poolKey, id, ciphertextForAuditor, permitSignature); // Revert if the public signal poseidon hash is invalid - (,, uint256 fakePoseidonHash, bytes memory fakePoseidonHashProof) = + RaylsHookHelper.PrivateSwapPublic memory proofWithWrongHash = RaylsHookHelper.getPublicSignalsFromPrivateSwapIntentProof(jsonPrivateSwap, false, true); - bytes memory fakeCommitmentId = abi.encode(fakePoseidonHash, ciphertextForAuditor); + bytes memory fakeCommitmentId = abi.encode(proofWithWrongHash.poseidonHash, ciphertextForAuditor); bytes memory expectedRevert = abi.encodeWithSelector(RaylsHook.CommitmentMismatch.selector, fakeCommitmentId, id); vm.expectRevert(expectedRevert); - hook.cancelCommitment(poolKey, id, fakePoseidonHashProof); + hook.cancelCommitment(poolKey, id, proofWithWrongHash.proofData); // Revert if the proof is invalid - (,,, bytes memory fakeProof) = + RaylsHookHelper.PrivateSwapPublic memory proofWithWrongPA = RaylsHookHelper.getPublicSignalsFromPrivateSwapIntentProof(jsonPrivateSwap, true, false); expectedRevert = abi.encodeWithSelector(RaylsHook.InvalidPrivateSwapIntentProof.selector); vm.expectRevert(expectedRevert); - hook.cancelCommitment(poolKey, id, fakeProof); + hook.cancelCommitment(poolKey, id, proofWithWrongPA.proofData); // Cancel it before it can be executed - hook.cancelCommitment(poolKey, id, proofData); + hook.cancelCommitment(poolKey, id, proofCorrect.proofData); // Cancel it again shoule revvert expectedRevert = abi.encodeWithSelector(RaylsHook.CommitmentNotActive.selector, id); vm.expectRevert(expectedRevert); - hook.cancelCommitment(poolKey, id, proofData); + hook.cancelCommitment(poolKey, id, proofCorrect.proofData); // Move time forward to be able to execute the commitment - vm.warp(timestamp + 1); + vm.warp(proofCorrect.timestamp + 1); // Revert if we try to execute a cancelled commitment expectedRevert = abi.encodeWithSelector(RaylsHook.CommitmentNotActive.selector, id); vm.expectRevert(expectedRevert); - hook.executeCommitment(poolKey, id, proofData); + hook.executeCommitment(poolKey, id, proofCorrect.proofData); vm.stopPrank(); (,, RaylsHook.CommitmentStatus status) = hook.commitments(poolKey.toId(), id); diff --git a/packages/foundry/test/utils/RaylsHookHelper.sol b/packages/foundry/test/utils/RaylsHookHelper.sol index 2b639a4..7ece6e0 100644 --- a/packages/foundry/test/utils/RaylsHookHelper.sol +++ b/packages/foundry/test/utils/RaylsHookHelper.sol @@ -9,6 +9,13 @@ import { IERC20Permit } from "@openzeppelin/contracts/token/ERC20/extensions/IER library RaylsHookHelper { using stdJson for string; + struct PrivateSwapPublic { + uint256 amountIn; + uint256 timestamp; + uint256 poseidonHash; + bytes proofData; + } + function decryptCiphertext(Vm vm, string memory _auditorPk, string memory ciphertext) public returns (uint256 output) @@ -182,7 +189,7 @@ library RaylsHookHelper { function getPublicSignalsFromPrivateSwapIntentProof(string memory json, bool fakePa, bool fakeHash) public pure - returns (uint256 amountIn, uint256 timestamp, uint256 poseidonHash, bytes memory proofData) + returns (PrivateSwapPublic memory out) { (uint256[2] memory pA, uint256[2][2] memory pB, uint256[2] memory pC, uint256[5] memory pubSignals) = loadPrivateSwapIntentProof(json); @@ -197,10 +204,10 @@ library RaylsHookHelper { pubSignals[0] = 1; } - proofData = abi.encode(pA, pB, pC, pubSignals); - poseidonHash = pubSignals[0]; - amountIn = pubSignals[1]; - timestamp = pubSignals[4]; + out.proofData = abi.encode(pA, pB, pC, pubSignals); + out.poseidonHash = pubSignals[0]; + out.amountIn = pubSignals[1]; + out.timestamp = pubSignals[4]; } function getJsonCiphertext(string memory _jsonEncryptedPayload) From a41c046a38c6b06954c421ad9bc3346fcaaaf171 Mon Sep 17 00:00:00 2001 From: Nuno Date: Mon, 15 Sep 2025 17:13:01 +0100 Subject: [PATCH 10/29] feat: addin lcov as dependency --- packages/foundry/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/foundry/package.json b/packages/foundry/package.json index b5dbdd4..5034803 100644 --- a/packages/foundry/package.json +++ b/packages/foundry/package.json @@ -29,6 +29,7 @@ "toml": "~3.0.0" }, "devDependencies": { + "lcov": "^1.16.0", "shx": "^0.3.4" } } From 3d973ed9373f29f8d68ff88779ef5a076357fe60 Mon Sep 17 00:00:00 2001 From: Nuno Date: Mon, 15 Sep 2025 17:19:09 +0100 Subject: [PATCH 11/29] feat: just addin new commands in README --- README.md | 71 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 4b766e9..1a7f25d 100644 --- a/README.md +++ b/README.md @@ -46,22 +46,24 @@ Rayls Hook implements a comprehensive investor suitability assessment system tha ### Technology Stack -| Layer | Technology | Purpose | -|-------|------------|---------| -| **ZK Layer** | Circom + SnarkJS | Zero-knowledge proof generation | -| **Smart Contracts** | Solidity + Foundry | On-chain verification | -| **Frontend** | NextJS + Scaffold-ETH 2 | User interface | -| **Integration** | Uniswap v4 Hooks | DEX integration | -| **Development** | TypeScript + Wagmi | Type-safe development | +| Layer | Technology | Purpose | +| ------------------- | ----------------------- | ------------------------------- | +| **ZK Layer** | Circom + SnarkJS | Zero-knowledge proof generation | +| **Smart Contracts** | Solidity + Foundry | On-chain verification | +| **Frontend** | NextJS + Scaffold-ETH 2 | User interface | +| **Integration** | Uniswap v4 Hooks | DEX integration | +| **Development** | TypeScript + Wagmi | Type-safe development | ### Circuit Architecture #### Suitability Assessment Circuit + - **Private Inputs**: 5 questionnaire responses (0-3 scale) - **Public Inputs**: Risk threshold and calculated profile - **Output**: Suitability verification (0 or 1) #### Private Swap Intent Circuit + - **Private Inputs**: Amount, direction, sender, timestamp - **Public Outputs**: Commitment hash and verification data - **Purpose**: Prove swap intent without revealing sensitive details @@ -95,7 +97,7 @@ yarn install ```bash # Start local Ethereum network (Scaffold-ETH 2) -yarn chain +yarn workspace foundry chain ``` This command starts a local Ethereum network using Foundry. The network runs on your local machine and can be used for testing and development. @@ -103,19 +105,16 @@ This command starts a local Ethereum network using Foundry. The network runs on ### 3. Setup Zero-Knowledge Circuits ```bash -# Setup ZK circuits and generate proofs -yarn setup - # Or setup specific circuits -yarn setup-suitability # Suitability assessment circuit -yarn setup-private-swap # Private swap intent circuit +yarn workspace circom setup-suitability # Suitability assessment circuit +yarn workspace circom setup-private-swap # Private swap intent circuit ``` ### 4. Deploy Smart Contracts ```bash # Deploy contracts to local network -yarn deploy +yarn workspace @se-2/foundry deploy ``` This command deploys the Rayls Hook smart contracts to the local network, including the ZK verifiers and Uniswap v4 hooks. @@ -124,27 +123,39 @@ This command deploys the Rayls Hook smart contracts to the local network, includ ```bash # Start the NextJS frontend -yarn start +yarn workspace @se-2/nextjs start ``` Visit your app on: `http://localhost:3000`. You can interact with the suitability assessment and test the ZK proof verification. +### 6. Running tests + +```bash +yarn workspace @se-2/foundry test +``` + +### 7. Check coverage + +```bash +yarn workspace @se-2/foundry coverage +``` + ## 🛠️ Development ### Available Commands -| Command | Description | -|---------|-------------| -| `yarn chain` | Start local blockchain | -| `yarn deploy` | Deploy smart contracts | -| `yarn start` | Start frontend | -| `yarn setup` | Setup ZK circuits (default: Suitability) | -| `yarn prove` | Generate new ZK proof | -| `yarn setup-suitability` | Setup Suitability circuit | -| `yarn prove-suitability` | Generate Suitability proof | -| `yarn setup-private-swap` | Setup PrivateSwapIntent circuit | -| `yarn prove-private-swap` | Generate PrivateSwapIntent proof | -| `yarn test` | Run tests | +| Command | Description | +| ------------------------- | ---------------------------------------- | +| `yarn chain` | Start local blockchain | +| `yarn deploy` | Deploy smart contracts | +| `yarn start` | Start frontend | +| `yarn setup` | Setup ZK circuits (default: Suitability) | +| `yarn prove` | Generate new ZK proof | +| `yarn setup-suitability` | Setup Suitability circuit | +| `yarn prove-suitability` | Generate Suitability proof | +| `yarn setup-private-swap` | Setup PrivateSwapIntent circuit | +| `yarn prove-private-swap` | Generate PrivateSwapIntent proof | +| `yarn test` | Run tests | ### Project Structure @@ -181,12 +192,14 @@ yarn prove-private-swap ## 📋 Roadmap ### Phase 1: Core Infrastructure ✅ + - [x] ZK circuits implementation (Suitability + PrivateSwapIntent) - [x] Smart contract verifiers - [x] Basic Uniswap v4 hook integration - [x] ZK proof generation and verification pipeline ### Phase 2: Frontend Development 🚧 + - [ ] Complete questionnaire UI implementation - [ ] ZK proof generation interface - [ ] Real-time proof verification @@ -194,6 +207,7 @@ yarn prove-private-swap - [ ] Integration with wallet providers ### Phase 3: Advanced Features 📋 + - [ ] Multi-circuit support and management - [ ] Advanced risk assessment algorithms - [ ] Compliance and regulatory features @@ -201,6 +215,7 @@ yarn prove-private-swap - [ ] Mobile-responsive design ### Phase 4: Production Ready 🎯 + - [ ] Security audits and testing - [ ] Performance optimization - [ ] Documentation and tutorials @@ -247,4 +262,4 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file --- -**Note**: This project is part of the Uniswap Hook Incubator 6 program. For production use, consider security audits and additional compliance requirements. \ No newline at end of file +**Note**: This project is part of the Uniswap Hook Incubator 6 program. For production use, consider security audits and additional compliance requirements. From df2719e251fcb7e28975c2fde70bb74f107cd33c Mon Sep 17 00:00:00 2001 From: Nuno Date: Tue, 16 Sep 2025 10:19:03 +0100 Subject: [PATCH 12/29] feat: improved test for auditor decryption --- packages/foundry/test/RaylsHook.t.sol | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/packages/foundry/test/RaylsHook.t.sol b/packages/foundry/test/RaylsHook.t.sol index c658d26..29d7221 100644 --- a/packages/foundry/test/RaylsHook.t.sol +++ b/packages/foundry/test/RaylsHook.t.sol @@ -290,16 +290,17 @@ contract RaylsHookTest is Test, Deployers { hook.executeCommitment(poolKey, id, proofCorrect.proofData); vm.stopPrank(); + // Test the auditor part (bytes memory onChainCiphertext,, RaylsHook.CommitmentStatus status) = hook.commitments(poolKey.toId(), id); assertEq(uint8(status), uint8(RaylsHook.CommitmentStatus.Executed)); assertEq(onChainCiphertext, ciphertextForAuditor); - string memory hexOnChainCiphertext = vm.toString(onChainCiphertext); + string memory onChainCiphertextStr = vm.toString(onChainCiphertext); // Decrypt off-chain and use the private values to calculate the commitment ID // It must match to the one stored on-chain created by the circuit. - uint256 decryptedPoseidonHash = RaylsHookHelper.decryptCiphertext(vm, auditorPk, hexOnChainCiphertext); + uint256 decryptedPoseidonHash = RaylsHookHelper.decryptCiphertext(vm, auditorPk, onChainCiphertextStr); // Check that commitmentId is correct assertEq(proofCorrect.poseidonHash, decryptedPoseidonHash); @@ -317,11 +318,22 @@ contract RaylsHookTest is Test, Deployers { // Get the ciphertext for the auditor from the json file bytes memory ciphertextForAuditor = RaylsHookHelper.getJsonCiphertext(jsonEncryptedPayload); - string memory hexOnChainCiphertext = vm.toString(ciphertextForAuditor); + string memory onChainCiphertextStr = vm.toString(ciphertextForAuditor); + // First lets try with a fake ciphertext and see that cannot decrypt it + // The wallet here was set at an invalid value so decryption will fail + bytes memory fakeCiphertext = + hex"ee86f15b901b6c155b8c3ec570e50f4c04b86d3cf44aafa7cc640a3e141354da40eef4c6ed78fd8077be72c3e853e435cf9fa2d70164501cd37efec0dc0a04119f66ecf007b190100c856d5aae7a5fec4d38b39c99bed1d8923635820c81bb9d8d52794056400a7d19f6e8ce663c79684cc19a7935ca8189811169a5fbe5c1147fd80f3a83207217c1a895862b162c89ce85dc51c53571c1202b90e1e710cb801d47b4aabeeac981197ba285c399c344ff09d56a386f26169726e8f29c9ff4c45c033816426f6d8d4befadb6f008d2bf8537022f5aaa9e93920fa8e959c0ca30e0edabd55bcfcbc3050343426ea294e61321e1885efe3db4be70f4bc9b8a0b2f4c"; + string memory fakeCiphertextStr = vm.toString(fakeCiphertext); + uint256 decryptedPoseidonHash = RaylsHookHelper.decryptCiphertext(vm, auditorPk, fakeCiphertextStr); + + // Check that hashes are different + assertNotEq(proofCorrect.poseidonHash, decryptedPoseidonHash); + + // Now a successful decryption // Decrypt off-chain and use the poseidonHash for comparison // It must match to the one stored on-chain created by the circuit. - uint256 decryptedPoseidonHash = RaylsHookHelper.decryptCiphertext(vm, auditorPk, hexOnChainCiphertext); + decryptedPoseidonHash = RaylsHookHelper.decryptCiphertext(vm, auditorPk, onChainCiphertextStr); // Check that hashes are equal assertEq(proofCorrect.poseidonHash, decryptedPoseidonHash); From 141da8b8a9c8e4b11aae3ce406da413ee5fa08fb Mon Sep 17 00:00:00 2001 From: Nuno Date: Tue, 16 Sep 2025 11:58:53 +0100 Subject: [PATCH 13/29] feat: adding README content --- README.md | 32 ++++++++++-- docs/RaylsHook_diagram.svg | 102 +++++++++++++++++++++++++++++++++++++ docs/privateSwaps.md | 84 ++++++++++++++++++++++++++++++ 3 files changed, 214 insertions(+), 4 deletions(-) create mode 100644 docs/RaylsHook_diagram.svg create mode 100644 docs/privateSwaps.md diff --git a/README.md b/README.md index 1a7f25d..544264e 100644 --- a/README.md +++ b/README.md @@ -14,13 +14,19 @@ TypeScript

-🧪 **Rayls Hook** is a privacy-preserving investor suitability assessment system built on Uniswap v4 hooks. It allows users to prove their investment suitability without revealing their specific questionnaire responses using Zero-Knowledge Proofs. +**Rayls Hook** introduces two complementary ZK-SNARK enabled features built on Uniswap v4 hooks: + +1. 🛡️ Suitability Verifier Logic – A privacy-preserving investor suitability assessment system. It allows users to prove their investment suitability without revealing their specific questionnaire responses using Zero-Knowledge Proofs. + +2. [🔐 Private Swap Logic](./docs/privateSwaps.md) (click for more info) – Private swaps with an execution timestamp. Swap values remain hidden and are committed on-chain through a commitment ID, then later executed and validated and revealed with zkSNARK proofs. The values are also encrypted with an Auditor’s wallet public key (optional), and the ciphertext is stored on-chain, enabling the Auditor to independently verify commitments at any time. + +There's no integration with Hackaton partners but for private swaps, while commitments and encrypted payloads are currently stored fully on-chain, they could instead be stored in EigenDA with only lightweight references on-chain, reducing gas costs and improving scalability without compromising verifiability. ⚙️ Built using **Scaffold-ETH 2** as the foundation, with **NextJS**, **RainbowKit**, **Foundry**, **Wagmi**, **Circom**, **SnarkJS**, and **TypeScript**. ## 🎯 Project Overview -Rayls Hook implements a comprehensive investor suitability assessment system that: +🛡️ Suitability Verifier Logic - ✅ **Private Questionnaire**: Users answer 5 suitability questions without revealing their responses - 🔐 **Zero-Knowledge Proofs**: Prove investment suitability using Circom circuits @@ -29,6 +35,14 @@ Rayls Hook implements a comprehensive investor suitability assessment system tha - 🛡️ **Privacy-First**: Never reveal private questionnaire data - ⚡ **On-Chain Verification**: Smart contract verification of ZK proofs +🔐 Private Swap Logic + +- ✅ Encrypted Commitments: Users (or backend services) create encrypted swap commitments +- ⏳ Deferred Execution: Commitments become executable only after a timestamp +- 🔏 ZK Proof of Intent: Execution requires a zkSNARK proof proving knowledge of commitment id +- 📡 Auditor Access: Commitments include encrypted values for auditors to decrypt +- 🪝 Uniswap v4 Integration: Hook contract executes swaps using permit + safe transfer logic + ## 🏗️ Architecture ### System Components @@ -44,6 +58,10 @@ Rayls Hook implements a comprehensive investor suitability assessment system tha └─────────────────┘ └──────────────────┘ └─────────────────┘ ``` +- Suitability Verifier Logic lives in circuits + verifier contracts + +- Private Swap Logic lives in the hook contracts + zk circuits + auditor encrypt/decrypt scripts. + ### Technology Stack | Layer | Technology | Purpose | @@ -64,7 +82,7 @@ Rayls Hook implements a comprehensive investor suitability assessment system tha #### Private Swap Intent Circuit -- **Private Inputs**: Amount, direction, sender, timestamp +- **Private Inputs**: amountIn, zeroForOne, sender, timestamp - **Public Outputs**: Commitment hash and verification data - **Purpose**: Prove swap intent without revealing sensitive details @@ -136,6 +154,8 @@ yarn workspace @se-2/foundry test ### 7. Check coverage +(We focused on RaylsHook contract for full coverage) + ```bash yarn workspace @se-2/foundry coverage ``` @@ -197,10 +217,12 @@ yarn prove-private-swap - [x] Smart contract verifiers - [x] Basic Uniswap v4 hook integration - [x] ZK proof generation and verification pipeline +- [x] Auditor encryption feature +- [x] Multiple tests ### Phase 2: Frontend Development 🚧 -- [ ] Complete questionnaire UI implementation +- [ ] Complete UI + BE implementation - [ ] ZK proof generation interface - [ ] Real-time proof verification - [ ] User dashboard and profile management @@ -209,6 +231,8 @@ yarn prove-private-swap ### Phase 3: Advanced Features 📋 - [ ] Multi-circuit support and management +- [ ] Private Swap multi-auditors support and management +- [ ] Private Swap multi-executors support and management - [ ] Advanced risk assessment algorithms - [ ] Compliance and regulatory features - [ ] Integration with external KYC providers diff --git a/docs/RaylsHook_diagram.svg b/docs/RaylsHook_diagram.svg new file mode 100644 index 0000000..ad2bc1d --- /dev/null +++ b/docs/RaylsHook_diagram.svg @@ -0,0 +1,102 @@ +

Start
Private Swap Flow

User

RAYLS Middleware

RAYLS Uniswap Hook

Pool Manager

Auditor (optional)

creates swap commitment

executes swap

reads ciphertext

executeCommitment

storeCommitment

cancelCommitment

\ No newline at end of file diff --git a/docs/privateSwaps.md b/docs/privateSwaps.md new file mode 100644 index 0000000..2035953 --- /dev/null +++ b/docs/privateSwaps.md @@ -0,0 +1,84 @@ +## 📄 `docs/privateSwaps.md` + +🔐 Private Swap Commitments + +This Uniswap v4 hook extension introduces encrypted swap commitments, allowing users to conceal their swap parameters until execution while preserving permissionless execution and optional auditor oversight. + +Private swaps are created with an execution timestamp. Swap values are hidden and committed on-chain via a unique commitment ID, then later revealed and validated with zkSNARK proofs. Optionally, swap details are encrypted with an Auditor’s public key and the ciphertext is stored on-chain, enabling independent verification at any time. + +Key use cases include: + +- MEV protection – hiding swap intent reduces frontrunning risk; at reveal time, private bundlers can be used for additional protection. + +- Large swaps – users executing large trades can split them into multiple commitments to minimize pool price impact. + +- Compliance & oversight – DAOs and regulated protocols can prove swap schedules on-chain, with auditors able to verify encrypted commitments. + +## 🔄 Flow + +

+ Private Swap Diagram +

+ +### 1. Create Commitment + +- **User** through a UI: + + - Creates a swap commitment by defining amountIn, direction, timestamp. + - Signs and sends along an ERC20 permit + +- **Rayls Middleware** + + - Encrypts swap params using Auditor's pub key. + - Creates and holds zkSNARK proofs of knowledge of swap params for commitment `id`.. + - Generates commitment id using Auditor's encryption + Poseidon hash from zk proof. + - Calls `storeCommitment(id, ciphertext, permit)` with: + - `id`: unique hash of the commitment. + - `ciphertext`: encrypted swap details (amount, direction, timestamp). + - `encKeyForAuditor`: ECIES encryption key for auditor. + - `permit`: ERC20 permit signature. + - Contract records commitment and emits `CommitmentStored`. + +### 2. Execute Commitment + +- **Rayls Middleware** + + - Monitors for commitments with expired timestamps. + - Triggers commitment execution when timestamp is reached + - When time is reached, calls `executeCommitment(id, zkProof)`. + +- **Rayls Hook** + + - Verifies: + - zkSNARK proof validity. + - Commitment matches proof. + - Permit authorizes token pull. + - Contract executes swap via Uniswap v4 `PoolManager`. + - Settles balances on callback + - Emits `CommitmentExecuted`. + +### 3. Cancel Commitment + +- **User** + - Triggers a commitment cancellation through a UI, before execution +- **Rayls Middleware** + - Calls `cancelCommitment(id, zkProof)`. +- **Rayls Hook** + - Marks commitment as canceled, clears heavy storage. + - Emits `CommitmentCanceled`. + +### 4. Auditor Flow + +- **Auditor** can always: + + - Read `ciphertext` + `encKeyForAuditor` onchain. + - Decrypt using it's own private key. + - Verify swap parameters offchain for compliance. + - Validates if permit matches the encrypted values + +--- + +## Key notes + +- We use circom for zksnark and AES encryption for the auditor. Encryption in circom is too expensive. +- We could enforce the auditor to approve a commitement cancelation. From 655bce49d3af32db1caa85285d7fbd31653aeb03 Mon Sep 17 00:00:00 2001 From: Nuno Date: Tue, 16 Sep 2025 12:06:03 +0100 Subject: [PATCH 14/29] feat: modifying diagram --- docs/RaylsHook_diagram.svg | 103 +------------------------------------ docs/privateSwaps.md | 2 +- 2 files changed, 2 insertions(+), 103 deletions(-) diff --git a/docs/RaylsHook_diagram.svg b/docs/RaylsHook_diagram.svg index ad2bc1d..457a2d4 100644 --- a/docs/RaylsHook_diagram.svg +++ b/docs/RaylsHook_diagram.svg @@ -1,102 +1 @@ -

Start
Private Swap Flow

User

RAYLS Middleware

RAYLS Uniswap Hook

Pool Manager

Auditor (optional)

creates swap commitment

executes swap

reads ciphertext

executeCommitment

storeCommitment

cancelCommitment

\ No newline at end of file +

Start
Private Swap Flow

User

RAYLS Middleware

RAYLS Uniswap Hook

Pool Manager

Auditor (optional)

creates swap commitment

executes swap

reads ciphertext

executeCommitment

storeCommitment

cancelCommitment

\ No newline at end of file diff --git a/docs/privateSwaps.md b/docs/privateSwaps.md index 2035953..5bc097c 100644 --- a/docs/privateSwaps.md +++ b/docs/privateSwaps.md @@ -17,7 +17,7 @@ Key use cases include: ## 🔄 Flow

- Private Swap Diagram + Private Swap Diagram

### 1. Create Commitment From 54a3bde4d36c023d27228fb5c53a2de63af6bdd6 Mon Sep 17 00:00:00 2001 From: Nuno Date: Tue, 16 Sep 2025 13:59:15 +0100 Subject: [PATCH 15/29] feat: updating diagram --- docs/RaylsHook_diagram.svg | 1 - docs/RaylsHook_sequence_diagram.svg | 102 ++++++++++++++++++++++++++++ docs/privateSwaps.md | 2 +- 3 files changed, 103 insertions(+), 2 deletions(-) delete mode 100644 docs/RaylsHook_diagram.svg create mode 100644 docs/RaylsHook_sequence_diagram.svg diff --git a/docs/RaylsHook_diagram.svg b/docs/RaylsHook_diagram.svg deleted file mode 100644 index 457a2d4..0000000 --- a/docs/RaylsHook_diagram.svg +++ /dev/null @@ -1 +0,0 @@ -

Start
Private Swap Flow

User

RAYLS Middleware

RAYLS Uniswap Hook

Pool Manager

Auditor (optional)

creates swap commitment

executes swap

reads ciphertext

executeCommitment

storeCommitment

cancelCommitment

\ No newline at end of file diff --git a/docs/RaylsHook_sequence_diagram.svg b/docs/RaylsHook_sequence_diagram.svg new file mode 100644 index 0000000..22e6dde --- /dev/null +++ b/docs/RaylsHook_sequence_diagram.svg @@ -0,0 +1,102 @@ +AuditorRayls HookRayls MiddlewareUserAuditorRayls HookRayls MiddlewareUserhas (sk = a, pk = aG)knows auditor pkSigns a permit message <hookAddress, amount>checks permitm = < amount, direction, sender, timestamp >generates a zkSNARK proof zk, outputs poseidon hash ph = Hash(m)ciphertext = ENC(m)commitmentId = keccak256(ciphertext, ph)m = DEC(sk, ciphertext)Monitors timestampVerifies zkSNARK proof validity.Verifies if commitmentId matches zk public signal.Verifies timestamp >= block.timestampExecutes permitEecutes swap via Uniswap v4 `PoolManager`.Settles balances on callbacktrigger private swap req = <amount, direction, sender, timestamp, permit>calls storeCommitment<poolKey, commitmentId, ciphertext, permit>new commitment: < ciphertext >User can cancel the commitmentcalls cancelCommitment<poolKey, commitmentId, zk>calls executeCommitment<poolKey, commitmentId, zk> diff --git a/docs/privateSwaps.md b/docs/privateSwaps.md index 5bc097c..2c98999 100644 --- a/docs/privateSwaps.md +++ b/docs/privateSwaps.md @@ -17,7 +17,7 @@ Key use cases include: ## 🔄 Flow

- Private Swap Diagram + Private Swap Diagram

### 1. Create Commitment From 44aa13d25f26e13e3f37e17c146fc7bf1a8ef85d Mon Sep 17 00:00:00 2001 From: Nuno Date: Tue, 16 Sep 2025 14:08:41 +0100 Subject: [PATCH 16/29] feat: modifying README --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 544264e..a913ecd 100644 --- a/README.md +++ b/README.md @@ -20,9 +20,11 @@ 2. [🔐 Private Swap Logic](./docs/privateSwaps.md) (click for more info) – Private swaps with an execution timestamp. Swap values remain hidden and are committed on-chain through a commitment ID, then later executed and validated and revealed with zkSNARK proofs. The values are also encrypted with an Auditor’s wallet public key (optional), and the ciphertext is stored on-chain, enabling the Auditor to independently verify commitments at any time. -There's no integration with Hackaton partners but for private swaps, while commitments and encrypted payloads are currently stored fully on-chain, they could instead be stored in EigenDA with only lightweight references on-chain, reducing gas costs and improving scalability without compromising verifiability. +## 📌 Key Notes -⚙️ Built using **Scaffold-ETH 2** as the foundation, with **NextJS**, **RainbowKit**, **Foundry**, **Wagmi**, **Circom**, **SnarkJS**, and **TypeScript**. +- Private swap commitments and encrypted payloads are currently fully stored on-chain, but they could be stored in EigenDA with only lightweight references on-chain to reduce gas costs and improve scalability without compromising verifiability. +- Only the beforeSwap hook is used, but the logic can be extended to beforeAddLiquidity as well. +- The two features — Suitability Verifier and Private Swap Commitments — are independent, though private swap execution could optionally require passing the suitability check. ## 🎯 Project Overview From caa0ff2128c46be67b739e4576651bed8fcbddb9 Mon Sep 17 00:00:00 2001 From: Nuno Date: Tue, 16 Sep 2025 14:21:10 +0100 Subject: [PATCH 17/29] feat: adding simple suitability md --- README.md | 2 +- ...vg => RaylsHook_private_swaps_diagram.svg} | 0 docs/RaylsHook_suitability_diagram.png | Bin 0 -> 359202 bytes docs/privateSwaps.md | 2 +- docs/suitability.md | 51 ++++++++++++++++++ 5 files changed, 53 insertions(+), 2 deletions(-) rename docs/{RaylsHook_sequence_diagram.svg => RaylsHook_private_swaps_diagram.svg} (100%) create mode 100644 docs/RaylsHook_suitability_diagram.png create mode 100644 docs/suitability.md diff --git a/README.md b/README.md index a913ecd..5a58742 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ **Rayls Hook** introduces two complementary ZK-SNARK enabled features built on Uniswap v4 hooks: -1. 🛡️ Suitability Verifier Logic – A privacy-preserving investor suitability assessment system. It allows users to prove their investment suitability without revealing their specific questionnaire responses using Zero-Knowledge Proofs. +1. [🛡️ Suitability Verifier Logic](./docs/suitability.md) (click for more info) – A privacy-preserving investor suitability assessment system. It allows users to prove their investment suitability without revealing their specific questionnaire responses using Zero-Knowledge Proofs. 2. [🔐 Private Swap Logic](./docs/privateSwaps.md) (click for more info) – Private swaps with an execution timestamp. Swap values remain hidden and are committed on-chain through a commitment ID, then later executed and validated and revealed with zkSNARK proofs. The values are also encrypted with an Auditor’s wallet public key (optional), and the ciphertext is stored on-chain, enabling the Auditor to independently verify commitments at any time. diff --git a/docs/RaylsHook_sequence_diagram.svg b/docs/RaylsHook_private_swaps_diagram.svg similarity index 100% rename from docs/RaylsHook_sequence_diagram.svg rename to docs/RaylsHook_private_swaps_diagram.svg diff --git a/docs/RaylsHook_suitability_diagram.png b/docs/RaylsHook_suitability_diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..d701e20cf409f0a5d097627aecdefd01cbb8295e GIT binary patch literal 359202 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

F=9o}?n4Ux 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%0A_ZJ_n{8cM4ypA7Zz{#VgMx#>tDFzu`cK0~ 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 HhhP2+1LvtF literal 0 HcmV?d00001 diff --git a/docs/privateSwaps.md b/docs/privateSwaps.md index 2c98999..93a430d 100644 --- a/docs/privateSwaps.md +++ b/docs/privateSwaps.md @@ -17,7 +17,7 @@ Key use cases include: ## 🔄 Flow

- Private Swap Diagram + Private Swap Diagram

### 1. Create Commitment diff --git a/docs/suitability.md b/docs/suitability.md new file mode 100644 index 0000000..e46de90 --- /dev/null +++ b/docs/suitability.md @@ -0,0 +1,51 @@ +## 🛡️ Suitability Verifier Logic + +The Suitability Verifier Logic ensures that **investors can prove compliance** with regulatory requirements without revealing their raw questionnaire responses. This is done using a **zkSNARK proof**. + +## 🔄 Flow + +

+ Suitability Diagram +

+ +1. **Investor (User)** + + - Fills out a suitability questionnaire offchain. + - FE (frontend) generates a commitment hash of the answers. + - BE (backend) computes zkSNARK proof: + - Shows that the answers meet required conditions. + - Keeps raw answers private. + +2. **Frontend (FE)** + + - Collects user answers. + - Passes them securely to BE. + - Displays status to user (proof verified or not). + +3. **Backend (BE)** + + - Generates proof using Circom circuit. + - Sends proof + public signals to smart contract. + +4. **Smart Contract (Verifier)** + - Receives proof + signals. + - Runs `verifyProof(...)` onchain. + - Marks user as "suitable" if proof is valid. + +--- + +## 🔐 Onchain Verification + +The contract only verifies: + +- Proof validity. +- Public signals match expected format (e.g., user address, KYC hash). + +Raw answers **never leave the BE** and are not revealed onchain. + +--- + +## 📋 Events + +- `SuitabilityVerified(address indexed user)` – user passed the suitability check. +- `SuitabilityRevoked(address indexed user)` – regulator/admin revoked suitability. From 4b7832402058e8864a35013d72264b5047cc9f6f Mon Sep 17 00:00:00 2001 From: Nuno Date: Tue, 16 Sep 2025 14:22:28 +0100 Subject: [PATCH 18/29] feat: increasing width diagram --- docs/privateSwaps.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/privateSwaps.md b/docs/privateSwaps.md index 93a430d..be241cf 100644 --- a/docs/privateSwaps.md +++ b/docs/privateSwaps.md @@ -17,7 +17,7 @@ Key use cases include: ## 🔄 Flow

- Private Swap Diagram + Private Swap Diagram

### 1. Create Commitment From 5ffb6f74bb256bc5f74ad58856abe768d00ad35f Mon Sep 17 00:00:00 2001 From: Nuno Date: Tue, 16 Sep 2025 14:44:53 +0100 Subject: [PATCH 19/29] feat: adding more comments to tests --- packages/foundry/test/RaylsHook.t.sol | 56 ++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 9 deletions(-) diff --git a/packages/foundry/test/RaylsHook.t.sol b/packages/foundry/test/RaylsHook.t.sol index 29d7221..8e3707b 100644 --- a/packages/foundry/test/RaylsHook.t.sol +++ b/packages/foundry/test/RaylsHook.t.sol @@ -129,7 +129,10 @@ contract RaylsHookTest is Test, Deployers { currency0.transfer(invalidProofSender, 1e18); } - function testSwapRevertsWithInvalidProof() public { + /** + * Tests that a swap reverts if the suitability proof is invalid. + */ + function testSuitabilitySwapWithInvalidProof() public { (uint256[2] memory pA, uint256[2][2] memory pB, uint256[2] memory pC, uint256[5] memory pubSignals) = RaylsHookHelper.loadSuitabilityProof(jsonSuitability); @@ -140,6 +143,7 @@ contract RaylsHookTest is Test, Deployers { vm.startPrank(proofSender, proofSender); IERC20Minimal(Currency.unwrap(currency0)).approve(address(swapRouter), amountIn); + // Revert if the proof is invalid vm.expectRevert(); swapRouter.swapExactTokensForTokens({ amountIn: amountIn, @@ -154,13 +158,19 @@ contract RaylsHookTest is Test, Deployers { vm.stopPrank(); } - function testVerifyProofInBeforeSwap() public { + /** + * Tests the suitability check before a swap. + */ + function testSuitabilitySwap() public { + // We load our zkSNARK proof from the json file (uint256[2] memory pA, uint256[2][2] memory pB, uint256[2] memory pC, uint256[5] memory pubSignals) = RaylsHookHelper.loadSuitabilityProof(jsonSuitability); bytes memory proofData = abi.encode(pA, pB, pC, pubSignals); + uint256 amountIn = 1e16; + // Revert if the proof is valid but the sender is not the one in the public signals vm.startPrank(invalidProofSender, invalidProofSender); IERC20Minimal(Currency.unwrap(currency0)).approve(address(swapRouter), amountIn); vm.expectRevert(); @@ -175,10 +185,11 @@ contract RaylsHookTest is Test, Deployers { }); vm.stopPrank(); + // Now we use the user that matches the public signal of the zkSNARK proof vm.startPrank(proofSender, proofSender); IERC20Minimal(Currency.unwrap(currency0)).approve(address(swapRouter), amountIn); - // Sucessful swap + // Now it should succeed BalanceDelta swapDelta = swapRouter.swapExactTokensForTokens({ amountIn: amountIn, amountOutMin: 0, @@ -188,14 +199,15 @@ contract RaylsHookTest is Test, Deployers { receiver: address(proofSender), deadline: block.timestamp + 1 }); + vm.stopPrank(); assertEq(int256(swapDelta.amount0()), -int256(amountIn)); - - // assertEq(selector, IHooks.beforeSwap.selector, "selector mismatch"); - // delta and fee are placeholder, assert if needed } + /** + * Tests the suitability verifier directly. + */ function testSuitabilityVerifier() public view { (uint256[2] memory pA, uint256[2][2] memory pB, uint256[2] memory pC, uint256[5] memory pubSignals) = RaylsHookHelper.loadSuitabilityProof(jsonSuitability); @@ -205,6 +217,9 @@ contract RaylsHookTest is Test, Deployers { assertTrue(ok); } + /** + * Tests the private swap intent verifier directly. + */ function testPrivateSwapIntentVerifier() public view { (uint256[2] memory pA, uint256[2][2] memory pB, uint256[2] memory pC, uint256[5] memory pubSignals) = RaylsHookHelper.loadPrivateSwapIntentProof(jsonPrivateSwap); @@ -214,7 +229,20 @@ contract RaylsHookTest is Test, Deployers { assertTrue(ok); } - function testAPrivateSwap() public { + /** + * Tests the full flow of a private swap: + * 1. Loads proof and public signals from the json file + * 2. Loads the ciphertext for the auditor from the json file + * 3. Calculates the commitment ID off-chain using both the ZK Snark Poseidon hash and the ciphertext + * 4. Stores the commitment on-chain + * 5. Does multiple negative revert tests. + * 6. Executes the commitment successfully + * 7. Checks the pool delta from the pool + * 8. Tests the auditor part by decrypting the ciphertext and checking that the poseidon hash matches the one from the proof + * This proves that the values in the encrypted payload: amountIn, zeroForOne, sender, timestamp are correct. + * And that the commitment ID is correct. + */ + function testPrivateSwap() public { // Get the proof and public signals from the json file RaylsHookHelper.PrivateSwapPublic memory proofCorrect = RaylsHookHelper.getPublicSignalsFromPrivateSwapIntentProof(jsonPrivateSwap, false, false); @@ -311,7 +339,7 @@ contract RaylsHookTest is Test, Deployers { * This simulates the auditor decrypting the ciphertext and checking that the commitment ID is correct. * Which proves that the values in the encrypted payload: amountIn, zeroForOne, sender, timestamp are correct. */ - function test_EncryptedCommitmentForAuditor() public { + function testEncryptedCommitmentForAuditor() public { // Get the proof and public signals from the json file RaylsHookHelper.PrivateSwapPublic memory proofCorrect = RaylsHookHelper.getPublicSignalsFromPrivateSwapIntentProof(jsonPrivateSwap, false, false); @@ -339,7 +367,17 @@ contract RaylsHookTest is Test, Deployers { assertEq(proofCorrect.poseidonHash, decryptedPoseidonHash); } - function test_cancelCommitment() public { + /** + * Tests the full flow of cancelling a private swap commitment: + * 1. Loads proof and public signals from the json file + * 2. Loads the ciphertext for the auditor from the json file + * 3. Calculates the commitment ID off-chain using both the ZK Snark Poseidon hash and the ciphertext + * 4. Stores the commitment on-chain + * 5. Does multiple negative revert tests. + * 6. Cancels the commitment successfully + * 7. Tries to execute it and reverts + */ + function testCancelCommitment() public { // Get the proof and public signals from the json file RaylsHookHelper.PrivateSwapPublic memory proofCorrect = RaylsHookHelper.getPublicSignalsFromPrivateSwapIntentProof(jsonPrivateSwap, false, false); From 464c17044e4dbdb22136d7df7bfcbb2927faf8d4 Mon Sep 17 00:00:00 2001 From: Nuno Date: Tue, 16 Sep 2025 16:34:45 +0100 Subject: [PATCH 20/29] feat: adding more README content --- README.md | 3 +- docs/privateSwaps.md | 4 +- packages/circom/README.md | 150 ++++++++++++++++++++++---------------- 3 files changed, 92 insertions(+), 65 deletions(-) diff --git a/README.md b/README.md index 5a58742..516b141 100644 --- a/README.md +++ b/README.md @@ -18,10 +18,11 @@ 1. [🛡️ Suitability Verifier Logic](./docs/suitability.md) (click for more info) – A privacy-preserving investor suitability assessment system. It allows users to prove their investment suitability without revealing their specific questionnaire responses using Zero-Knowledge Proofs. -2. [🔐 Private Swap Logic](./docs/privateSwaps.md) (click for more info) – Private swaps with an execution timestamp. Swap values remain hidden and are committed on-chain through a commitment ID, then later executed and validated and revealed with zkSNARK proofs. The values are also encrypted with an Auditor’s wallet public key (optional), and the ciphertext is stored on-chain, enabling the Auditor to independently verify commitments at any time. +2. [🔐 Private Swap Logic](./docs/privateSwaps.md) (click for more info) – Private swaps with an execution timestamp. Swap values remain hidden and are committed on-chain through a commitment Id, then later revealed, validated and executed with zkSNARK proofs. The values are also encrypted (ECIES) using an Auditor’s wallet public key (optional) and the generated ciphertext is stored on-chain, enabling the Auditor to independently verify commitments at any time. ## 📌 Key Notes +- More details about circom and zkSNARK [here](./packages/circom/README.md) - Private swap commitments and encrypted payloads are currently fully stored on-chain, but they could be stored in EigenDA with only lightweight references on-chain to reduce gas costs and improve scalability without compromising verifiability. - Only the beforeSwap hook is used, but the logic can be extended to beforeAddLiquidity as well. - The two features — Suitability Verifier and Private Swap Commitments — are independent, though private swap execution could optionally require passing the suitability check. diff --git a/docs/privateSwaps.md b/docs/privateSwaps.md index be241cf..e444970 100644 --- a/docs/privateSwaps.md +++ b/docs/privateSwaps.md @@ -2,9 +2,7 @@ 🔐 Private Swap Commitments -This Uniswap v4 hook extension introduces encrypted swap commitments, allowing users to conceal their swap parameters until execution while preserving permissionless execution and optional auditor oversight. - -Private swaps are created with an execution timestamp. Swap values are hidden and committed on-chain via a unique commitment ID, then later revealed and validated with zkSNARK proofs. Optionally, swap details are encrypted with an Auditor’s public key and the ciphertext is stored on-chain, enabling independent verification at any time. +This Uniswap v4 hook extension introduces private swaps that allow users to conceal their swap parameters until an execution timestamp is reached. Hidden swap values are committed on-chain via a unique commitment ID, then later revealed, validated with zkSNARK proofs and the swap is executed. Swap details are also encrypted with an Auditor’s public key and the ciphertext is stored on-chain, enabling independent verification at any time. The commitment Id is the result of runnig the cryptographic function keccak256 against the auditor ciphertext and the posedion hash generated by the zk snark proof. Key use cases include: diff --git a/packages/circom/README.md b/packages/circom/README.md index dc519bd..b2ce9a0 100644 --- a/packages/circom/README.md +++ b/packages/circom/README.md @@ -1,47 +1,40 @@ -# Suitability Assessment with Zero-Knowledge Proofs +# Zero-Knowledge Proofs -This project implements an investor suitability assessment system using Zero-Knowledge Proofs (ZKP) with Circom and SnarkJS. The system allows a user to prove they have an adequate risk profile without revealing their specific questionnaire responses. - -## 🎯 Objective - -The goal is to create a system where: -- A user answers 5 suitability questions -- Each answer has a specific weight -- The system calculates a risk profile (0-10) -- The user can prove their profile meets a minimum threshold -- **Without revealing their specific responses** +This project implements an investor suitability assessment system and private swaps using Zero-Knowledge Proofs (ZKP) with Circom and SnarkJS. The system allows a user to prove they have an adequate risk profile without revealing their specific questionnaire responses. ## 🏗️ Architecture -### Available Circuits - The project includes two main circuits: -#### 1. Suitability Circuit (`circuits/Suitability.circom`) +### 1. Suitability Circuit (`circuits/Suitability.circom`) The suitability assessment circuit implements: + - **Private inputs**: 5 questionnaire responses (0-3 each) - **Public inputs**: minimum threshold and calculated risk profile - **Public output**: indicates if the profile meets the threshold (0 or 1) -#### 2. Private Swap Intent Circuit (`circuits/PrivateSwapIntent.circom`) +#### Objective -The private swap intent circuit implements: -- **Private inputs**: amount, direction, sender, timestamp -- **Public outputs**: commitment hash and public parameters -- **Purpose**: Prove swap intent without revealing sensitive details +The goal is to create a system where: -### Question Weights +- A user answers 5 suitability questions +- Each answer has a specific weight +- The system calculates a risk profile (0-10) +- The user can prove their profile meets a minimum threshold +- **Without revealing their specific responses** + +#### Question Weights -| Question | Weight | Description | -|----------|--------|-------------| -| 1 | 2 | Investment experience | -| 2 | 3 | Risk tolerance | -| 3 | 2 | Time horizon | -| 4 | 1 | Financial objectives | -| 5 | 2 | Market knowledge | +| Question | Weight | Description | +| -------- | ------ | --------------------- | +| 1 | 2 | Investment experience | +| 2 | 3 | Risk tolerance | +| 3 | 2 | Time horizon | +| 4 | 1 | Financial objectives | +| 5 | 2 | Market knowledge | -### Risk Profile Calculation +#### Risk Profile Calculation ``` weightedSum = answer1*2 + answer2*3 + answer3*2 + answer4*1 + answer5*2 @@ -49,6 +42,14 @@ maxPossibleScore = 4 * (2+3+2+1+2) = 40 riskProfile = (weightedSum * 10) / maxPossibleScore ``` +### 2. Private Swap Intent Circuit (`circuits/PrivateSwapIntent.circom`) + +The private swap intent circuit implements: + +- **Private inputs**: amount, direction, sender, timestamp +- **Public outputs**: poseidon hash and public parameters +- **Purpose**: Prove swap intent without revealing sensitive details + ## 🚀 Installation and Setup ### Prerequisites @@ -123,12 +124,14 @@ The `zk_pipeline.sh` script handles the entire ZK workflow: ### 2. What the Pipeline Does #### Compilation Phase: + - Compiles the Circom circuit - Generates R1CS constraints - Creates WASM and JavaScript files - Generates circuit symbols #### Setup Phase (--force-setup): + - Generates Powers of Tau (Phase 1) - Contributes to Powers of Tau - Prepares Phase 2 @@ -138,6 +141,7 @@ The `zk_pipeline.sh` script handles the entire ZK workflow: - Generates Solidity verifier contract #### Proof Generation: + - Calculates circuit witness - Generates ZK proof - Verifies proof off-chain @@ -148,6 +152,7 @@ The `zk_pipeline.sh` script handles the entire ZK workflow: The pipeline creates all necessary files: ``` +Example for Suitability: artifacts/ ├── Suitability.r1cs # Circuit constraints ├── Suitability_js/ # JavaScript witness calculator @@ -173,26 +178,25 @@ scripts/ # Input files ├── solidityInputs.json # Proof data for contract calls ├── solidityInputs.decimal.json # Decimal format ├── solidityInputs.ui.json # UI format -├── solidityCalldata.txt # Raw calldata -└── cast_call.sh # Cast call script +└── solidityCalldata.txt # Raw calldata ``` ## 🔧 Available Scripts -| Script | Description | -|--------|-------------| -| `yarn compile` | Compiles the Circom circuit only | -| `yarn setup` | Complete ZK setup for Suitability (default) | -| `yarn prove` | Generate new proof for Suitability (reuses existing setup) | -| `yarn test` | Runs system tests | +| Script | Description | +| -------------- | ---------------------------------------------------------- | +| `yarn compile` | Compiles the Circom circuit only | +| `yarn setup` | Complete ZK setup for Suitability (default) | +| `yarn prove` | Generate new proof for Suitability (reuses existing setup) | +| `yarn test` | Runs system tests | ### Circuit-Specific Commands -| Script | Description | -|--------|-------------| -| `yarn setup-suitability` | Complete ZK setup for Suitability circuit | -| `yarn prove-suitability` | Generate new proof for Suitability circuit | -| `yarn setup-private-swap` | Complete ZK setup for PrivateSwapIntent circuit | +| Script | Description | +| ------------------------- | ------------------------------------------------ | +| `yarn setup-suitability` | Complete ZK setup for Suitability circuit | +| `yarn prove-suitability` | Generate new proof for Suitability circuit | +| `yarn setup-private-swap` | Complete ZK setup for PrivateSwapIntent circuit | | `yarn prove-private-swap` | Generate new proof for PrivateSwapIntent circuit | ## 🧪 Tests @@ -204,8 +208,9 @@ yarn test ``` Tests scenarios such as: + - Low risk profile -- Medium risk profile +- Medium risk profile - High risk profile - Different thresholds - Constraint validation @@ -218,18 +223,19 @@ The Suitability circuit requires specific input format with questionnaire respon ```json { - "answer1": 3, // Investment experience (0-3) - "answer2": 2, // Risk tolerance (0-3) - "answer3": 1, // Time horizon (0-3) - "answer4": 2, // Financial objectives (0-3) - "answer5": 3, // Market knowledge (0-3) + "answer1": 3, // Investment experience (0-3) + "answer2": 2, // Risk tolerance (0-3) + "answer3": 1, // Time horizon (0-3) + "answer4": 2, // Financial objectives (0-3) + "answer5": 3, // Market knowledge (0-3) "wallet": "0x1234567890AbcdEF1234567890aBcdef12345678", // User wallet address "thresholdScaled": 20, // Minimum threshold (0-100, where 100 = 10.0) - "isSuitablePub": 1 // Expected result (0=Unsuitable, 1=Suitable) + "isSuitablePub": 1 // Expected result (0=Unsuitable, 1=Suitable) } ``` #### Field Descriptions: + - **answer1-5**: Questionnaire responses (0-3 scale) - `0`: Lowest risk/conservative option - `3`: Highest risk/aggressive option @@ -243,14 +249,15 @@ The PrivateSwapIntent circuit requires swap parameters and commitment data: ```json { - "amountIn": "100", // Amount to swap (string for large numbers) - "zeroForOne": "1", // Swap direction (0=Token1→Token0, 1=Token0→Token1) + "amountIn": "100", // Amount to swap (string for large numbers) + "zeroForOne": "1", // Swap direction (0=Token1→Token0, 1=Token0→Token1) "sender": "0x1234567890AbcdEF1234567890aBcdef12345678", // Sender address - "timestamp": "1697052800" // Unix timestamp of swap intent + "timestamp": "1697052800" // Unix timestamp of swap intent } ``` #### Field Descriptions: + - **amountIn**: Swap amount (use string format for large numbers) - **zeroForOne**: Direction flag (0 or 1) - **sender**: Address of the swap initiator @@ -274,22 +281,35 @@ yarn prove-private-swap #### Example Scenarios: **Suitable Profile (High Risk Tolerance):** + ```json { - "answer1": 3, "answer2": 3, "answer3": 2, "answer4": 3, "answer5": 3, - "thresholdScaled": 15, "isSuitablePub": 1 + "answer1": 3, + "answer2": 3, + "answer3": 2, + "answer4": 3, + "answer5": 3, + "thresholdScaled": 15, + "isSuitablePub": 1 } ``` **Unsuitable Profile (Low Risk Tolerance):** + ```json { - "answer1": 0, "answer2": 0, "answer3": 0, "answer4": 0, "answer5": 0, - "thresholdScaled": 25, "isSuitablePub": 0 + "answer1": 0, + "answer2": 0, + "answer3": 0, + "answer4": 0, + "answer5": 0, + "thresholdScaled": 25, + "isSuitablePub": 0 } ``` **Large Swap Intent:** + ```json { "amountIn": "1000000000000000000", // 1 ETH in wei @@ -336,12 +356,14 @@ const proofData = require('../foundry/solidityInputs.json'); ## 🛡️ Security ### Privacy + - **Private responses**: Never revealed - **Calculated profile**: Can be public - **Threshold**: Can be public - **Result**: Can be public ### Validation + - Constraints ensure valid responses (0-3) - Consistency verification between profile and threshold - Boundary validation (0-10) @@ -351,11 +373,13 @@ const proofData = require('../foundry/solidityInputs.json'); To integrate with the frontend: 1. **Run the ZK pipeline**: + ```bash yarn setup ``` 2. **Deploy the contract**: + ```bash cd ../foundry forge build @@ -363,16 +387,19 @@ forge script script/DeploySuitabilityVerifier.s.sol --rpc-url http://localhost:8 ``` 3. **Use Scaffold-ETH hooks**: + ```typescript -const { writeContractAsync: verifySuitabilityAsync } = useScaffoldWriteContract({ - contractName: "SuitabilityVerifier" -}); +const { writeContractAsync: verifySuitabilityAsync } = useScaffoldWriteContract( + { + contractName: "SuitabilityVerifier", + } +); // Verify suitability using generated proof data -const proofData = require('../foundry/solidityInputs.json'); +const proofData = require("../foundry/solidityInputs.json"); await verifySuitabilityAsync({ functionName: "verifyProof", - args: [proofData[0], proofData[1], proofData[2], proofData[3]] + args: [proofData[0], proofData[1], proofData[2], proofData[3]], }); ``` @@ -399,10 +426,11 @@ MIT License - see the [LICENSE](../LICENSE) file for details. ## 🆘 Support For questions or issues: + 1. Check the documentation 2. Run the tests 3. Open a GitHub issue --- -**Note**: This is an educational project. For production use, consider security audits and more robust implementations. \ No newline at end of file +**Note**: This is an educational project. For production use, consider security audits and more robust implementations. From 384aacd917d612f9f3a676bf8309b8c3b814db04 Mon Sep 17 00:00:00 2001 From: Nuno Date: Tue, 16 Sep 2025 16:43:57 +0100 Subject: [PATCH 21/29] feat: a few fixes in README --- README.md | 2 +- docs/privateSwaps.md | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 516b141..d960d4f 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ ## 📌 Key Notes -- More details about circom and zkSNARK [here](./packages/circom/README.md) +- More details about circom and zkSNARK implementation [here](./packages/circom/README.md) - Private swap commitments and encrypted payloads are currently fully stored on-chain, but they could be stored in EigenDA with only lightweight references on-chain to reduce gas costs and improve scalability without compromising verifiability. - Only the beforeSwap hook is used, but the logic can be extended to beforeAddLiquidity as well. - The two features — Suitability Verifier and Private Swap Commitments — are independent, though private swap execution could optionally require passing the suitability check. diff --git a/docs/privateSwaps.md b/docs/privateSwaps.md index e444970..74616ec 100644 --- a/docs/privateSwaps.md +++ b/docs/privateSwaps.md @@ -33,7 +33,6 @@ Key use cases include: - Calls `storeCommitment(id, ciphertext, permit)` with: - `id`: unique hash of the commitment. - `ciphertext`: encrypted swap details (amount, direction, timestamp). - - `encKeyForAuditor`: ECIES encryption key for auditor. - `permit`: ERC20 permit signature. - Contract records commitment and emits `CommitmentStored`. @@ -69,7 +68,7 @@ Key use cases include: - **Auditor** can always: - - Read `ciphertext` + `encKeyForAuditor` onchain. + - Read `ciphertext` onchain. - Decrypt using it's own private key. - Verify swap parameters offchain for compliance. - Validates if permit matches the encrypted values From f2d86dc9805de8d4136e8e2c0a8280e7257761d7 Mon Sep 17 00:00:00 2001 From: Nuno Date: Tue, 16 Sep 2025 17:05:17 +0100 Subject: [PATCH 22/29] feat: more README --- README.md | 4 ++-- docs/privateSwaps.md | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index d960d4f..54ab7e8 100644 --- a/README.md +++ b/README.md @@ -16,9 +16,9 @@ **Rayls Hook** introduces two complementary ZK-SNARK enabled features built on Uniswap v4 hooks: -1. [🛡️ Suitability Verifier Logic](./docs/suitability.md) (click for more info) – A privacy-preserving investor suitability assessment system. It allows users to prove their investment suitability without revealing their specific questionnaire responses using Zero-Knowledge Proofs. +1. [🛡️ Suitability Verifier](./docs/suitability.md) (click for more info) – A privacy-preserving investor suitability assessment system. It allows users to prove their investment suitability without revealing their specific questionnaire responses using Zero-Knowledge Proofs. -2. [🔐 Private Swap Logic](./docs/privateSwaps.md) (click for more info) – Private swaps with an execution timestamp. Swap values remain hidden and are committed on-chain through a commitment Id, then later revealed, validated and executed with zkSNARK proofs. The values are also encrypted (ECIES) using an Auditor’s wallet public key (optional) and the generated ciphertext is stored on-chain, enabling the Auditor to independently verify commitments at any time. +2. [🔐 Private Swaps](./docs/privateSwaps.md) (click for more info) – Private swaps that allow users to conceal their swap parameters until an execution timestamp is reached. Hidden swap values are committed on-chain via a unique commitment ID, then at execution time they are revealed and validated using zkSNARK proofs. Swap details are also encrypted using the Auditor’s public key and the generated ciphertext is stored on-chain, enabling independent verification at any time. The commitment Id is the result of running the cryptographic function keccak256 against the auditor ciphertext and the poseidon hash generated by the zk snark proof. ## 📌 Key Notes diff --git a/docs/privateSwaps.md b/docs/privateSwaps.md index 74616ec..90048c4 100644 --- a/docs/privateSwaps.md +++ b/docs/privateSwaps.md @@ -2,15 +2,15 @@ 🔐 Private Swap Commitments -This Uniswap v4 hook extension introduces private swaps that allow users to conceal their swap parameters until an execution timestamp is reached. Hidden swap values are committed on-chain via a unique commitment ID, then later revealed, validated with zkSNARK proofs and the swap is executed. Swap details are also encrypted with an Auditor’s public key and the ciphertext is stored on-chain, enabling independent verification at any time. The commitment Id is the result of runnig the cryptographic function keccak256 against the auditor ciphertext and the posedion hash generated by the zk snark proof. +This Uniswap v4 hook extension introduces private swaps that allow users to conceal their swap parameters until an execution timestamp is reached. Hidden swap values are committed on-chain via a unique commitment ID, then at execution time they are revealed and validated using zkSNARK proofs. Swap details are also encrypted using the Auditor’s public key and the generated ciphertext is stored on-chain, enabling independent verification at any time. The commitment Id is the result of running the cryptographic function keccak256 against the auditor ciphertext and the poseidon hash generated by the zk snark proof. Key use cases include: -- MEV protection – hiding swap intent reduces frontrunning risk; at reveal time, private bundlers can be used for additional protection. +- MEV protection – hiding swap intent reduces frontrunning risk. -- Large swaps – users executing large trades can split them into multiple commitments to minimize pool price impact. +- Large swaps – users executing large trades can split them into multiple commitments to minimize token price impact in the pool. -- Compliance & oversight – DAOs and regulated protocols can prove swap schedules on-chain, with auditors able to verify encrypted commitments. +- Compliance & oversight – DAOs and regulated protocols can prove onchain to an auditor the agreed swap schedules according to the defined tokenomics. ## 🔄 Flow @@ -79,3 +79,4 @@ Key use cases include: - We use circom for zksnark and AES encryption for the auditor. Encryption in circom is too expensive. - We could enforce the auditor to approve a commitement cancelation. +- When calling executeCommitment, Rayls Middleware would use private bundlers for additional MEV protection. From 4b1313bca5df5a4c9f154c8f52773ca241565c08 Mon Sep 17 00:00:00 2001 From: Nuno Date: Tue, 16 Sep 2025 17:22:54 +0100 Subject: [PATCH 23/29] feat: more content --- README.md | 2 +- docs/privateSwaps.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 54ab7e8..8eb1f41 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ ## 📌 Key Notes - More details about circom and zkSNARK implementation [here](./packages/circom/README.md) -- Private swap commitments and encrypted payloads are currently fully stored on-chain, but they could be stored in EigenDA with only lightweight references on-chain to reduce gas costs and improve scalability without compromising verifiability. +- There's no partner integration but although Private swap commitments and encrypted payloads are currently fully stored on-chain, they could be stored in EigenDA with only lightweight references on-chain to reduce gas costs and improve scalability without compromising verifiability. - Only the beforeSwap hook is used, but the logic can be extended to beforeAddLiquidity as well. - The two features — Suitability Verifier and Private Swap Commitments — are independent, though private swap execution could optionally require passing the suitability check. diff --git a/docs/privateSwaps.md b/docs/privateSwaps.md index 90048c4..19a8dfc 100644 --- a/docs/privateSwaps.md +++ b/docs/privateSwaps.md @@ -8,7 +8,7 @@ Key use cases include: - MEV protection – hiding swap intent reduces frontrunning risk. -- Large swaps – users executing large trades can split them into multiple commitments to minimize token price impact in the pool. +- Large swaps without price impact – users executing large trades can split them into multiple commitments to minimize token price impact in the pool. - Compliance & oversight – DAOs and regulated protocols can prove onchain to an auditor the agreed swap schedules according to the defined tokenomics. @@ -27,7 +27,7 @@ Key use cases include: - **Rayls Middleware** - - Encrypts swap params using Auditor's pub key. + - Encrypts swap params using Auditor's pub key (file encrypt.js). - Creates and holds zkSNARK proofs of knowledge of swap params for commitment `id`.. - Generates commitment id using Auditor's encryption + Poseidon hash from zk proof. - Calls `storeCommitment(id, ciphertext, permit)` with: @@ -69,7 +69,7 @@ Key use cases include: - **Auditor** can always: - Read `ciphertext` onchain. - - Decrypt using it's own private key. + - Decrypt using it's own private key (file decrypt.js). - Verify swap parameters offchain for compliance. - Validates if permit matches the encrypted values From 8cb6232843925499a881f49c786914a481f438fa Mon Sep 17 00:00:00 2001 From: Nuno Date: Wed, 17 Sep 2025 11:45:00 +0100 Subject: [PATCH 24/29] feat: adding more content --- docs/privateSwaps.md | 2 +- packages/circom/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/privateSwaps.md b/docs/privateSwaps.md index 19a8dfc..dbb4847 100644 --- a/docs/privateSwaps.md +++ b/docs/privateSwaps.md @@ -8,7 +8,7 @@ Key use cases include: - MEV protection – hiding swap intent reduces frontrunning risk. -- Large swaps without price impact – users executing large trades can split them into multiple commitments to minimize token price impact in the pool. +- Price impact mitigation for large swaps – users executing large trades can split them into multiple commitments to minimize token price impact in the pool. - Compliance & oversight – DAOs and regulated protocols can prove onchain to an auditor the agreed swap schedules according to the defined tokenomics. diff --git a/packages/circom/README.md b/packages/circom/README.md index b2ce9a0..e26753b 100644 --- a/packages/circom/README.md +++ b/packages/circom/README.md @@ -48,7 +48,7 @@ The private swap intent circuit implements: - **Private inputs**: amount, direction, sender, timestamp - **Public outputs**: poseidon hash and public parameters -- **Purpose**: Prove swap intent without revealing sensitive details +- **Purpose**: Prove it knows valid private inputs (swap params) that hash to the poseidon hash, without revealing sensitive details ## 🚀 Installation and Setup From e580d22e9cdc97e0dc7f373120e44694a12f9b45 Mon Sep 17 00:00:00 2001 From: Nuno Date: Wed, 17 Sep 2025 13:04:27 +0100 Subject: [PATCH 25/29] feat: adding questionaire png --- README.md | 1 + docs/SuitabilityQuestionaire.png | Bin 0 -> 73586 bytes docs/suitability.md | 6 +++++- 3 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 docs/SuitabilityQuestionaire.png diff --git a/README.md b/README.md index 8eb1f41..03ed54c 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ - There's no partner integration but although Private swap commitments and encrypted payloads are currently fully stored on-chain, they could be stored in EigenDA with only lightweight references on-chain to reduce gas costs and improve scalability without compromising verifiability. - Only the beforeSwap hook is used, but the logic can be extended to beforeAddLiquidity as well. - The two features — Suitability Verifier and Private Swap Commitments — are independent, though private swap execution could optionally require passing the suitability check. +- The frontend provides an example of a Suitability questionaire, but there's currently no FE->BE integration. ## 🎯 Project Overview diff --git a/docs/SuitabilityQuestionaire.png b/docs/SuitabilityQuestionaire.png new file mode 100644 index 0000000000000000000000000000000000000000..950de02a3ff3124b1de4278beeea12691aa12651 GIT binary patch literal 73586 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 S%)os$$T&||KbLh*2~7a6%u}rZ literal 0 HcmV?d00001 diff --git a/docs/suitability.md b/docs/suitability.md index e46de90..f0dfdb4 100644 --- a/docs/suitability.md +++ b/docs/suitability.md @@ -2,10 +2,14 @@ The Suitability Verifier Logic ensures that **investors can prove compliance** with regulatory requirements without revealing their raw questionnaire responses. This is done using a **zkSNARK proof**. +

+ Suitability Questionnaire +

+ ## 🔄 Flow

- Suitability Diagram + Suitability Diagram

1. **Investor (User)** From 43444ad9fa89d4f04c50d4d054279f886c918fac Mon Sep 17 00:00:00 2001 From: Nuno Date: Wed, 17 Sep 2025 13:05:49 +0100 Subject: [PATCH 26/29] feat: increase image width --- docs/suitability.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/suitability.md b/docs/suitability.md index f0dfdb4..4e77327 100644 --- a/docs/suitability.md +++ b/docs/suitability.md @@ -3,13 +3,13 @@ The Suitability Verifier Logic ensures that **investors can prove compliance** with regulatory requirements without revealing their raw questionnaire responses. This is done using a **zkSNARK proof**.

- Suitability Questionnaire + Suitability Questionnaire

## 🔄 Flow

- Suitability Diagram + Suitability Diagram

1. **Investor (User)** From b091ff1e1a04af6dbdac6dd738d3a9dd22a84abc Mon Sep 17 00:00:00 2001 From: Nuno Date: Wed, 17 Sep 2025 13:55:29 +0100 Subject: [PATCH 27/29] feat: changing id to commitmentId for clarity --- packages/foundry/contracts/RaylsHook.sol | 52 ++++++++++++----------- packages/foundry/test/RaylsHook.t.sol | 53 ++++++++++++------------ 2 files changed, 55 insertions(+), 50 deletions(-) diff --git a/packages/foundry/contracts/RaylsHook.sol b/packages/foundry/contracts/RaylsHook.sol index 7d1ac7f..e286f08 100644 --- a/packages/foundry/contracts/RaylsHook.sol +++ b/packages/foundry/contracts/RaylsHook.sol @@ -47,7 +47,7 @@ contract RaylsHook is BaseHook, IUnlockCallback, ReentrancyGuard { event CommitmentCancelled(uint256 indexed id, address indexed canceller); // Errors - error CommitmentMismatch(bytes pubId, uint256 expectedId); + error CommitmentMismatch(bytes32 pubId, uint256 expectedId); error CommitmentNotReady(uint256 notBefore, uint256 currentTime); error InvalidWallet(address provided, address expected); error InvalidSuitabilityProof(); @@ -133,24 +133,24 @@ contract RaylsHook is BaseHook, IUnlockCallback, ReentrancyGuard { * Reverts if a commitment with the same `id` already exists. * The ciphertextForAuditor allows a designated auditor to decrypt the swap parameters offchain. * @param key Pool key identifying the Uniswap v4 pool this commitment belongs to. - * @param id Unique identifier for the commitment (Poseidon/keccak hash). + * @param commitmentId Unique identifier for the commitment (Poseidon/keccak hash). * @param ciphertextForAuditor Encrypted swap data for the auditor * @param permit ERC20 permit signature data, allowing token transfers at execution. * Emits a {CommitmentStored} event. */ function storeCommitment( PoolKey calldata key, - uint256 id, + uint256 commitmentId, bytes calldata ciphertextForAuditor, bytes calldata permit ) external { - if (commitments[key.toId()][id].status != CommitmentStatus.None) { - revert AlreadyExists(id); + if (commitments[key.toId()][commitmentId].status != CommitmentStatus.None) { + revert AlreadyExists(commitmentId); } - commitments[key.toId()][id] = + commitments[key.toId()][commitmentId] = Commitment({ ciphertextForAuditor: ciphertextForAuditor, permit: permit, status: CommitmentStatus.Active }); - emit CommitmentStored(id, msg.sender, ciphertextForAuditor, permit); + emit CommitmentStored(commitmentId, msg.sender, ciphertextForAuditor, permit); } /** @@ -159,24 +159,24 @@ contract RaylsHook is BaseHook, IUnlockCallback, ReentrancyGuard { * Reverts if the commitment does not exist, was already executed, or already canceled. * Large storage fields may be cleared to save gas, but the status is retained for auditability. * @param key Pool key identifying the Uniswap v4 pool this commitment belongs to. - * @param id Unique identifier of the commitment to cancel. + * @param commitmentId Unique identifier of the commitment to cancel. * @param zkSnarkProof ABI-encoded zkSNARK proof data (pA, pB, pC, pubSignals) to authorize the cancellation. * Emits a {CommitmentCancelled} event. */ - function cancelCommitment(PoolKey calldata key, uint256 id, bytes calldata zkSnarkProof) external { - Commitment storage c = commitments[key.toId()][id]; + function cancelCommitment(PoolKey calldata key, uint256 commitmentId, bytes calldata zkSnarkProof) external { + Commitment storage c = commitments[key.toId()][commitmentId]; if (c.status != CommitmentStatus.Active) { - revert CommitmentNotActive(id); + revert CommitmentNotActive(commitmentId); } (uint256[2] memory pA, uint256[2][2] memory pB, uint256[2] memory pC, uint256[5] memory pubSignals) = abi.decode(zkSnarkProof, (uint256[2], uint256[2][2], uint256[2], uint256[5])); // Making sure we are executing the right commitment - bytes memory commitmentId = abi.encode(pubSignals[0], c.ciphertextForAuditor); + bytes32 commitmentIdFromZK = getCommitmentId(pubSignals[0], c.ciphertextForAuditor); - if (keccak256(commitmentId) != bytes32(id)) { - revert CommitmentMismatch(commitmentId, id); + if (commitmentIdFromZK != bytes32(commitmentId)) { + revert CommitmentMismatch(commitmentIdFromZK, commitmentId); } bool privateVerifierOk = privateSwapIntentVerifier.verifyProof(pA, pB, pC, pubSignals); @@ -188,7 +188,7 @@ contract RaylsHook is BaseHook, IUnlockCallback, ReentrancyGuard { c.status = CommitmentStatus.Cancelled; delete c.ciphertextForAuditor; delete c.permit; - emit CommitmentCancelled(id, msg.sender); + emit CommitmentCancelled(commitmentId, msg.sender); } /** @@ -198,22 +198,22 @@ contract RaylsHook is BaseHook, IUnlockCallback, ReentrancyGuard { * It uses ERC20 permit to pull tokens from the original sender, then executes a Uniswap v4 swap through * the PoolManager. Marks the commitment as executed to prevent replay. * @param key Pool key identifying the Uniswap v4 pool this commitment belongs to. - * @param id Unique identifier of the commitment to execute. + * @param commitmentId Unique identifier of the commitment to execute. * @param zkSnarkProof ABI-encoded zkSNARK proof data (pA, pB, pC, pubSignals) to authorize the execution. * @return delta Net balance delta returned from the swap execution. * Emits a {CommitmentExecuted} event (if you add one). */ - function executeCommitment(PoolKey calldata key, uint256 id, bytes calldata zkSnarkProof) + function executeCommitment(PoolKey calldata key, uint256 commitmentId, bytes calldata zkSnarkProof) external nonReentrant returns (BalanceDelta) { - Commitment storage commitment = commitments[key.toId()][id]; + Commitment storage commitment = commitments[key.toId()][commitmentId]; if (commitment.status == CommitmentStatus.None) { - revert CommitmentNotFound(id); + revert CommitmentNotFound(commitmentId); } if (commitment.status != CommitmentStatus.Active) { - revert CommitmentNotActive(id); + revert CommitmentNotActive(commitmentId); } (uint256[2] memory pA, uint256[2][2] memory pB, uint256[2] memory pC, uint256[5] memory pubSignals) = @@ -224,13 +224,13 @@ contract RaylsHook is BaseHook, IUnlockCallback, ReentrancyGuard { } // Making sure we are executing the right commitment - bytes memory commitmentId = abi.encode( + bytes32 commitmentIdFromZK = getCommitmentId( pubSignals[0], // Poseidon hash commitment.ciphertextForAuditor ); - if (keccak256(commitmentId) != bytes32(id)) { - revert CommitmentMismatch(commitmentId, id); + if (commitmentIdFromZK != bytes32(commitmentId)) { + revert CommitmentMismatch(commitmentIdFromZK, commitmentId); } bool privateVerifierOk = privateSwapIntentVerifier.verifyProof(pA, pB, pC, pubSignals); @@ -270,7 +270,7 @@ contract RaylsHook is BaseHook, IUnlockCallback, ReentrancyGuard { ); (BalanceDelta delta) = abi.decode(callbackReturn, (BalanceDelta)); - emit CommitmentExecuted(id, msg.sender); + emit CommitmentExecuted(commitmentId, msg.sender); return delta; } @@ -350,4 +350,8 @@ contract RaylsHook is BaseHook, IUnlockCallback, ReentrancyGuard { origin_ = abi.decode(data, (address)); } } + + function getCommitmentId(uint256 poseidonHash, bytes memory cipherText) public pure returns (bytes32) { + return keccak256(abi.encode(poseidonHash, cipherText)); + } } diff --git a/packages/foundry/test/RaylsHook.t.sol b/packages/foundry/test/RaylsHook.t.sol index 8e3707b..907424b 100644 --- a/packages/foundry/test/RaylsHook.t.sol +++ b/packages/foundry/test/RaylsHook.t.sol @@ -251,7 +251,7 @@ contract RaylsHookTest is Test, Deployers { bytes memory ciphertextForAuditor = RaylsHookHelper.getJsonCiphertext(jsonEncryptedPayload); // Calculate the commitment ID off-chain using both the ZK Snark Poseidon Hash and the ciphertext - uint256 id = uint256(keccak256(abi.encode(proofCorrect.poseidonHash, ciphertextForAuditor))); + uint256 commitmentId = uint256(hook.getCommitmentId(proofCorrect.poseidonHash, ciphertextForAuditor)); // Store the commitment on-chain vm.startPrank(proofSender, proofSender); @@ -267,22 +267,22 @@ contract RaylsHookTest is Test, Deployers { ); // Call the hook to store the commitment - hook.storeCommitment(poolKey, id, ciphertextForAuditor, permitSignature); + hook.storeCommitment(poolKey, commitmentId, ciphertextForAuditor, permitSignature); // Revert if already exsits - bytes memory expectedRevert = abi.encodeWithSelector(RaylsHook.AlreadyExists.selector, id); + bytes memory expectedRevert = abi.encodeWithSelector(RaylsHook.AlreadyExists.selector, commitmentId); vm.expectRevert(expectedRevert); - hook.storeCommitment(poolKey, id, ciphertextForAuditor, permitSignature); + hook.storeCommitment(poolKey, commitmentId, ciphertextForAuditor, permitSignature); // For now we just approve the swapRouter to spend the tokens // IERC20Minimal(Currency.unwrap(currency0)).approve(address(hook), amountIn); - // Move time forward but not enough to be able to execute the commitment + // Move time forward but not enough to be able tcommitmentIdo execute the commitment vm.warp(proofCorrect.timestamp - 1); expectedRevert = abi.encodeWithSelector(RaylsHook.CommitmentNotReady.selector, proofCorrect.timestamp, block.timestamp); vm.expectRevert(expectedRevert); - hook.executeCommitment(poolKey, id, proofCorrect.proofData); + hook.executeCommitment(poolKey, commitmentId, proofCorrect.proofData); // Move time forward to be able to execute the commitment vm.warp(proofCorrect.timestamp); @@ -296,30 +296,31 @@ contract RaylsHookTest is Test, Deployers { // Revert if the public signal poseidon hash is invalid RaylsHookHelper.PrivateSwapPublic memory proofWithWrongHash = RaylsHookHelper.getPublicSignalsFromPrivateSwapIntentProof(jsonPrivateSwap, false, true); - bytes memory fakeCommitmentId = abi.encode(proofWithWrongHash.poseidonHash, ciphertextForAuditor); - expectedRevert = abi.encodeWithSelector(RaylsHook.CommitmentMismatch.selector, fakeCommitmentId, id); + bytes32 fakeCommitmentId = hook.getCommitmentId(proofWithWrongHash.poseidonHash, ciphertextForAuditor); + expectedRevert = abi.encodeWithSelector(RaylsHook.CommitmentMismatch.selector, fakeCommitmentId, commitmentId); vm.expectRevert(expectedRevert); - hook.executeCommitment(poolKey, id, proofWithWrongHash.proofData); + hook.executeCommitment(poolKey, commitmentId, proofWithWrongHash.proofData); // Revert if the proof is invalid RaylsHookHelper.PrivateSwapPublic memory proofWithWrongPA = RaylsHookHelper.getPublicSignalsFromPrivateSwapIntentProof(jsonPrivateSwap, true, false); expectedRevert = abi.encodeWithSelector(RaylsHook.InvalidPrivateSwapIntentProof.selector); vm.expectRevert(expectedRevert); - hook.executeCommitment(poolKey, id, proofWithWrongPA.proofData); + hook.executeCommitment(poolKey, commitmentId, proofWithWrongPA.proofData); // Execute the commitment successfully - BalanceDelta delta = hook.executeCommitment(poolKey, id, proofCorrect.proofData); + BalanceDelta delta = hook.executeCommitment(poolKey, commitmentId, proofCorrect.proofData); assertEq(int256(delta.amount0()), -int256(proofCorrect.amountIn)); // Revert if we want to execute it again - expectedRevert = abi.encodeWithSelector(RaylsHook.CommitmentNotActive.selector, id); + expectedRevert = abi.encodeWithSelector(RaylsHook.CommitmentNotActive.selector, commitmentId); vm.expectRevert(expectedRevert); - hook.executeCommitment(poolKey, id, proofCorrect.proofData); + hook.executeCommitment(poolKey, commitmentId, proofCorrect.proofData); vm.stopPrank(); // Test the auditor part - (bytes memory onChainCiphertext,, RaylsHook.CommitmentStatus status) = hook.commitments(poolKey.toId(), id); + (bytes memory onChainCiphertext,, RaylsHook.CommitmentStatus status) = + hook.commitments(poolKey.toId(), commitmentId); assertEq(uint8(status), uint8(RaylsHook.CommitmentStatus.Executed)); assertEq(onChainCiphertext, ciphertextForAuditor); @@ -386,7 +387,7 @@ contract RaylsHookTest is Test, Deployers { bytes memory ciphertextForAuditor = RaylsHookHelper.getJsonCiphertext(jsonEncryptedPayload); // Calculate the commitment ID off-chain using both the ZK Snark Poseidon Hash and the ciphertext - uint256 id = uint256(keccak256(abi.encode(proofCorrect.poseidonHash, ciphertextForAuditor))); + uint256 commitmentId = uint256(hook.getCommitmentId(proofCorrect.poseidonHash, ciphertextForAuditor)); // Store the commitment on-chain vm.startPrank(proofSender, proofSender); @@ -402,42 +403,42 @@ contract RaylsHookTest is Test, Deployers { ); // Call the hook to store the commitment - hook.storeCommitment(poolKey, id, ciphertextForAuditor, permitSignature); + hook.storeCommitment(poolKey, commitmentId, ciphertextForAuditor, permitSignature); // Revert if the public signal poseidon hash is invalid RaylsHookHelper.PrivateSwapPublic memory proofWithWrongHash = RaylsHookHelper.getPublicSignalsFromPrivateSwapIntentProof(jsonPrivateSwap, false, true); - bytes memory fakeCommitmentId = abi.encode(proofWithWrongHash.poseidonHash, ciphertextForAuditor); + bytes32 fakeCommitmentId = hook.getCommitmentId(proofWithWrongHash.poseidonHash, ciphertextForAuditor); bytes memory expectedRevert = - abi.encodeWithSelector(RaylsHook.CommitmentMismatch.selector, fakeCommitmentId, id); + abi.encodeWithSelector(RaylsHook.CommitmentMismatch.selector, fakeCommitmentId, commitmentId); vm.expectRevert(expectedRevert); - hook.cancelCommitment(poolKey, id, proofWithWrongHash.proofData); + hook.cancelCommitment(poolKey, commitmentId, proofWithWrongHash.proofData); // Revert if the proof is invalid RaylsHookHelper.PrivateSwapPublic memory proofWithWrongPA = RaylsHookHelper.getPublicSignalsFromPrivateSwapIntentProof(jsonPrivateSwap, true, false); expectedRevert = abi.encodeWithSelector(RaylsHook.InvalidPrivateSwapIntentProof.selector); vm.expectRevert(expectedRevert); - hook.cancelCommitment(poolKey, id, proofWithWrongPA.proofData); + hook.cancelCommitment(poolKey, commitmentId, proofWithWrongPA.proofData); // Cancel it before it can be executed - hook.cancelCommitment(poolKey, id, proofCorrect.proofData); + hook.cancelCommitment(poolKey, commitmentId, proofCorrect.proofData); // Cancel it again shoule revvert - expectedRevert = abi.encodeWithSelector(RaylsHook.CommitmentNotActive.selector, id); + expectedRevert = abi.encodeWithSelector(RaylsHook.CommitmentNotActive.selector, commitmentId); vm.expectRevert(expectedRevert); - hook.cancelCommitment(poolKey, id, proofCorrect.proofData); + hook.cancelCommitment(poolKey, commitmentId, proofCorrect.proofData); // Move time forward to be able to execute the commitment vm.warp(proofCorrect.timestamp + 1); // Revert if we try to execute a cancelled commitment - expectedRevert = abi.encodeWithSelector(RaylsHook.CommitmentNotActive.selector, id); + expectedRevert = abi.encodeWithSelector(RaylsHook.CommitmentNotActive.selector, commitmentId); vm.expectRevert(expectedRevert); - hook.executeCommitment(poolKey, id, proofCorrect.proofData); + hook.executeCommitment(poolKey, commitmentId, proofCorrect.proofData); vm.stopPrank(); - (,, RaylsHook.CommitmentStatus status) = hook.commitments(poolKey.toId(), id); + (,, RaylsHook.CommitmentStatus status) = hook.commitments(poolKey.toId(), commitmentId); assertEq(uint8(status), uint8(RaylsHook.CommitmentStatus.Cancelled)); } From 5e63300bd24f26059cb21b4ab3a384d4a258b4a7 Mon Sep 17 00:00:00 2001 From: Nuno Date: Thu, 18 Sep 2025 09:57:52 +0100 Subject: [PATCH 28/29] feat: adding block diagram for private swaps --- docs/RaylsHook_private_swaps_block_diagram.svg | 1 + docs/privateSwaps.md | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 docs/RaylsHook_private_swaps_block_diagram.svg diff --git a/docs/RaylsHook_private_swaps_block_diagram.svg b/docs/RaylsHook_private_swaps_block_diagram.svg new file mode 100644 index 0000000..11099fe --- /dev/null +++ b/docs/RaylsHook_private_swaps_block_diagram.svg @@ -0,0 +1 @@ +

Start
Private Swap Flow

User

RAYLS Middleware

RAYLS Uniswap Hook

Pool Manager

Auditor (optional)

creates swap commitment

executes swap

reads ciphertext

executeCommitment

storeCommitment

cancelCommitment

\ No newline at end of file diff --git a/docs/privateSwaps.md b/docs/privateSwaps.md index dbb4847..21a96b1 100644 --- a/docs/privateSwaps.md +++ b/docs/privateSwaps.md @@ -12,6 +12,10 @@ Key use cases include: - Compliance & oversight – DAOs and regulated protocols can prove onchain to an auditor the agreed swap schedules according to the defined tokenomics. +

+ Private Swap Block Diagram +

+ ## 🔄 Flow

@@ -77,6 +81,12 @@ Key use cases include: ## Key notes -- We use circom for zksnark and AES encryption for the auditor. Encryption in circom is too expensive. +- We use circom for zkSNARK and ECIES encryption for the auditor (using nodejs scripts). Encryption in circom is too expensive. - We could enforce the auditor to approve a commitement cancelation. - When calling executeCommitment, Rayls Middleware would use private bundlers for additional MEV protection. + +## Future Extensions and Use Cases + +- Decentralized Executors: Anyone could register as an executor and earn a percentage of swap fees for executing commitments, creating an open marketplace of executors. +- Auditor-Gated Cancellation: Cancellation requests could require auditor approval, preventing users from revoking commitments that already passed compliance checks. +- Multi-Auditor Support: Commitments could be associated with multiple auditors, allowing collaborative oversight or redundancy in regulatory validation. From 463a2daaf65f5983b165619bf8f908261602ad1d Mon Sep 17 00:00:00 2001 From: Nuno Date: Thu, 18 Sep 2025 11:05:49 +0100 Subject: [PATCH 29/29] feat: slight change in README --- README.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 03ed54c..883424e 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,13 @@ Before you begin, you need to install the following tools: - [Git](https://git-scm.com/downloads) - [Circom](https://docs.circom.io/getting-started/installation/) (for ZK circuits) - [SnarkJS](https://github.com/iden3/snarkjs) (for ZK proofs) +- [Foundry](https://getfoundry.sh/introduction/installation/) + +To better run circom you might need to add this to your PATH: + +```bash +export PATH=$PATH:$HOME/.cargo/bin +``` ## 🚀 Quick Start @@ -109,7 +116,7 @@ To get started with Rayls Hook, follow these steps: ```bash # Clone the repository git clone https://github.com/raylsnetwork/uniswap-incubator.git -cd rayls-hook +cd uniswap-incubator # Install all dependencies yarn install @@ -119,7 +126,7 @@ yarn install ```bash # Start local Ethereum network (Scaffold-ETH 2) -yarn workspace foundry chain +yarn workspace @se-2/foundry chain ``` This command starts a local Ethereum network using Foundry. The network runs on your local machine and can be used for testing and development. @@ -128,8 +135,8 @@ This command starts a local Ethereum network using Foundry. The network runs on ```bash # Or setup specific circuits -yarn workspace circom setup-suitability # Suitability assessment circuit -yarn workspace circom setup-private-swap # Private swap intent circuit +yarn workspace rayls-hook-circom setup-suitability # Suitability assessment circuit +yarn workspace rayls-hook-circom setup-private-swap # Private swap intent circuit ``` ### 4. Deploy Smart Contracts