diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index dd9fd98afe..0000000000 --- a/.gitmodules +++ /dev/null @@ -1,12 +0,0 @@ -[submodule "evm/lib/forge-std"] - path = evm/lib/forge-std - url = https://github.com/foundry-rs/forge-std -[submodule "evm/lib/openzeppelin-contracts"] - path = evm/lib/openzeppelin-contracts - url = https://github.com/OpenZeppelin/openzeppelin-contracts -[submodule "evm/lib/openzeppelin-contracts-upgradeable"] - path = evm/lib/openzeppelin-contracts-upgradeable - url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable -[submodule "evm/lib/openzeppelin-foundry-upgrades"] - path = evm/lib/openzeppelin-foundry-upgrades - url = https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades diff --git a/README.md b/README.md index 9e094675e0..36c9e24f94 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,6 @@ The VDP Framework is divided into the following modules: - **Partial verification** is necessary when leveraging the zkVM, maintaining high performance by partially verifying proofs in a replicated compute platform to minimise ZK proving times. - **Full verification** is only necessary when the data processed is public, which is rare as the zkVM is designed to maintain data privacy and roll up various TLS attestations into a single succinct proof. - `verify-local`: Performs TLS proof verification by combining remote verification of public facets, with private facets of the TLS proof. Designs specifically for zkVM guest environment. -- `evm`: Smart Contracts templates for integrating various chains in an app-specific multi-chain protocol powered by the IC and Verity. - `examples`: Examples of how to use the Verity Data Processor Framework to generate zkTLS proofs. - `zk`: Utilities and tests supporting zkVM usage. diff --git a/evm/.env.sample b/evm/.env.sample deleted file mode 100644 index 0d8600efb8..0000000000 --- a/evm/.env.sample +++ /dev/null @@ -1,12 +0,0 @@ -# rpc parameters -RPC_URL=http://localhost:8545 -PRIVATE_KEY= - -# deployment parameters -DEPLOY_REMITTANCE_CANISTER_PUBKEY= -DEPLOY_CHAIN_IDENTIFIER=ethereum:1 - -# Parameters ret upgrade -UPGRADE_CONTRACT_ADDRESS= -UPGRADE_OLD_CONTRACT_NAME="Locker.sol" -UPGRADE_NEW_CONTRACT_NAME="LockerV2.sol" \ No newline at end of file diff --git a/evm/.github/workflows/test.yml b/evm/.github/workflows/test.yml deleted file mode 100644 index 9282e82944..0000000000 --- a/evm/.github/workflows/test.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: test - -on: workflow_dispatch - -env: - FOUNDRY_PROFILE: ci - -jobs: - check: - strategy: - fail-fast: true - - name: Foundry project - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - submodules: recursive - - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - with: - version: nightly - - - name: Run Forge build - run: | - forge --version - forge build --sizes - id: build - - - name: Run Forge tests - run: | - forge test -vvv - id: test diff --git a/evm/.gitignore b/evm/.gitignore deleted file mode 100644 index 85198aaa55..0000000000 --- a/evm/.gitignore +++ /dev/null @@ -1,14 +0,0 @@ -# Compiler files -cache/ -out/ - -# Ignores development broadcast logs -!/broadcast -/broadcast/*/31337/ -/broadcast/**/dry-run/ - -# Docs -docs/ - -# Dotenv file -.env diff --git a/evm/README.md b/evm/README.md deleted file mode 100644 index 609d60b700..0000000000 --- a/evm/README.md +++ /dev/null @@ -1,91 +0,0 @@ -## EVM -This Project is made with foundry and contains the contracts relevant to the protocol. - -**Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.** - -Foundry consists of: - -- **Forge**: Ethereum testing framework (like Truffle, Hardhat and DappTools). -- **Cast**: Swiss army knife for interacting with EVM smart contracts, sending transactions and getting chain data. -- **Anvil**: Local Ethereum node, akin to Ganache, Hardhat Network. -- **Chisel**: Fast, utilitarian, and verbose solidity REPL. - -## Documentation - -https://book.getfoundry.sh/ - -## Usage - -Update the submodules first -```shell -git submodule update --init --recursive -``` - -### Build - -```shell -forge build -``` - -### Test - -```shell -forge test -``` - -### Format - -```shell -forge fmt -``` - -### Gas Snapshots - -```shell -forge snapshot -``` - -### Anvil - -```shell -anvil -``` - -### Deploy - -```shell -source . -forge clean -forge script script/DeployLocker.s.sol:DeployLocker \ - --rpc-url $RPC_URL \ - --broadcast \ - --private-key $PRIVATE_KEY \ - --force -``` - - -### Upgrade - -```shell -source . -forge clean -forge script script/UpgradeLocker.s.sol:DeployLocker \ - --rpc-url $RPC_URL \ - --broadcast \ - --private-key $PRIVATE_KEY \ - --force -``` - -### Cast - -```shell -cast -``` - -### Help - -```shell -forge --help -anvil --help -cast --help -``` diff --git a/evm/foundry.toml b/evm/foundry.toml deleted file mode 100644 index 3f3788969e..0000000000 --- a/evm/foundry.toml +++ /dev/null @@ -1,11 +0,0 @@ -[profile.default] -src = "src" -out = "out" -libs = ["lib"] -ffi = true -ast = true -build_info = true -extra_output = ["storageLayout"] - - -# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options diff --git a/evm/lib/forge-std b/evm/lib/forge-std deleted file mode 160000 index d3db4ef90a..0000000000 --- a/evm/lib/forge-std +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d3db4ef90a72b7d24aa5a2e5c649593eaef7801d diff --git a/evm/lib/openzeppelin-contracts b/evm/lib/openzeppelin-contracts deleted file mode 160000 index 0643d17e8d..0000000000 --- a/evm/lib/openzeppelin-contracts +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 0643d17e8d9640df803c5d256c53d458c4c6008d diff --git a/evm/lib/openzeppelin-contracts-upgradeable b/evm/lib/openzeppelin-contracts-upgradeable deleted file mode 160000 index 7f46c690d2..0000000000 --- a/evm/lib/openzeppelin-contracts-upgradeable +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 7f46c690d2fe714e4a51eed4b1a601d9678b9b92 diff --git a/evm/lib/openzeppelin-foundry-upgrades b/evm/lib/openzeppelin-foundry-upgrades deleted file mode 160000 index 6461ba3851..0000000000 --- a/evm/lib/openzeppelin-foundry-upgrades +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 6461ba3851dea1fa4381a0fb1477c669279cdd44 diff --git a/evm/remappings.txt b/evm/remappings.txt deleted file mode 100644 index ebb29d444c..0000000000 --- a/evm/remappings.txt +++ /dev/null @@ -1,3 +0,0 @@ -@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/ -@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/ -@openzeppelin/foundry-upgrades/=lib/openzeppelin-foundry-upgrades/src/ diff --git a/evm/script/DeployLocker.s.sol b/evm/script/DeployLocker.s.sol deleted file mode 100644 index 7234652537..0000000000 --- a/evm/script/DeployLocker.s.sol +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.17; - -import {Script, console} from "forge-std/Script.sol"; -import {Upgrades} from "@openzeppelin/foundry-upgrades/Upgrades.sol"; - -import {Locker} from "../src/Locker.sol"; - -contract DeployLocker is Script { - // TODO: update these parameters to reflect the state of thecontract before deployment - address REMITTANCE_CANISTER_PUBKEY = vm.envAddress("DEPLOY_REMITTANCE_CANISTER_PUBKEY"); // Example address - string CHAIN_IDENTIFIER = vm.envString("DEPLOY_CHAIN_IDENTIFIER"); - - function run() public { - vm.startBroadcast(); - - address _proxyAddress = Upgrades.deployUUPSProxy( - "Locker.sol", - abi.encodeCall(Locker.initialize, (REMITTANCE_CANISTER_PUBKEY, CHAIN_IDENTIFIER)) - ); - - console.log("Locker Proxy Implementation deployed at:", _proxyAddress); - vm.stopBroadcast(); - } -} diff --git a/evm/script/UpgradeLocker.s.sol b/evm/script/UpgradeLocker.s.sol deleted file mode 100644 index d170d4dfe1..0000000000 --- a/evm/script/UpgradeLocker.s.sol +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.17; - -import {Script, console} from "forge-std/Script.sol"; -import {Upgrades} from "@openzeppelin/foundry-upgrades/Upgrades.sol"; -import {Options} from "@openzeppelin/foundry-upgrades/Options.sol"; - -contract UpgradeLocker is Script { - // TODO: update contract address - address contractAddress = vm.envAddress("UPGRADE_CONTRACT_ADDRESS"); - // TODO: REPLACE "Locker.sol" with old contract name - string oldContractName = vm.envString("UPGRADE_OLD_CONTRACT_NAME"); - - function run() public { - vm.startBroadcast(); - - Options memory opts; - opts.referenceContract = oldContractName; - - // TODO: REPLACE "LockerV2.sol" with new contract name - Upgrades.upgradeProxy(contractAddress, vm.envString("UPGRADE_NEW_CONTRACT_NAME"), "", opts); - - console.log("Locker Proxy Implementation upgraded"); - vm.stopBroadcast(); - } -} diff --git a/evm/src/Locker.sol b/evm/src/Locker.sol deleted file mode 100644 index 1c003af5dd..0000000000 --- a/evm/src/Locker.sol +++ /dev/null @@ -1,193 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; - -import {IERC20} from "@openzeppelin/contracts/interfaces/IERC20.sol"; -import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; -import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; -import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; -import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol"; -import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; - -import {VerifySignature} from "./utils/VerifySignature.sol"; - -contract Locker is Initializable, UUPSUpgradeable, OwnableUpgradeable, ReentrancyGuardUpgradeable { - bool initialized; - string public chainId; - address public remittanceCanister; - address constant ZER0_ADDRESS = 0x0000000000000000000000000000000000000000; - mapping(bytes => bool) usedSignatures; - mapping(bytes32 => mapping(address => uint256)) public canisters; // keccak256(principal) => tokenAddress => amountDeposited - event FundsDeposited(string canisterId, address indexed account, uint amount, string chain, address token); - event FundsWithdrawn(string canisterId, address indexed account, uint amount, string chain, address token); - event WithdrawCanceled(string canisterId, address indexed account, uint amount, string chain, address token); - event UpdateRemittanceCanister(address remittanceCanister); - /** - * @dev Deposits native tokens (ETH) into the contract for a specified canister ID. - * Emits a `FundsDeposited` event on success. - */ - function depositTokens(string calldata _canisterId) public payable nonReentrant { - uint256 _amount = msg.value; - address _token = ZER0_ADDRESS; - require(bytes(_canisterId).length == 27, "INVALID_CANISTERID"); - require(_amount > 0, "amount == 0"); - canisters[keccak256(bytes(_canisterId))][_token] += _amount; - emit FundsDeposited(_canisterId, msg.sender, _amount, chainId, _token); - } - /** - * @dev Initializes the contract with a remittance canister address and chain ID. - * This function can only be called once. - */ - function initialize(address _remittanceCanister, string calldata _chainId) public initializer { - __Ownable_init(msg.sender); - __UUPSUpgradeable_init(); - __ReentrancyGuard_init(); - remittanceCanister = _remittanceCanister; - chainId = _chainId; - initialized = true; - } - /** - * @dev Deposits ERC20 tokens into the contract for a specified canister ID. - * Transfers the specified token amount from the sender to this contract. - * Emits a `FundsDeposited` event on success. - */ - function depositFunds( - string calldata _canisterId, - uint256 _amount, - address _token - ) public payable nonReentrant returns (bool) { - require(bytes(_canisterId).length == 27, "INVALID_CANISTERID"); - require(_amount > 0, "amount == 0"); - canisters[keccak256(bytes(_canisterId))][_token] += _amount; - emit FundsDeposited(_canisterId, msg.sender, _amount, chainId, _token); - bool response = IERC20(_token).transferFrom(msg.sender, address(this), _amount); - return response; - } - /** - * @dev Sets a new address for the remittance canister. Can only be called by the owner. - * Emits an `UpdateRemittanceCanister` event on success. - */ - function setRemittanceCanisterAddress(address _remittanceCanister) public onlyOwner { - remittanceCanister = _remittanceCanister; - emit UpdateRemittanceCanister(_remittanceCanister); - } - /** - * @dev Verifies the provided signature against a specified data hash. - * Returns true if the signature is valid. - */ - function validateSignature(bytes32 dataHash, bytes calldata signature) internal view returns (bool isValid) { - isValid = VerifySignature.verify(remittanceCanister, dataHash, signature); - } - /** - * @dev Returns the balance of a specified token for a given canister ID. - */ - function getBalance(string calldata _canisterId, address _token) public view returns (uint256 balance) { - balance = canisters[keccak256(bytes(_canisterId))][_token]; - } - /** - * @dev Withdraws ERC20 tokens from the contract to the sender’s address for a specified canister ID. - * Requires a valid signature. - * Emits a `FundsWithdrawn` event on success. - */ - function withdraw( - string calldata _canisterId, - address _token, - uint _nonce, - uint _amount, - bytes calldata _signature - ) public returns (bool) { - bool success = withdrawTo(_canisterId, _token, _nonce, _amount, _signature, msg.sender); - return success; - } - /** - * @dev Withdraws ERC20 tokens from the contract to a specified recipient address for a specified canister ID. - * Requires a valid signature. - * Emits a `FundsWithdrawn` event on success. - */ - function withdrawTo( - string calldata _canisterId, - address _token, - uint _nonce, - uint _amount, - bytes calldata _signature, - address _recipient - ) public nonReentrant returns (bool) { - require(initialized, "CONTRACT_UNINITIALIZED"); - require(getBalance(_canisterId, _token) >= _amount, "WITHDRAW_AMOUNT > CANISTER_TOKEN_BALANCE"); - require(!usedSignatures[_signature], "USED_SIGNATURE"); - bytes32 dataHash = keccak256(abi.encodePacked(_nonce, _amount, msg.sender, chainId, _canisterId, _token)); - require(validateSignature(dataHash, _signature), "INVALID_SIGNATURE"); - usedSignatures[_signature] = true; - emit FundsWithdrawn(_canisterId, msg.sender, _amount, chainId, _token); - bool success = IERC20(_token).transfer(_recipient, _amount); - return success; - } - /** - * @dev Withdraws native tokens (ETH) to a specified recipient for a specified canister ID. - * Requires a valid signature. - * Emits a `FundsWithdrawn` event on success. - */ - function withdrawTokensTo( - string calldata _canisterId, - uint _nonce, - uint _amount, - bytes calldata _signature, - address _recipient - ) public nonReentrant returns (bool) { - address _token = ZER0_ADDRESS; - require(initialized, "CONTRACT_UNINITIALIZED"); - require(_amount <= getBalance(), "INSUFFICIENT_CONTRACT_BALANCE"); - require(getBalance(_canisterId, _token) >= _amount, "WITHDRAW_AMOUNT > CANISTER_TOKEN_BALANCE"); - require(!usedSignatures[_signature], "USED_SIGNATURE"); - bytes32 dataHash = keccak256(abi.encodePacked(_nonce, _amount, msg.sender, chainId, _canisterId, _token)); - require(validateSignature(dataHash, _signature), "INVALID_SIGNATURE"); - usedSignatures[_signature] = true; - emit FundsWithdrawn(_canisterId, msg.sender, _amount, chainId, _token); - (bool success, ) = payable(_recipient).call{value: _amount}(""); - return success; - } - /** - * @dev Withdraws native tokens (ETH) to the sender for a specified canister ID. - * Requires a valid signature. - * Emits a `FundsWithdrawn` event on success. - */ - function withdrawTokens( - string calldata _canisterId, - uint _nonce, - uint _amount, - bytes calldata _signature - ) public nonReentrant returns (bool) { - bool success = withdrawTokensTo(_canisterId, _nonce, _amount, _signature, msg.sender); - return success; - } - /** - * @dev Returns the contract’s native token (ETH) balance. - */ - function getBalance() public view returns (uint) { - return address(this).balance; - } - /** - * @dev Cancels a withdrawal request for a specified canister ID. - * Requires a valid signature. Emits a `WithdrawCanceled` event on success. - */ - function cancelWithdraw( - string calldata _canisterId, - address _token, - uint _nonce, - uint _amount, - bytes calldata _signature - ) public { - require(initialized, "CONTRACT_UNINITIALIZED"); - require(!usedSignatures[_signature], "USED_SIGNATURE"); - // validate the signature - bytes32 dataHash = keccak256(abi.encodePacked(_nonce, _amount, msg.sender, chainId, _canisterId, _token)); - require(validateSignature(dataHash, _signature), "INVALID_SIGNATURE"); - // mark signature as used - usedSignatures[_signature] = true; - emit WithdrawCanceled(_canisterId, msg.sender, _amount, chainId, _token); - } - - /** - * @dev Authorizes contract upgrades. Required by the UUPS module. - */ - function _authorizeUpgrade(address) internal override onlyOwner {} -} diff --git a/evm/src/utils/VerifySignature.sol b/evm/src/utils/VerifySignature.sol deleted file mode 100644 index 7982b3f617..0000000000 --- a/evm/src/utils/VerifySignature.sol +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.17; - -/* Signature Verification - -How to Sign and Verify -# Signing -1. Create message to sign -2. Hash the message -3. Sign the hash (off chain, keep your private key secret) - -# Verify -1. Recreate hash from the original message -2. Recover signer from signature and hash -3. Compare recovered signer to claimed signer -*/ - -library VerifySignature { - function verify(address signer, bytes32 message, bytes memory signature) internal pure returns (bool) { - (bytes32 r, bytes32 s, uint8 v) = splitSignature(signature); - bytes32 ethSignedMessageHash = getEthSignedMessageHash(message); - - address recovered = ecrecover(ethSignedMessageHash, v, r, s); - - return signer == recovered; - } - - function splitSignature(bytes memory sig) internal pure returns (bytes32 r, bytes32 s, uint8 v) { - require(sig.length == 65, "invalid signature length"); - - assembly { - /* - First 32 bytes stores the length of the signature - - add(sig, 32) = pointer of sig + 32 - effectively, skips first 32 bytes of signature - - mload(p) loads next 32 bytes starting at the memory address p into memory - */ - - // first 32 bytes, after the length prefix - r := mload(add(sig, 32)) - // second 32 bytes - s := mload(add(sig, 64)) - // final byte (first byte of the next 32 bytes) - v := byte(0, mload(add(sig, 96))) - } - - // implicitly return (r, s, v) - } - - function getEthSignedMessageHash(bytes32 _messageHash) internal pure returns (bytes32) { - /* - Signature is produced by signing a keccak256 hash with the following format: - "\x19Ethereum Signed Message\n" + len(msg) + msg - */ - return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", _messageHash)); - } -} diff --git a/evm/test/Locker.t.sol b/evm/test/Locker.t.sol deleted file mode 100644 index 1ef9d839ee..0000000000 --- a/evm/test/Locker.t.sol +++ /dev/null @@ -1,130 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; - -import {Test, console} from "forge-std/Test.sol"; -import {Locker} from "../src/Locker.sol"; -import {ERC20Mock} from "@openzeppelin/contracts/mocks/token/ERC20Mock.sol"; -import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; - -contract LockerTest is Test { - Locker public locker; - ERC20Mock public token; - address admin; - address canister; - - uint256 constant NONCE = 10; - string CHAIN_ID = "ethereum:1"; - uint256 constant INITIAL_BALANCE = 100 ether; - uint256 constant DEPOSIT_AMOUNT = 10 ether; - uint256 constant WITHDRAW_AMOUNT = 1 ether; - - string constant CANISTER_ID = "c2lt4-zmaaa-aaaaa-qaaiq-cai"; - bytes32 constant CANISTER_ID_HASH = keccak256("c2lt4-zmaaa-aaaaa-qaaiq-cai"); - address REMITTANCE_CANISTER_PUBKEY = 0x2189a3E395Abbf8ac15CA9159E87FD3A05f92714; // Example address for remittance canister - bytes constant SIGNATURE = - hex"d7c29a240bfa3f29197d519b884ca6201c8b3da81275a571e1cd68742a302bd24b83dde5efaa6179efbb2ba9b4a5232afa70f906bf77ef06317fdb3ab4f3eca81c"; - bytes constant INVALID_SIGNATURE = - hex"9c30b379586b631866bd2b4fd06d4e92342ec8977e3d39b67b410a80957a9e9737e4633712b7683d30b8612e80381a54af0cfb547f44e7a5ec1872d5114c4ba01c"; - - - event FundsDeposited(string canisterId, address indexed account, uint amount, string chain, address token); - event FundsWithdrawn(string canisterId, address indexed account, uint amount, string chain, address token); - - - function setUp() public { - admin = address(0x431); // Locker contract's address - canister = address(0x456); // Canister's address - - token = new ERC20Mock(); // Deploy mock token - Locker lockerImplementation = new Locker(); - - TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy( - address(lockerImplementation), - admin, - abi.encodeWithSelector(Locker.initialize.selector, REMITTANCE_CANISTER_PUBKEY, CHAIN_ID) - ); - - // Initialize the proxy as the Locker contract - locker = Locker(address(proxy)); - token.mint(admin, INITIAL_BALANCE); // Mint some tokens to admin - } - - function testDepositFunds() public { - vm.startPrank(admin); - token.approve(address(locker), DEPOSIT_AMOUNT); // Approve Locker - - vm.expectEmit(true, false, false, false, address(locker)); - emit FundsDeposited(CANISTER_ID, admin, DEPOSIT_AMOUNT, CHAIN_ID, address(token)); - - bool success = locker.depositFunds(CANISTER_ID, DEPOSIT_AMOUNT, address(token)); - assertTrue(success, "Deposit failed"); - - vm.stopPrank(); - - // Validate balances - uint256 lockerBalance = token.balanceOf(address(locker)); - assertEq(lockerBalance, DEPOSIT_AMOUNT, "Locker balance should be 0.5 ETH"); - } - - function testWithdrawFunds() public { - vm.startPrank(admin); - // Admin deposits funds - token.approve(address(locker), DEPOSIT_AMOUNT); // Approve Locker - locker.depositFunds(CANISTER_ID, DEPOSIT_AMOUNT, address(token)); - - // Admin signs a withdrawal request (assuming signature verification in Locker) - // this is the payload being signed and how to generate it. - // it is used to generate the signature - // bytes32 dataHash 0x9c603099505d044c9654b57f35b022f1f54322d134673ce34007294e8396a205 - // bytes32 dataHash = keccak256( - // abi.encodePacked(NONCE, DEPOSIT_AMOUNT, admin, CHAIN_ID, CANISTER_ID, address(token)) - // ); - // emit log_bytes32(dataHash); - - // Check event emission - vm.expectEmit(true, false, false, false, address(locker)); - emit FundsWithdrawn(CANISTER_ID, admin, DEPOSIT_AMOUNT, CHAIN_ID, address(token)); - - // Attempt to withdraw funds - bool success = locker.withdraw(CANISTER_ID, address(token), NONCE, DEPOSIT_AMOUNT, SIGNATURE); - assertTrue(success, "Withdrawal failed"); - vm.stopPrank(); - - // Validate post-withdrawal balance - uint256 recipientBalance = token.balanceOf(admin); - assertEq(recipientBalance, INITIAL_BALANCE, "Admin should have initial after withdrawal"); - } - - function testInvalidSignatureReverts() public { - vm.startPrank(admin); - - // Attempt to deposit with an invalid signature - token.approve(address(locker), DEPOSIT_AMOUNT); // Approve Locker for two withdrawals - locker.depositFunds(CANISTER_ID, DEPOSIT_AMOUNT, address(token)); - - // Attempt to withdraw funds with an invalid signature - vm.expectRevert("INVALID_SIGNATURE"); - locker.withdraw(CANISTER_ID, address(token), NONCE, DEPOSIT_AMOUNT, INVALID_SIGNATURE); - - vm.stopPrank(); - } - - function testReusedSignatureReverts() public { - uint256 num_withdrawals = 2; - vm.startPrank(admin); - - // Attempt to deposit with an invalid signature - token.approve(address(locker), DEPOSIT_AMOUNT * num_withdrawals); // Approve Locker for two withdrawals - locker.depositFunds(CANISTER_ID, DEPOSIT_AMOUNT * num_withdrawals, address(token)); - - // Attempt to withdraw funds first time - locker.withdraw(CANISTER_ID, address(token), NONCE, DEPOSIT_AMOUNT, SIGNATURE); - - - vm.expectRevert("USED_SIGNATURE"); - // attempt to withdraw funds again with same signature - locker.withdraw(CANISTER_ID, address(token), NONCE, DEPOSIT_AMOUNT, SIGNATURE); - - vm.stopPrank(); - } -} diff --git a/fixtures/assets/receipt/receipt_1kb.bin b/fixtures/assets/receipt/receipt_1kb.bin index 5529523f58..976f51464b 100644 Binary files a/fixtures/assets/receipt/receipt_1kb.bin and b/fixtures/assets/receipt/receipt_1kb.bin differ diff --git a/fixtures/assets/receipt/receipt_32b.bin b/fixtures/assets/receipt/receipt_32b.bin index f89280e295..968482c4bb 100644 Binary files a/fixtures/assets/receipt/receipt_32b.bin and b/fixtures/assets/receipt/receipt_32b.bin differ