diff --git a/proposals/ethereum-bridge-contact/README.md b/proposals/ethereum-bridge-contact/README.md index 71f83fac4..c93fabeef 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 diff --git a/proposals/ethereum-bridge-contact/SETUP.md b/proposals/ethereum-bridge-contact/SETUP.md index e900f58de..9b4a6423a 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 37b499f52..1e96f4387 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`