|
| 1 | + |
| 2 | +use alloy_primitives::{Address, U256}; |
| 3 | +use bytes::Bytes; |
| 4 | +use revm::precompile::{Precompile, PrecompileError, PrecompileOutput}; |
| 5 | +use std::str; |
| 6 | + |
| 7 | +/// The address of the native mint precompile. |
| 8 | +pub const NATIVE_MINT_PRECOMPILE_ADDRESS: Address = Address::new([ |
| 9 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 10 | + 0x00, 0x00, 0x00, 0xEF, |
| 11 | +]); |
| 12 | + |
| 13 | +/// The ABI for the native mint precompile. |
| 14 | +/// |
| 15 | +/// The precompile accepts a 52-byte buffer, structured as follows: |
| 16 | +/// - The first 20 bytes represent the recipient's address (`to`). |
| 17 | +/// - The next 32 bytes represent the amount to mint (`amount`). |
| 18 | +/// |
| 19 | +/// ```solidity |
| 20 | +/// interface INativeMint { |
| 21 | +/// function mint(address to, uint256 amount) external; |
| 22 | +/// } |
| 23 | +/// ``` |
| 24 | +pub const NATIVE_MINT_PRECOMPILE_ABI: &str = r#"[{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"}]"#; |
| 25 | + |
| 26 | +/// The gas cost for the native mint precompile. |
| 27 | +pub const NATIVE_MINT_PRECOMPILE_GAS_COST: u64 = 5_000; |
| 28 | + |
| 29 | +/// A stateless precompile for minting the native token. |
| 30 | +/// |
| 31 | +/// This precompile is responsible for parsing the input, validating the gas, and returning a |
| 32 | +/// success or error. The actual state mutation (crediting the balance) is handled by the |
| 33 | +/// `MintInspector`. |
| 34 | +pub fn native_mint(input: &Bytes, gas_limit: u64) -> Result<PrecompileOutput, PrecompileError> { |
| 35 | + // Check if the gas limit is sufficient. |
| 36 | + if gas_limit < NATIVE_MINT_PRECOMPILE_GAS_COST { |
| 37 | + return Err(PrecompileError::OutOfGas); |
| 38 | + } |
| 39 | + |
| 40 | + // The input should be exactly 52 bytes long: 20 bytes for the address and 32 bytes for the |
| 41 | + // amount. |
| 42 | + if input.len() != 52 { |
| 43 | + return Err(PrecompileError::Other( |
| 44 | + "invalid input length".to_string().into(), |
| 45 | + )); |
| 46 | + } |
| 47 | + |
| 48 | + // Return success with the gas used. The actual minting is handled by the inspector. |
| 49 | + Ok(PrecompileOutput::new( |
| 50 | + NATIVE_MINT_PRECOMPILE_GAS_COST, |
| 51 | + Bytes::new(), |
| 52 | + )) |
| 53 | +} |
0 commit comments