Smart Contract Patterns
Practical Solidity patterns for HyperEVM. HyperEVM is Cancun-compatible — any standard Ethereum contract works without modification. These examples also show HyperEVM-specific integrations.
1. ERC-20 Token
StandardHyperEVM is fully EVM-compatible. Deploy any OpenZeppelin contract without changes. This is a minimal ERC-20 example.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract MyToken is ERC20, Ownable {
constructor(address initialOwner)
ERC20("MyToken", "MTK")
Ownable(initialOwner)
{
_mint(msg.sender, 1_000_000 * 10 ** decimals());
}
function mint(address to, uint256 amount) public onlyOwner {
_mint(to, amount);
}
}forge create src/MyToken.sol:MyToken \ --constructor-args <YOUR_ADDRESS> \ --rpc-url https://rpc.hyperliquid-testnet.xyz/evm \ --chain-id 998 \ --private-key $PRIVATE_KEY
2. Wrapped HYPE (WHYPE) Integration
HyperEVM NativeHYPE is the native gas token on HyperEVM. To use it in DeFi protocols (swaps, liquidity pools), wrap it into WHYPE — a standard ERC-20 backed 1:1 by HYPE.
0x5555555555555555555555555555555555555555// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface IWHYPE {
function deposit() external payable;
function withdraw(uint256 wad) external;
function transfer(address to, uint256 amount) external returns (bool);
function balanceOf(address account) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
}
contract WHYPEVault {
IWHYPE public constant WHYPE =
IWHYPE(0x5555555555555555555555555555555555555555);
mapping(address => uint256) public shares;
// Wrap native HYPE into WHYPE and deposit into vault
function deposit() external payable {
require(msg.value > 0, "Send HYPE to deposit");
WHYPE.deposit{value: msg.value}();
shares[msg.sender] += msg.value;
}
// Unwrap WHYPE back to native HYPE and return to user
function withdraw(uint256 amount) external {
require(shares[msg.sender] >= amount, "Insufficient shares");
shares[msg.sender] -= amount;
WHYPE.withdraw(amount);
(bool ok, ) = msg.sender.call{value: amount}("");
require(ok, "HYPE transfer failed");
}
receive() external payable {}
}3. Reading HyperCore Prices (Oracle)
HyperEVM NativeHyperEVM contracts can read live oracle prices from HyperCore. The system precompile at the read address allows querying mark prices and other L1 state.
HyperCore precompile addresses for reading L1 data are documented in the official Hyperliquid GitBook under HyperEVM → System Addresses & Precompiles. Always verify addresses from the official source before production deployment. The pattern below illustrates the interface shape.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
// Interface shape — verify exact ABI from official Hyperliquid docs
// https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/hyperevm
interface IHyperCoreRead {
// Returns oracle mid price for a HyperCore perp/spot asset
// Asset index matches the index in /info "meta" endpoint
function getOraclePrice(uint32 assetIndex) external view returns (uint64 price, uint32 decimals);
}
contract PriceConsumer {
// Verify this address from official Hyperliquid documentation
IHyperCoreRead public immutable hyperCore;
constructor(address hyperCorePrecompile) {
hyperCore = IHyperCoreRead(hyperCorePrecompile);
}
function getAssetPrice(uint32 assetIndex) public view returns (uint64, uint32) {
return hyperCore.getOraclePrice(assetIndex);
}
}Asset indexes match the universe array from the meta Info API endpoint. Spot assets use index 10000 + spotIndex.
4. HyperCore → HyperEVM Bridge Transfer
System AddressTo programmatically move HYPE from HyperCore to a HyperEVM contract, send to the system bridge address. This works from both EOAs and contracts.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract BridgeReceiver {
// This is the system address that receives HYPE
// sent from HyperCore → HyperEVM
address public constant BRIDGE =
0x2222222222222222222222222222222222222222;
event Received(address indexed from, uint256 amount);
// Your contract can receive HYPE bridged from HyperCore
receive() external payable {
emit Received(msg.sender, msg.value);
}
// Forward HYPE to the bridge (HyperEVM → HyperCore direction
// requires using the official bridge UI or SDK)
function getBalance() public view returns (uint256) {
return address(this).balance;
}
}Security Checklist
- •Always verify precompile addresses from the official Hyperliquid GitBook before production use.
- •Use the latest stable OpenZeppelin contracts (v5+).
- •Deploy to testnet (Chain ID: 998) and test thoroughly before mainnet (Chain ID: 999).
- •Get an audit for contracts handling significant user funds.
- •HyperEVM performance doesn't eliminate reentrancy, overflow, or access control risks.