From 85447e2b3fecfabe3e76dc5c36d02d5fffa7a8b9 Mon Sep 17 00:00:00 2001 From: GLiberman Date: Thu, 14 May 2026 15:29:44 -0700 Subject: [PATCH 1/2] fix: ethereum contract readme update --- proposals/ethereum-bridge-contact/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/proposals/ethereum-bridge-contact/README.md b/proposals/ethereum-bridge-contact/README.md index 71f83fac4a..c93fabeefd 100644 --- a/proposals/ethereum-bridge-contact/README.md +++ b/proposals/ethereum-bridge-contact/README.md @@ -77,6 +77,7 @@ bytes32 messageHash = keccak256( ETHEREUM_CHAIN_ID, WITHDRAW_OPERATION, // keccak256("WITHDRAW_OPERATION") recipient, + address(this), // Bridge contract address tokenContract, amount ) @@ -112,6 +113,7 @@ bytes32 messageHash = keccak256( ETHEREUM_CHAIN_ID, MINT_OPERATION, // keccak256("MINT_OPERATION") recipient, + address(this), // Bridge contract address amount ) ); @@ -210,6 +212,7 @@ error MustBeInAdminControl() // Operation requires ADMIN_CONTROL state error InvalidEpochSequence() // Epoch not sequential error NoValidGenesisEpoch() // Cannot enable operations without epoch 1 error TimeoutNotReached() // Timeout check called too early +error InvalidAmount() // Zero-amount withdrawal or mint rejected ``` ## Gas Costs From 224b9c6ad1def39571074dbfacf3ae59b9b3b4ee Mon Sep 17 00:00:00 2001 From: bonujel Date: Wed, 3 Jun 2026 09:38:59 +0800 Subject: [PATCH 2/2] docs(bridge): align SETUP and contract docs with BridgeContract.sol (#1285) Beyond the README quickfix, the other two bridge docs carried the same messageHash inconsistency plus stale BLS point sizes. Align them with the contract source: - messageHash now includes address(this) and the full field order for both withdraw and mint (matches BridgeContract.sol). - BLS sizes corrected to the EIP-2537 precompile encoding: G1 signature 128 bytes, G2 group key 256 bytes (uncompressed), replacing the old 48/96-byte compressed figures. - Fixed the trailing-comma typo in the mint encoding example. Co-Authored-By: Claude Opus 4.8 (1M context) --- proposals/ethereum-bridge-contact/SETUP.md | 8 +++--- .../ethereum-bridge-contract.md | 26 ++++++++++++------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/proposals/ethereum-bridge-contact/SETUP.md b/proposals/ethereum-bridge-contact/SETUP.md index e900f58de8..9b4a6423ac 100644 --- a/proposals/ethereum-bridge-contact/SETUP.md +++ b/proposals/ethereum-bridge-contact/SETUP.md @@ -167,8 +167,10 @@ bridge.on("AdminControlActivated", (timestamp, reason) => { - Check latest epoch ID: `bridge.getLatestEpochInfo()` **"InvalidSignature" Error** -- Verify BLS signature format (48 bytes, G1 point) -- Check message encoding: `abi.encodePacked(epochId, requestId, recipient, token, amount)` +- Verify BLS signature format (128-byte uncompressed G1 point) +- Check message encoding matches the operation: + - Withdrawal: `abi.encodePacked(epochId, GONKA_CHAIN_ID, requestId, ETHEREUM_CHAIN_ID, WITHDRAW_OPERATION, recipient, address(this), tokenContract, amount)` + - Mint: `abi.encodePacked(epochId, GONKA_CHAIN_ID, requestId, ETHEREUM_CHAIN_ID, MINT_OPERATION, recipient, address(this), amount)` - Ensure group public key is correct for the epoch **"BridgeNotOperational" Error** @@ -241,4 +243,4 @@ bridge.on("AdminControlActivated", (timestamp, reason) => { ### Polygon - Very low costs - Check BLS precompile compatibility -- Different gas pricing model \ No newline at end of file +- Different gas pricing model diff --git a/proposals/ethereum-bridge-contact/ethereum-bridge-contract.md b/proposals/ethereum-bridge-contact/ethereum-bridge-contract.md index 37b499f52e..1e96f43877 100644 --- a/proposals/ethereum-bridge-contact/ethereum-bridge-contract.md +++ b/proposals/ethereum-bridge-contact/ethereum-bridge-contract.md @@ -28,14 +28,14 @@ This document describes the Ethereum smart contract that serves as the bridge en - Utilizes Ethereum's native BLS12-381 curve support for signature verification - Implements threshold signature validation using precompiled contracts -- Group public keys stored as G2 points (96 bytes compressed format) -- Signatures verified as G1 points (48 bytes compressed format) +- Group public keys stored as uncompressed G2 points (256 bytes) +- Signatures verified as uncompressed G1 points (128 bytes) **Signature Verification Process:** ```text -1. Parse withdrawal command: (epoch_id, request_id, recipient, token, amount) -2. Encode data using abi.encodePacked for consistent hashing +1. Parse bridge command and operation context +2. Encode data using the contract's exact `abi.encodePacked` field order 3. Compute message hash: keccak256(encoded_data) 4. Retrieve group public key for specified epoch_id 5. Verify BLS signature against group public key using precompiled contract (with operation domain separation) @@ -306,17 +306,20 @@ struct WithdrawalCommand { uint64 epochId; // 8 bytes - epoch for signature validation bytes32 requestId; // 32 bytes - unique request identifier from source chain address recipient; // 20 bytes - Ethereum address to receive tokens - address tokenContract; // 20 bytes - ERC-20 contract address + address tokenContract; // 20 bytes - ERC-20 contract address (or address(this) for ETH) uint256 amount; // 32 bytes - token amount to withdraw - bytes signature; // 48 bytes - BLS threshold signature (G1 point) + bytes signature; // 128 bytes - BLS threshold signature (G1 point, uncompressed) } ``` **Validation Flow:** -1. **Epoch Validation**: Verify group key exists for specified `epochId` (`epochGroupKeys[epochId].length > 0`) +1. **Epoch Validation**: Verify a non-empty group key exists for specified `epochId` 2. **Replay Protection**: Check `requestId` hasn't been processed for this `epochId` -3. **Signature Verification**: Validate BLS signature against epoch's group public key using message: `abi.encodePacked(epochId, requestId, WITHDRAW_OPERATION, recipient, tokenContract, amount)` +3. **Signature Verification**: Validate BLS signature against epoch's group public key using message: + ```solidity + abi.encodePacked(epochId, GONKA_CHAIN_ID, requestId, ETHEREUM_CHAIN_ID, WITHDRAW_OPERATION, recipient, address(this), tokenContract, amount) + ``` 4. **Balance Check**: Ensure contract has sufficient token or ETH balance 5. **Execution**: Transfer tokens or ETH to recipient address - **ETH withdrawals**: When `tokenContract == address(this)`, transfer ETH using `call{value:}` @@ -456,7 +459,7 @@ struct MintCommand { bytes32 requestId; // 32 bytes - unique request identifier from source chain address recipient; // 20 bytes - Ethereum address to receive WGNK uint256 amount; // 32 bytes - WGNK amount to mint - bytes signature; // 48 bytes - BLS threshold signature (G1 point) + bytes signature; // 128 bytes - BLS threshold signature (G1 point, uncompressed) } function mintWithSignature(MintCommand calldata cmd) external; @@ -467,7 +470,10 @@ function mintWithSignature(MintCommand calldata cmd) external; 1. **State Check**: Only allowed in `NORMAL_OPERATION` state 2. **Epoch Validation**: Verify group key exists for specified `epochId` 3. **Replay Protection**: Check `requestId` hasn't been processed for this `epochId` -4. **Signature Verification**: Validate BLS signature against epoch's group public key using message: `abi.encodePacked(epochId, requestId, MINT_OPERATION, recipient, amount, )` +4. **Signature Verification**: Validate BLS signature against epoch's group public key using message: + ```solidity + abi.encodePacked(epochId, GONKA_CHAIN_ID, requestId, ETHEREUM_CHAIN_ID, MINT_OPERATION, recipient, address(this), amount) + ``` 5. **Execution**: Mint WGNK tokens to recipient's balance, increase total supply 6. **Record Processing**: Mark `requestId` as processed for this `epochId`