Helper libraries for token transfers, error definitions, ownership patterns, and the split-code deployment factory for contracts exceeding the 24KB limit.
Source:src/fira_bonding/libraries/
Errors.sol
Central registry of all custom error types. Errors are prefixed by module (Market*, YC*, FW*, Router*). Using custom errors instead of string reverts saves gas and makes off-chain decoding straightforward.
TokenHelper.sol
Safe ERC20 transfer wrappers with native ETH handling:
_transferIn(token, from, amount) — Handles ETH by checking msg.value and wrapping via WETH
_transferOut(token, to, amount) — Handles ETH by unwrapping WETH
_selfBalance(token) — Balance accounting for native ETH
_safeApproveInf(token, spender) — Infinite approval only if current allowance is low
The NATIVE sentinel address (0x000...000) represents ETH in TokenInput/TokenOutput structs.
BoringOwnableUpgradeable.sol
Two-step ownership transfer: transferOwnership(newOwner, direct, renounce) either transfers immediately or sets a pending owner who must call claimOwnership(). Used by FW tokens and factories.
BaseSplitCodeFactory / CodeDeployer
Works around the 24KB EVM contract size limit (EIP-170):
At factory deployment, creation bytecode is split into two chunks, each deployed as a "code storage" contract
At creation time, bytecode is concatenated in memory and deployed via CREATE2
Used by both FiraMarketFactory and YieldContractFactory since FiraMarket and CouponToken exceed the size limit.
Other helpers
MiniHelpers.sol — isCurrentlyExpired(expiry), ensureNotExpired() — used everywhere for pre/post-expiry gating
ExpiryUtilsLib.sol / StringLib.sol — Generate deterministic token names like FW-USDC-BT-07MAY2026 from symbols and expiry timestamps
ArrayLib.sol — create(a, b) returns a 2-element address[]; sum(arr) sums a uint256[]