datahaven/operator/precompiles/call-permit/CallPermit.sol
Steve Degosserie 479af2e192
feat: Add Moonbeam CallPermit precompile (#140)
## Summary

This PR adds Moonbeam's CallPermit precompile to DataHaven, enabling
gasless meta-transactions through EIP-712 signature-based permissions.
Users can sign transaction permits offline, allowing relayers to execute
transactions on their behalf while maintaining full security and
authentication.

## Key Features

### CallPermit Precompile Functions
- **`dispatch(address from, address to, uint256 value, bytes data,
uint64[] gasLimit, uint256 deadline, uint8 v, bytes32 r, bytes32 s)`**:
Execute permitted calls with signature verification
- **`nonces(address owner)`**: Get current nonce for permit validation

### Technical Implementation
- **Address**: `0x080A` (2058 in decimal)
- **EIP-712 Compliance**: Structured signature validation with proper
domain separation
- **Nonce Management**: Per-user nonce tracking for replay protection
- **Deadline Validation**: Time-bound permits for enhanced security
- **Gas Forwarding**: Proper gas limit enforcement and forwarding

Depends on https://github.com/datahaven-xyz/datahaven/pull/137

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-09-07 15:00:37 +02:00

54 lines
2.4 KiB
Solidity

// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >=0.8.3;
/// @dev The CallPermit contract's address.
address constant CALL_PERMIT_ADDRESS = 0x000000000000000000000000000000000000080a;
/// @dev The CallPermit contract's instance.
CallPermit constant CALL_PERMIT_CONTRACT = CallPermit(CALL_PERMIT_ADDRESS);
/// @author The Moonbeam Team
/// @title Call Permit Interface
/// @dev The interface aims to be a general-purpose tool to perform gas-less transactions. It uses the EIP-712 standard,
/// and signed messages can be dispatched by another network participant with a transaction
/// @custom:address 0x000000000000000000000000000000000000080a
interface CallPermit {
/// @dev Dispatch a call on the behalf of an other user with a EIP712 permit.
/// Will revert if the permit is not valid or if the dispatched call reverts or errors (such as
/// out of gas).
/// If successful the EIP712 nonce is increased to prevent this permit to be replayed.
/// @param from Who made the permit and want its call to be dispatched on their behalf.
/// @param to Which address the call is made to.
/// @param value Value being transfered from the "from" account.
/// @param data Call data
/// @param gaslimit Gaslimit the dispatched call requires.
/// Providing it prevents the dispatcher to manipulate the gaslimit.
/// @param deadline Deadline in UNIX seconds after which the permit will no longer be valid.
/// @param v V part of the signature.
/// @param r R part of the signature.
/// @param s S part of the signature.
/// @return output Output of the call.
/// @custom:selector b5ea0966
function dispatch(
address from,
address to,
uint256 value,
bytes memory data,
uint64 gaslimit,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external returns (bytes memory output);
/// @dev Returns the current nonce for given owner.
/// A permit must have this nonce to be consumed, which will
/// increase the nonce by one.
/// @custom:selector 7ecebe00
function nonces(address owner) external view returns (uint256);
/// @dev Returns the EIP712 domain separator. It is used to avoid replay
/// attacks accross assets or other similar EIP712 message structures.
/// @custom:selector 3644e515
function DOMAIN_SEPARATOR() external view returns (bytes32);
}