Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions proposals/ethereum-bridge-contact/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ bytes32 messageHash = keccak256(
ETHEREUM_CHAIN_ID,
WITHDRAW_OPERATION, // keccak256("WITHDRAW_OPERATION")
recipient,
address(this), // Bridge contract address
tokenContract,
amount
)
Expand Down Expand Up @@ -112,6 +113,7 @@ bytes32 messageHash = keccak256(
ETHEREUM_CHAIN_ID,
MINT_OPERATION, // keccak256("MINT_OPERATION")
recipient,
address(this), // Bridge contract address
amount
)
);
Expand Down Expand Up @@ -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
Expand Down
8 changes: 5 additions & 3 deletions proposals/ethereum-bridge-contact/SETUP.md
Original file line number Diff line number Diff line change
Expand Up @@ -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**
Expand Down Expand Up @@ -241,4 +243,4 @@ bridge.on("AdminControlActivated", (timestamp, reason) => {
### Polygon
- Very low costs
- Check BLS precompile compatibility
- Different gas pricing model
- Different gas pricing model
26 changes: 16 additions & 10 deletions proposals/ethereum-bridge-contact/ethereum-bridge-contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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:}`
Expand Down Expand Up @@ -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;
Expand All @@ -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`

Expand Down