Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
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
12 changes: 12 additions & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@ optimizer = true
optimizer_runs = 200
via_ir = true

ignored_error_codes = [
2519, # shadowed declarations
3628, # https://github.com/argotorg/solidity/issues/10159
]

# For dependencies
remappings = [
]

[lint]
exclude_lints = [
"incorrect-shift",
"mixed-case-function",
#"unsafe-typecast",
]
23 changes: 23 additions & 0 deletions src/FVMAddress.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
pragma solidity ^0.8.30;

library FVMAddress {
error NotMaskedIdAddress(address addr);

/// @notice Creates an f0 (ID) address in bytes using unsigned LEB128 encoding
function f0(uint64 actorId) internal pure returns (bytes memory buffer) {
// Max size: 1 protocol byte + 10 bytes for uint64 LEB128 encoding
Expand Down Expand Up @@ -34,4 +36,25 @@ library FVMAddress {
function f410(address addr) internal pure returns (bytes memory) {
return f4(0x0a, bytes20(addr));
}

/// @notice Creates a masked ID address (the EVM encoding of an f0 actor ID)
/// @dev Format: 0xff + 11 zero bytes + big-endian uint64 actor ID (20 bytes total)
function maskedAddress(uint64 actorId) internal pure returns (address maskedAddr) {
assembly ("memory-safe") {
maskedAddr := or(actorId, 0xff00000000000000000000000000000000000000)
}
}

/// @notice Extracts the actor ID from a masked ID address without prefix validation
/// @dev Only call when the address is known to have the 0xff000...000 prefix
function actorId(address maskedAddr) internal pure returns (uint64) {
return uint64(uint160(maskedAddr));
}

/// @notice Extracts the actor ID from a masked ID address, reverting if the prefix is wrong
/// @dev Use FVMActor.tryGetActorId to test if the actorId is valid
function safeActorId(address maskedAddr) internal pure returns (uint64) {
require(uint160(maskedAddr) >> 64 == 0xff0000000000000000000000, NotMaskedIdAddress(maskedAddr));
return actorId(maskedAddr);
}
}
6 changes: 3 additions & 3 deletions src/FVMCodec.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ pragma solidity ^0.8.30;
// @dev empty returned data
uint64 constant EMPTY_CODEC = 0;

// @dev CBOR-encoded data
uint64 constant CBOR_CODEC = 0x51;

// @dev actor returned unencoded raw data
uint64 constant RAW_CODEC = 0x55;

// @dev CBOR encoded data (IPLD dag-cbor)
uint64 constant CBOR_CODEC = 0x51;
49 changes: 48 additions & 1 deletion src/FVMErrors.sol
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
// SPDX-License-Identifier: Apache-2.0 OR MIT
pragma solidity ^0.8.30;

// See filecoin-project/ref-fvm shared/src/error/mod.rs
// Syscall errors: filecoin-project/ref-fvm shared/src/error/mod.rs
// Exit codes: https://docs.rs/fvm_shared/latest/fvm_shared/error/struct.ExitCode.html

int256 constant EXIT_SUCCESS = 0;

// Syscall error numbers (negative exit codes, ErrorNumber in ref-fvm)

// @dev A syscall parameters was invalid.
int256 constant ILLEGAL_ARGUMENT = -1;
// @dev The actor is not in the correct state to perform the requested operation.
Expand All @@ -31,3 +34,47 @@ int256 constant FORBIDDEN = -11;
int256 constant BUFFER_TOO_SMALL = -12;
// @dev The actor is executing in a read-only context.
int256 constant READ_ONLY = -13;

// System exit codes (positive, ExitCode in fvm_shared::error, set by the VM — actors cannot use these)
// @dev The message sender doesn't exist.
uint32 constant SYS_SENDER_INVALID = 1;
// @dev The message sender was not in a valid state (bad nonce or insufficient gas funds).
uint32 constant SYS_SENDER_STATE_INVALID = 2;
// @dev The message receiver trapped (panicked).
uint32 constant SYS_ILLEGAL_INSTRUCTION = 4;
// @dev The receiver doesn't exist and can't be auto-created, or doesn't implement the entrypoint.
uint32 constant SYS_INVALID_RECEIVER = 5;
// @dev The message sender didn't have the requisite funds.
uint32 constant SYS_INSUFFICIENT_FUNDS = 6;
// @dev Message execution (including subcalls) used more gas than the specified limit.
uint32 constant SYS_OUT_OF_GAS = 7;
// @dev The message receiver aborted with a reserved exit code.
uint32 constant SYS_ILLEGAL_EXIT_CODE = 9;
// @dev An internal VM assertion failed.
uint32 constant SYS_ASSERTION_FAILED = 10;
// @dev The actor returned a block handle that doesn't exist.
uint32 constant SYS_MISSING_RETURN = 11;

// Actor user exit codes (positive, ExitCode in fvm_shared::error)
// @dev The method parameters are invalid.
uint32 constant USR_ILLEGAL_ARGUMENT = 16;
// @dev The requested resource does not exist.
uint32 constant USR_NOT_FOUND = 17;
// @dev The requested operation is forbidden.
uint32 constant USR_FORBIDDEN = 18;
// @dev The actor has insufficient funds to perform the requested operation.
uint32 constant USR_INSUFFICIENT_FUNDS = 19;
// @dev The actor's internal state is invalid.
uint32 constant USR_ILLEGAL_STATE = 20;
// @dev There was a de/serialization failure within actor code.
uint32 constant USR_SERIALIZATION = 21;
// @dev The message cannot be handled (usually indicates an unhandled method number).
uint32 constant USR_UNHANDLED_MESSAGE = 22;
// @dev The actor failed with an unspecified error.
uint32 constant USR_UNSPECIFIED = 23;
// @dev The actor failed a user-level assertion.
uint32 constant USR_ASSERTION_FAILED = 24;
// @dev The requested operation cannot be performed in read-only mode.
uint32 constant USR_READ_ONLY = 25;
// @dev The method cannot handle a transfer of value.
uint32 constant USR_NOT_PAYABLE = 26;
7 changes: 7 additions & 0 deletions src/FVMMethod.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ pragma solidity ^0.8.30;
uint64 constant SEND = 0;
uint64 constant CONSTRUCT = 1;

// Lowest method number callable by user actors (FRC-0042 / restrict_internal_api threshold).
// Methods 1–(FIRST_EXPORTED_METHOD_NUMBER-1) are reserved for built-in callers only.
uint64 constant FIRST_EXPORTED_METHOD_NUMBER = 1 << 24; // 16777216

// Storage power actor methods
uint64 constant MINER_POWER = 36284446;

// FRC-0042 hashed method numbers (https://github.com/filecoin-project/FIPs/blob/master/FRCs/frc-0042.md)
uint64 constant AUTHENTICATE_MESSAGE = 2643134072;
uint64 constant UNIVERSAL_RECEIVER_HOOK = 118350608;
Expand Down
Loading
Loading