Home
Foundry
Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.
Foundry consists of:
- Forge: Ethereum testing framework (like Truffle, Hardhat and DappTools).
- Cast: Swiss army knife for interacting with EVM smart contracts, sending transactions and getting chain data.
- Anvil: Local Ethereum node, akin to Ganache, Hardhat Network.
- Chisel: Fast, utilitarian, and verbose solidity REPL.
Documentation
https://book.getfoundry.sh/
Usage
Build
$ forge build
Test
$ forge test
Format
$ forge fmt
Gas Snapshots
$ forge snapshot
Anvil
$ anvil
Deploy
$ forge script script/Counter.s.sol:CounterScript --rpc-url <your_rpc_url> --private-key <your_private_key>
Cast
$ cast <subcommand>
Help
$ forge --help
$ anvil --help
$ cast --help
Contents
HHelper
Inherits: Ownable
Title: Helper features and modifiers.
Author: Obiaraije Henry
Inherits OpenZeppelin {Ownable} so the launch owner is set at construction.
State Variables
owner2
Secondary owner who may run every admin action but cannot manage owners.
Set by owner1 via {Henriable.actionAdminSetOwner2}; address(0) means unset.
address internal owner2
ownerUsdToken
USDC token used for all investments, payouts and payments.
IERC20 internal ownerUsdToken
vehicleNft
Vehicle-title NFT collection used to hold and hand over asset titles.
Minted to this contract when an investment is fully funded and transferred to the rider once the hire purchase is paid in full.
HenriableVehicleNFT internal vehicleNft
ownerPayoutsList
All owner/contract payouts ever made.
HOwnerPayout[] internal ownerPayoutsList
ownerPayouts
Maps an investment id => 1-based position in {ownerPayoutsList} of the most recent owner payout for that investment.
Key: investment id (bytes32). Value: index + 1 into {ownerPayoutsList},
so 0 means no owner payout has been recorded for the investment yet.
mapping(bytes32 => uint256) internal ownerPayouts
ownerPayoutHistory
Maps an investment id => the aggregate owner payout history for it.
Key: investment id (bytes32). Value: {HOwnerPayoutsHistory} holding the running totals of every owner payout recorded on that investment.
mapping(bytes32 => HOwnerPayoutsHistory) internal ownerPayoutHistory
assetsList
All registered assets, in insertion order.
HAsset[] internal assetsList
assets
Maps an asset id => 1-based position in {assetsList}.
Key: asset id (bytes32). Value: index + 1 into {assetsList}, so 0 means
“not registered”; this single mapping provides an O(1) existence check
and lookup.
mapping(bytes32 => uint256) internal assets
assetInvestments
Maps an asset id => the investments created for that asset.
Key: asset id (bytes32). Value: array of 1-based positions into {investmentsList} (subtract 1 to index the array).
mapping(bytes32 => uint256[]) internal assetInvestments
investmentsList
All investment opportunities ever created.
HInvestment[] internal investmentsList
investments
Maps an investment id => 1-based position in {investmentsList}.
Key: investment id (bytes32). Value: index + 1 into {investmentsList},
so 0 means “not registered” for an O(1) existence check and lookup.
mapping(bytes32 => uint256) internal investments
investorsList
All registered investors.
HInvestor[] internal investorsList
completedRiderInvestmentList
Indices (into {investmentsList}) of investments whose rider has fully paid and that are complete.
uint256[] internal completedRiderInvestmentList
investmentsCompleted
Indices (into {investmentsList}) of completed rider investments. This list is append-only and is never cleared.
uint256[] internal investmentsCompleted
titleInvestmentId
Maps a minted title token id => the investment it was minted for.
The forward link lives on the investment ({HInvestment.nftTokenId}); this is the reverse, so a title can resolve its investment – and thus its asset and rider – without scanning the investment list. Set once when the title mints.
mapping(uint256 => bytes32) internal titleInvestmentId
investors
Maps an investor address => 1-based position in {investorsList}.
Key: investor address. Value: index + 1 into {investorsList}, so 0
means “not registered”.
mapping(address => uint256) internal investors
investorPayoutList
All investor payouts ever made.
HInvestorPayout[] internal investorPayoutList
investorPayouts
Maps an investor and investment id => the investor’s payout in {investorPayoutList}.
Key: investor address, then investment id (bytes32). Value: 1-based position in {investorPayoutList} of that investor’s most recent payout for the investment, or 0 if none has been recorded.
mapping(address => mapping(bytes32 => uint256)) internal investorPayouts
ridersList
All registered riders.
HRider[] internal ridersList
riders
Maps a rider address => 1-based position in {ridersList}.
Key: rider address. Value: index + 1 into {ridersList}, so 0 means
“not registered”.
mapping(address => uint256) internal riders
ridersHirePurchasesRequestsList
All rider hire-purchase requests ever made.
HRiderHirePurchaseRequest[] internal ridersHirePurchasesRequestsList
ridersHireRequestPurchasesByInvestment
Maps a rider id and investment id => the rider’s hire request in {ridersHirePurchasesRequestsList}.
Key: rider id (bytes32), then investment id (bytes32). Value: 1-based position in {ridersHirePurchasesRequestsList}, or 0 if the rider has not requested that investment.
mapping(bytes32 => mapping(bytes32 => uint256)) internal ridersHireRequestPurchasesByInvestment
rejectedRiders
Maps a rider id and investment id => a rejection marker.
Key: rider id (bytes32), then investment id (bytes32). Value: non-zero once the rider has been rejected for that investment, 0 otherwise.
mapping(bytes32 => mapping(bytes32 => uint256)) internal rejectedRiders
riderPayinsList
All rider periodic payments ever made.
HRiderPayin[] internal riderPayinsList
riderSavingsSlashesList
All rider savings slashes ever applied, in insertion order.
HRiderSavingsSlash[] internal riderSavingsSlashesList
riderSavingsSlashesByInvestment
Maps an investment id => 1-based position in {riderSavingsSlashesList} of the most recent slash for that investment.
Key: investment id (bytes32). Value: index + 1 into
{riderSavingsSlashesList}, so 0 means no slash has been recorded yet.
mapping(bytes32 => uint256) internal riderSavingsSlashesByInvestment
stats
Running platform totals exposed by {Henriable.getStats}.
Counters are maintained in O(1) at each write site; the totals that mirror list lengths are filled in by the getter at read time.
HStats internal stats
assetActiveInvestmentsCount
Maps an asset id => the number of its currently active investments.
Used to keep {HStats.assetsWithRunningInvestments} exact without looping: the global counter only moves when this per-asset count crosses 0.
mapping(bytes32 => uint256) internal assetActiveInvestmentsCount
assetHasCompletedInvestment
Maps an asset id => whether one of its investments has completed.
Completion is monotonic, so a boolean is enough to count {HStats.assetsWithCompletedInvestments} exactly once per asset.
mapping(bytes32 => bool) internal assetHasCompletedInvestment
Functions
constructor
Deploys the helper, setting the contract owner, the USDC token and the NFT.
constructor(address initialOwner, IERC20 ownerUsdToken_, HenriableVehicleNFT vehicleNft_) Ownable(initialOwner);
Parameters
| Name | Type | Description |
|---|---|---|
initialOwner | address | The address that will own the contract. |
ownerUsdToken_ | IERC20 | The USDC token used for investments, payouts and payments. |
vehicleNft_ | HenriableVehicleNFT | The vehicle-title NFT collection whose minter is this contract. |
onlyOwners
Restricts a function to owner1 or owner2.
Owner-managing functions keep OpenZeppelin’s {onlyOwner} (owner1 only), so owner2 can run admin actions but cannot set or clear owners. Reverts with OpenZeppelin’s {OwnableUnauthorizedAccount} when the caller is neither.
modifier onlyOwners() ;
isInvestmentStatus
Returns whether an investment is currently in any of the given statuses.
function isInvestmentStatus(bytes32 investmentId, HInvestmentStatus[] memory statuses)
internal
view
returns (bool);
Parameters
| Name | Type | Description |
|---|---|---|
investmentId | bytes32 | The id of the investment. |
statuses | HInvestmentStatus[] | The statuses to test for. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bool | True if the investment’s current status equals any entry in statuses. |
isAssetSettingsCorrect
Checks that an asset’s pricing settings can pay every investor and the owner.
The investor pools must cover the asset: every investor’s buying price times its slot count must be at least {HAsset.costPrice}, and the rider’s {HAsset.sellPrice} must cover that principal plus the profits promised to both pools plus {HAsset.ownerProfit}. The rider’s slashable savings ({HAsset.riderSlashableRepayableExtraCharge}) is charged on top of the sell price and refunded later, so it is deliberately excluded here.
function isAssetSettingsCorrect(HAsset memory asset) internal pure returns (bool);
Parameters
| Name | Type | Description |
|---|---|---|
asset | HAsset | The asset configuration to validate. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bool | True when the pools cover the cost price and the sell price covers the investor principal, their profits and the owner’s profit. |
calcInvestmentOpportunityLevel1SettingsAccuracy
Checks that the level-1 settings of a new investment opportunity are consistent with its asset, so the rider’s payments can cover the profits promised to the senior and junior investor pools.
Placeholder: always returns true until the real accuracy math is implemented and reviewed. The investment parameter is intentionally unused.
function calcInvestmentOpportunityLevel1SettingsAccuracy(HInvestment storage) internal pure returns (bool);
Returns
| Name | Type | Description |
|---|---|---|
<none> | bool | True when the level-1 settings are accurate. |
calcSeniorPoolPaidSoFar
Sums how much the senior investor pool has been paid so far on an investment.
An address may hold several senior seats, so a naive sum over the list would count that investor’s aggregate payout history once per seat. The mapping {HInvestment.seniorInvestors} points at the investor’s most recent seat, so only that seat’s entry counts, keeping each investor’s total counted once.
function calcSeniorPoolPaidSoFar(HInvestment storage investment) internal view returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
investment | HInvestment | The investment (storage reference). |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The total amount paid to senior investors, in USDC base units (6 decimals). |
calcJuniorPoolPaidSoFar
Sums how much the junior investor pool has been paid so far on an investment.
An address may hold several junior seats, so a naive sum over the list would count that investor’s aggregate payout history once per seat. The mapping {HInvestment.juniorInvestors} points at the investor’s most recent seat, so only that seat’s entry counts, keeping each investor’s total counted once.
function calcJuniorPoolPaidSoFar(HInvestment storage investment) internal view returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
investment | HInvestment | The investment (storage reference). |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The total amount paid to junior investors, in USDC base units (6 decimals). |
calcSharingFormula
Splits one rider payment across the owner and the two investor pools.
The rider’s refundable savings charge is collected on top of the payment and is not part of this split. The split is driven by what each pool is still owed, not by configurable percentages: the payment first fills the senior pool up to its remaining target (seats x (buying price + profit)), then the junior pool up to its target, and the owner receives whatever is left. Because the asset’s sell price covers the two pool targets plus {HAsset.ownerProfit}, this pays every investor their buying price plus profit in full and leaves the owner exactly its promised profit (plus any surplus when the sell price exceeds the targets). The owner absorbs integer-division dust.
function calcSharingFormula(HInvestment storage investment, HAsset storage asset, uint256 amount)
internal
view
returns (HSharingBreakdown memory);
Parameters
| Name | Type | Description |
|---|---|---|
investment | HInvestment | The investment being paid (storage reference). |
asset | HAsset | The asset backing the investment (storage reference). |
amount | uint256 | The rider payment to split, in USDC base units (6 decimals) (excludes the savings charge). |
Returns
| Name | Type | Description |
|---|---|---|
<none> | HSharingBreakdown | The per-bucket breakdown. |
calcRiderAmountToPayNow
Computes the payment a rider owes for the next instalment of an investment.
The rider owes {HAsset.sellPrice} in total and the outstanding balance is that minus what they have paid. The periodic minimum is capped by the outstanding balance on the final instalment, then the asset’s per-period savings charge is always added on top so the rider’s refundable savings keep accumulating.
function calcRiderAmountToPayNow(HInvestment storage investment, HAsset storage asset)
internal
view
returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
investment | HInvestment | The investment being paid (storage reference). |
asset | HAsset | The asset backing the investment (storage reference). |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The amount due for the next instalment, in USDC base units (6 decimals). |
maybeUpdateInvestmentStatus
Advances an investment’s lifecycle status when its current state and timing allow it.
State machine: every transition goes through setInvestmentStatus, which also keeps the stats counters in step.
- Pending -> AcceptingInvestments once the admin-set window opens
(
timeNextInvestmentStart <= now <= timeNextInvestmentEnd). - AcceptingInvestments -> InvestmentDone once the asset’s senior and junior pools are both filled, recording {HInvestment.investmentsDoneAt}.
- InvestmentDone -> AcceptingRiders once the admin-set hire window opens
(
timeNextRiderHireRequestStart <= now <= timeNextRiderHireRequestEnd). It runs lazily on first use (e.g. when an investor or rider calls in), so the status catches up. After each status update it returns.
function maybeUpdateInvestmentStatus(bytes32 investmentId) internal;
Parameters
| Name | Type | Description |
|---|---|---|
investmentId | bytes32 | The id of the investment to update. |
actionMaybeUpdateStatus
Provided for frontend to call when they suspect a status should have changed but it did not. e.g. When start investment countdown has begone but investment is still pending. We can’t run a cron job so it has to be triggered somehow minimally.
function actionMaybeUpdateStatus(bytes32 _investmentId) external;
upsertInvestor
Creates an investor profile for an address, or updates it if it exists.
function upsertInvestor(address investorAddress, HInvestor memory investorProfile) internal;
Parameters
| Name | Type | Description |
|---|---|---|
investorAddress | address | The investor’s address. |
investorProfile | HInvestor | The profile fields (name, country, age) to store. |
upsertRider
Creates a rider profile for an address, or updates it if it exists.
function upsertRider(address riderAddress, bytes32 riderName, bytes32 riderCountry, uint8 riderAge) internal;
Parameters
| Name | Type | Description |
|---|---|---|
riderAddress | address | The rider’s address. |
riderName | bytes32 | The rider’s name. |
riderCountry | bytes32 | The rider’s country. |
riderAge | uint8 | The rider’s age. |
recordDistribution
Records the accounting for one rider payment split across its beneficiaries.
Writes the payout state and moves no tokens, so the caller can keep the transfer step last (checks-effects-interactions). The owner and each investor in a tier share their pool equally; an empty tier or any division remainder stays in the contract. The rider’s savings charge is recorded separately by recordRiderSavings.
function recordDistribution(
HInvestment storage investment,
bytes32 investmentId,
HSharingBreakdown memory breakdown,
HPayoutType payoutType
) internal;
Parameters
| Name | Type | Description |
|---|---|---|
investment | HInvestment | The investment the payment belongs to (storage reference). |
investmentId | bytes32 | The id of the investment. |
breakdown | HSharingBreakdown | The owner/investor split of the payment. |
payoutType | HPayoutType | What produced the payout ({HPayoutType.RiderPaying} or {HPayoutType.RiderSavingsSlash}); stored on every entry it creates. |
recordRiderSavings
Records the rider’s per-period savings charge for an investment.
The savings are held in the contract (not transferred): they are refunded when the rider completes and can be slashed if the rider defaults.
function recordRiderSavings(HInvestment storage investment, uint256 amount) internal;
Parameters
| Name | Type | Description |
|---|---|---|
investment | HInvestment | The investment the payment belongs to (storage reference). |
amount | uint256 | The savings charge to add, in USDC base units (6 decimals). |
recordRiderSavingsSlash
Records a slash of the rider’s savings for an investment.
Reduces the rider’s refundable savings, appends a global slash entry, links it to the investment, and updates the investment and platform slash totals. Writes state only: the caller splits and transfers the slashed amount separately, as those are part of the normal payout accounting.
function recordRiderSavingsSlash(HInvestment storage investment, bytes32 investmentId, uint256 amount) internal;
Parameters
| Name | Type | Description |
|---|---|---|
investment | HInvestment | The investment the slash belongs to (storage reference). |
investmentId | bytes32 | The id of the investment. |
amount | uint256 | The amount to slash, in USDC base units (6 decimals). |
applyRiderSavingsSlash
Validates and applies a slash of the rider’s savings for an investment.
Reverts when the slash exceeds the rider’s saved amount. Reduces the savings, records the slash, then splits the amount to the owner and investor pools as {HPayoutType.RiderSavingsSlash} payouts and transfers them.
function applyRiderSavingsSlash(HInvestment storage investment, bytes32 investmentId, uint256 amount) internal;
Parameters
| Name | Type | Description |
|---|---|---|
investment | HInvestment | The investment the slash belongs to (storage reference). |
investmentId | bytes32 | The id of the investment. |
amount | uint256 | The amount to slash, in USDC base units (6 decimals); must be non-zero. |
recordTierPayouts
Records an equal-share payout for every investor in a tier.
function recordTierPayouts(
HInvestment storage investment,
bytes32 investmentId,
address[] storage tierInvestors,
uint256 poolAmount,
HPayoutType payoutType
) internal;
Parameters
| Name | Type | Description |
|---|---|---|
investment | HInvestment | The investment the payment belongs to (storage reference). |
investmentId | bytes32 | The id of the investment. |
tierInvestors | address[] | The tier’s investor list. |
poolAmount | uint256 | The total amount to split across the tier, in USDC base units (6 decimals). |
payoutType | HPayoutType | What produced the payout, stored on every entry it creates. |
transferDistribution
Transfers the owner and investor shares of a recorded distribution.
Call only after recordDistribution: this is the token-moving step.
function transferDistribution(HInvestment storage investment, HSharingBreakdown memory breakdown) internal;
Parameters
| Name | Type | Description |
|---|---|---|
investment | HInvestment | The investment the payment belongs to (storage reference). |
breakdown | HSharingBreakdown | The owner/investor/savings split of the payment. |
transferTierShares
Transfers an equal share of a tier’s pool to each of its investors.
function transferTierShares(address[] storage tierInvestors, uint256 poolAmount) internal;
Parameters
| Name | Type | Description |
|---|---|---|
tierInvestors | address[] | The tier’s investor list. |
poolAmount | uint256 | The total amount to split across the tier, in USDC base units (6 decimals). |
setAssetActive
Applies an asset’s active flag and keeps {HStats.activeAssets} in step.
The single write point for {HAsset.active} after creation, so the counter cannot drift.
function setAssetActive(HAsset storage asset, bool newActive) internal;
Parameters
| Name | Type | Description |
|---|---|---|
asset | HAsset | The asset to update (storage reference). |
newActive | bool | The requested active status. |
setInvestmentActive
Applies an investment’s active flag and keeps the running totals in step.
The single write point for {HInvestment.active} after creation. Updates {HStats.activeInvestments} and, via the asset’s active-investment count, {HStats.assetsWithRunningInvestments}.
function setInvestmentActive(HInvestment storage investment, bool newActive) internal;
Parameters
| Name | Type | Description |
|---|---|---|
investment | HInvestment | The investment to update (storage reference). |
newActive | bool | The requested active status. |
setInvestmentStatus
Applies an investment’s lifecycle status and keeps the running totals in step.
The single write point for {HInvestment.status} after creation, so the {HStats.investmentsInHire} and {HStats.investmentsPaidInFull} counters and the per-asset completion count cannot drift.
function setInvestmentStatus(HInvestment storage investment, HInvestmentStatus newStatus) internal;
Parameters
| Name | Type | Description |
|---|---|---|
investment | HInvestment | The investment to update (storage reference). |
newStatus | HInvestmentStatus | The requested lifecycle status. |
getOwnerUsdToken
Returns the USDC token used by the platform.
function getOwnerUsdToken() external view returns (IERC20);
Returns
| Name | Type | Description |
|---|---|---|
<none> | IERC20 | The {IERC20} owner USDC token. |
getOwner2
Returns the secondary owner, who may run admin actions but not manage owners.
function getOwner2() external view returns (address);
Returns
| Name | Type | Description |
|---|---|---|
<none> | address | The owner2 address, or address(0) when unset. |
getVehicleNft
Returns the vehicle-title NFT collection used for asset titles.
Lets callers reach the collection (e.g. to read token metadata) through the platform address alone, without a separately configured NFT address.
function getVehicleNft() external view returns (HenriableVehicleNFT);
Returns
| Name | Type | Description |
|---|---|---|
<none> | HenriableVehicleNFT | The {HenriableVehicleNFT} collection. |
getAssetsCount
Returns the total number of registered assets.
function getAssetsCount() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The length of {assetsList}. |
getAssetAt
Returns the asset registered at an index.
function getAssetAt(uint256 index) external view returns (HAsset memory);
Parameters
| Name | Type | Description |
|---|---|---|
index | uint256 | The index into {assetsList}. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | HAsset | The {HAsset} at the given index. |
getAsset
Returns an asset’s configuration by id.
function getAsset(bytes32 assetId) external view returns (HAsset memory);
Parameters
| Name | Type | Description |
|---|---|---|
assetId | bytes32 | The id of the asset. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | HAsset | The {HAsset} for the given id (zero-filled if it does not exist). |
getAssetExists
Returns whether an asset id is registered.
function getAssetExists(bytes32 assetId) external view returns (bool);
Parameters
| Name | Type | Description |
|---|---|---|
assetId | bytes32 | The id of the asset. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bool | True if the asset is registered. |
getAssetStorage
Returns a storage reference to a registered asset.
Hides the index + 1 bookkeeping so callers can read or write fields
directly, e.g. getAssetStorage(id).active = false;. Reverts if the
asset is not registered.
function getAssetStorage(bytes32 assetId) internal view returns (HAsset storage);
Parameters
| Name | Type | Description |
|---|---|---|
assetId | bytes32 | The id of the asset. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | HAsset | A storage reference to the asset. |
getAssetInvestmentIds
Returns the ids of the investments created for an asset.
function getAssetInvestmentIds(bytes32 assetId) external view returns (bytes32[] memory);
Parameters
| Name | Type | Description |
|---|---|---|
assetId | bytes32 | The id of the asset. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bytes32[] | An array of investment ids. |
getAssetInvestmentStorage
Returns a storage reference to an investment created for an asset.
Hides the index + 1 bookkeeping used by {assetInvestments}.
function getAssetInvestmentStorage(bytes32 assetId, uint256 position) internal view returns (HInvestment storage);
Parameters
| Name | Type | Description |
|---|---|---|
assetId | bytes32 | The id of the asset. |
position | uint256 | The position in the asset’s investment list. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | HInvestment | A storage reference to the investment. |
getAssetInvestmentsCount
Returns the number of investments created for an asset.
function getAssetInvestmentsCount(bytes32 assetId) external view returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
assetId | bytes32 | The id of the asset. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The count of investments for the asset. |
getInvestmentsCount
Returns the total number of investment opportunities.
function getInvestmentsCount() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The length of {investmentsList}. |
getInvestmentIndex
Returns the 1-based index in {investmentsList} for an investment id.
Positions are 1-based (0 means “not registered”); to index the array directly, callers subtract 1.
function getInvestmentIndex(bytes32 investmentId) external view returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
investmentId | bytes32 | The id of the investment. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The 1-based index, or 0 if the investment is not registered. |
getInvestmentStorage
Returns a storage reference to a registered investment.
Hides the index + 1 bookkeeping so callers can read or write fields
directly, e.g. getInvestmentStorage(id).active = false;. Reverts if
the investment is not registered.
function getInvestmentStorage(bytes32 investmentId) internal view returns (HInvestment storage);
Parameters
| Name | Type | Description |
|---|---|---|
investmentId | bytes32 | The id of the investment. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | HInvestment | A storage reference to the investment. |
getInvestmentCore
Returns the core (half-investment) fields of an investment.
function getInvestmentCore(uint256 index)
external
view
returns (
bytes32 investmentId,
bool active,
bytes32 assetId,
uint256 investmentsDoneAt,
uint256 riderInitialBuyinUsd,
uint256 periodicRiderPayingInMinutes,
uint256 minimumRiderPeriodicPayingsUsd,
HInvestmentStatus status
);
Parameters
| Name | Type | Description |
|---|---|---|
index | uint256 | The index into {investmentsList}. |
Returns
| Name | Type | Description |
|---|---|---|
investmentId | bytes32 | Unique investment id. |
active | bool | Whether the opportunity is active. |
assetId | bytes32 | Asset being invested in. |
investmentsDoneAt | uint256 | Time the funding target was reached. |
riderInitialBuyinUsd | uint256 | Initial rider buy-in, in USDC base units (6 decimals). |
periodicRiderPayingInMinutes | uint256 | Length of a rider period, in minutes. |
minimumRiderPeriodicPayingsUsd | uint256 | Minimum rider payment per period, in USDC base units (6 decimals). |
status | HInvestmentStatus | Current lifecycle status. |
getInvestmentSchedule
Returns the scheduling fields of an investment.
function getInvestmentSchedule(uint256 index)
external
view
returns (
uint256 timeNextInvestmentStart,
uint256 timeNextInvestmentEnd,
uint256 timeNextRiderHireRequestStart,
uint256 timeNextRiderHireRequestEnd
);
Parameters
| Name | Type | Description |
|---|---|---|
index | uint256 | The index into {investmentsList}. |
Returns
| Name | Type | Description |
|---|---|---|
timeNextInvestmentStart | uint256 | Start of the next investment round. |
timeNextInvestmentEnd | uint256 | End of the next investment round. |
timeNextRiderHireRequestStart | uint256 | Start of the next hire-request round. |
timeNextRiderHireRequestEnd | uint256 | End of the next hire-request round. |
getInvestmentRiderInfo
Returns the rider hire-purchase fields of an investment.
function getInvestmentRiderInfo(uint256 index)
external
view
returns (
address riderWhoHiredIt,
uint256 riderNextPayinDate,
uint256 nftTokenId,
uint256 timeRiderCompletedPayments,
uint256 timeNftTransferedToRider
);
Parameters
| Name | Type | Description |
|---|---|---|
index | uint256 | The index into {investmentsList}. |
Returns
| Name | Type | Description |
|---|---|---|
riderWhoHiredIt | address | Address of the rider who hired the asset. |
riderNextPayinDate | uint256 | Time the rider’s next payment is due. |
nftTokenId | uint256 | Token id of the NFT title for the asset. |
timeRiderCompletedPayments | uint256 | Time the rider completed all payments. |
timeNftTransferedToRider | uint256 | Time the NFT title was transferred to the rider. |
getTitleInfo
Returns what a title token needs for its metadata: the asset name and rider.
Read by {HenriableVehicleNFT.tokenURI} so the on-chain card can show the vehicle and the rider. Returns zero values for an unknown token, or before a rider is hired, which the metadata treats as “omit”.
function getTitleInfo(uint256 tokenId) external view returns (bytes32 assetName, address rider);
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The title’s token id. |
Returns
| Name | Type | Description |
|---|---|---|
assetName | bytes32 | The bytes32 name of the asset the title represents. |
rider | address | The rider who hired the asset, or address(0) if none yet. |
getSeniorInvestorsList
Returns the list of senior investors for an investment.
function getSeniorInvestorsList(uint256 index) external view returns (address[] memory);
Parameters
| Name | Type | Description |
|---|---|---|
index | uint256 | The index into {investmentsList}. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | address[] | The senior investor addresses. |
getJuniorInvestorsList
Returns the list of junior investors for an investment.
function getJuniorInvestorsList(uint256 index) external view returns (address[] memory);
Parameters
| Name | Type | Description |
|---|---|---|
index | uint256 | The index into {investmentsList}. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | address[] | The junior investor addresses. |
getSeniorInvestorIndex
Returns a senior investor’s 1-based index within an investment’s senior list.
Positions are 1-based; 0 means the investor is not in the list. When an investor holds several seats, this is their most recently taken seat.
function getSeniorInvestorIndex(bytes32 investmentId, address investor) external view returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
investmentId | bytes32 | The id of the investment. |
investor | address | The investor address. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The 1-based index, or 0 if not present. |
getJuniorInvestorIndex
Returns a junior investor’s 1-based index within an investment’s junior list.
Positions are 1-based; 0 means the investor is not in the list. When an investor holds several seats, this is their most recently taken seat.
function getJuniorInvestorIndex(bytes32 investmentId, address investor) external view returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
investmentId | bytes32 | The id of the investment. |
investor | address | The investor address. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The 1-based index, or 0 if not present. |
getRidersHirePurchaseRequestsList
Returns the rider ids of the hire-purchase requests for an investment.
function getRidersHirePurchaseRequestsList(uint256 index) external view returns (bytes32[] memory);
Parameters
| Name | Type | Description |
|---|---|---|
index | uint256 | The index into {investmentsList}. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bytes32[] | An array of rider ids. |
getInvestmentHireRequestStorage
Returns a storage reference to a hire-purchase request of an investment.
Hides the index + 1 bookkeeping used by the investment’s request list.
function getInvestmentHireRequestStorage(bytes32 investmentId, uint256 position)
internal
view
returns (HRiderHirePurchaseRequest storage);
Parameters
| Name | Type | Description |
|---|---|---|
investmentId | bytes32 | The id of the investment. |
position | uint256 | The position in the investment’s hire-request list. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | HRiderHirePurchaseRequest | A storage reference to the hire-purchase request. |
getRiderHirePurchaseRequestIndex
Returns a rider’s 1-based position in an investment’s hire-request list.
Positions are 1-based; 0 means the rider has no request for the investment.
function getRiderHirePurchaseRequestIndex(bytes32 investmentId, address rider) external view returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
investmentId | bytes32 | The id of the investment. |
rider | address | The rider address. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The 1-based position, or 0 if not present. |
getInvestmentRiderPayinsHistory
Returns the rider payment history of an investment.
function getInvestmentRiderPayinsHistory(uint256 index) external view returns (HPayingHistory memory);
Parameters
| Name | Type | Description |
|---|---|---|
index | uint256 | The index into {investmentsList}. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | HPayingHistory | The {HPayingHistory} for the investment’s rider. |
getInvestmentRiderSavings
Returns the rider savings record of an investment.
function getInvestmentRiderSavings(uint256 index) external view returns (HRiderSavingsHistory memory);
Parameters
| Name | Type | Description |
|---|---|---|
index | uint256 | The index into {investmentsList}. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | HRiderSavingsHistory | The {HRiderSavingsHistory} for the investment’s rider. |
getInvestorPayoutHistory
Returns one investor’s payout history for an investment.
function getInvestorPayoutHistory(bytes32 investmentId, address investor)
external
view
returns (HInvestorPayoutsHistory memory);
Parameters
| Name | Type | Description |
|---|---|---|
investmentId | bytes32 | The id of the investment. |
investor | address | The investor address. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | HInvestorPayoutsHistory | The {HInvestorPayoutsHistory} for that investor. |
getInvestmentPayoutHistory
Returns the aggregate payout history of an investment.
function getInvestmentPayoutHistory(uint256 index) external view returns (HInvestmentPayoutsHistory memory);
Parameters
| Name | Type | Description |
|---|---|---|
index | uint256 | The index into {investmentsList}. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | HInvestmentPayoutsHistory | The {HInvestmentPayoutsHistory} for the investment. |
getInvestmentContractPayoutHistory
Returns the contract/owner payout history recorded on an investment.
function getInvestmentContractPayoutHistory(uint256 index) external view returns (HOwnerPayoutsHistory memory);
Parameters
| Name | Type | Description |
|---|---|---|
index | uint256 | The index into {investmentsList}. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | HOwnerPayoutsHistory | The {HOwnerPayoutsHistory} for the investment. |
getInvestorsCount
Returns the total number of registered investors.
function getInvestorsCount() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The length of {investorsList}. |
getInvestorIndex
Returns an investor’s 1-based index in {investorsList}.
Positions are 1-based (0 means “not registered”); to index the array directly, callers subtract 1.
function getInvestorIndex(address investor) external view returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
investor | address | The investor address. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The 1-based index, or 0 if the investor is not registered. |
getInvestorStorage
Returns a storage reference to a registered investor.
Hides the index + 1 bookkeeping so callers can read or write fields
directly. Reverts if the investor is not registered.
function getInvestorStorage(address investor) internal view returns (HInvestor storage);
Parameters
| Name | Type | Description |
|---|---|---|
investor | address | The investor address. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | HInvestor | A storage reference to the investor. |
getInvestorAt
Returns the investor registered at an index.
function getInvestorAt(uint256 index) external view returns (HInvestor memory);
Parameters
| Name | Type | Description |
|---|---|---|
index | uint256 | The index into {investorsList}. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | HInvestor | The {HInvestor} at the given index. |
getInvestor
Returns the investor profile for an address.
function getInvestor(address investor) external view returns (HInvestor memory);
Parameters
| Name | Type | Description |
|---|---|---|
investor | address | The investor address. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | HInvestor | The {HInvestor} for the address (zero-filled if not registered). |
getRidersCount
Returns the total number of registered riders.
function getRidersCount() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The length of {ridersList}. |
getRiderIndex
Returns a rider’s 1-based index in {ridersList}.
Positions are 1-based (0 means “not registered”); to index the array directly, callers subtract 1.
function getRiderIndex(address rider) external view returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
rider | address | The rider address. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The 1-based index, or 0 if the rider is not registered. |
getRiderStorage
Returns a storage reference to a registered rider.
Hides the index + 1 bookkeeping so callers can read or write fields
directly. Reverts if the rider is not registered.
function getRiderStorage(address rider) internal view returns (HRider storage);
Parameters
| Name | Type | Description |
|---|---|---|
rider | address | The rider address. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | HRider | A storage reference to the rider. |
getRiderAt
Returns the rider registered at an index.
function getRiderAt(uint256 index) external view returns (HRider memory);
Parameters
| Name | Type | Description |
|---|---|---|
index | uint256 | The index into {ridersList}. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | HRider | The {HRider} at the given index. |
getRider
Returns the rider profile for an address.
function getRider(address rider) external view returns (HRider memory);
Parameters
| Name | Type | Description |
|---|---|---|
rider | address | The rider address. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | HRider | The {HRider} for the address (zero-filled if not registered). |
getHireRequestsCount
Returns the total number of rider hire-purchase requests.
function getHireRequestsCount() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The length of {ridersHirePurchasesRequestsList}. |
getHireRequestAt
Returns a rider hire-purchase request at an index.
function getHireRequestAt(uint256 index) external view returns (HRiderHirePurchaseRequest memory);
Parameters
| Name | Type | Description |
|---|---|---|
index | uint256 | The index into {ridersHirePurchasesRequestsList}. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | HRiderHirePurchaseRequest | The {HRiderHirePurchaseRequest} at the given index. |
getRejectedRiderIndex
Returns whether/how a rider was rejected for an investment.
function getRejectedRiderIndex(bytes32 riderId, bytes32 investmentId) external view returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
riderId | bytes32 | The id of the rider. |
investmentId | bytes32 | The id of the investment. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | A non-zero marker if the rider was rejected, otherwise zero. |
getRiderPayinsCount
Returns the total number of rider payments.
function getRiderPayinsCount() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The length of {riderPayinsList}. |
getRiderPayinAt
Returns a rider payment at an index.
function getRiderPayinAt(uint256 index) external view returns (HRiderPayin memory);
Parameters
| Name | Type | Description |
|---|---|---|
index | uint256 | The index into {riderPayinsList}. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | HRiderPayin | The {HRiderPayin} at the given index. |
getRiderPayinIndexes
Returns the payment indices recorded on an investment.
function getRiderPayinIndexes(bytes32 investmentId) external view returns (uint256[] memory);
Parameters
| Name | Type | Description |
|---|---|---|
investmentId | bytes32 | The id of the investment. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256[] | The 1-based indices into the global rider payins list. |
getRiderAmountToPayNow
Returns how much the calling rider must pay for the next instalment of an investment, including the asset’s per-period savings charge.
Reads the investment’s rider payment history for the outstanding balance. Returns 0 when the caller is not the investment’s hired rider or the rider has already met the target total.
function getRiderAmountToPayNow(bytes32 investmentId) external view returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
investmentId | bytes32 | The id of the investment. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The amount the caller should pay now, in USDC base units (6 decimals). |
getRiderSavingsSlashesCount
Returns the total number of rider savings slashes.
function getRiderSavingsSlashesCount() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The length of {riderSavingsSlashesList}. |
getRiderSavingsSlashAt
Returns a rider savings slash at an index.
function getRiderSavingsSlashAt(uint256 index) external view returns (HRiderSavingsSlash memory);
Parameters
| Name | Type | Description |
|---|---|---|
index | uint256 | The index into {riderSavingsSlashesList}. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | HRiderSavingsSlash | The {HRiderSavingsSlash} at the given index. |
getRiderSavingsSlashIndex
Returns the most recent savings slash index for an investment.
function getRiderSavingsSlashIndex(bytes32 investmentId) external view returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
investmentId | bytes32 | The id of the investment. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The 1-based index into {riderSavingsSlashesList}, or 0 if none. |
getInvestmentRiderSavingsSlashes
Returns the savings slash indices recorded on an investment.
function getInvestmentRiderSavingsSlashes(bytes32 investmentId) external view returns (uint256[] memory);
Parameters
| Name | Type | Description |
|---|---|---|
investmentId | bytes32 | The id of the investment. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256[] | The 1-based indices into the global rider savings slashes list. |
getInvestmentRiderSavingsSlashesHistory
Returns the aggregate savings slash history of an investment.
function getInvestmentRiderSavingsSlashesHistory(uint256 index)
external
view
returns (HRiderSavingsSlashesHistory memory);
Parameters
| Name | Type | Description |
|---|---|---|
index | uint256 | The index into {investmentsList}. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | HRiderSavingsSlashesHistory | The {HRiderSavingsSlashesHistory} for the investment. |
getInvestorPayoutsCount
Returns the total number of investor payouts.
function getInvestorPayoutsCount() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The length of {investorPayoutList}. |
getInvestorPayoutAt
Returns an investor payout at an index.
function getInvestorPayoutAt(uint256 index) external view returns (HInvestorPayout memory);
Parameters
| Name | Type | Description |
|---|---|---|
index | uint256 | The index into {investorPayoutList}. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | HInvestorPayout | The {HInvestorPayout} at the given index. |
getInvestorPayoutIndex
Returns an investor’s payout index for an investment.
function getInvestorPayoutIndex(address investor, bytes32 investmentId) external view returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
investor | address | The investor address. |
investmentId | bytes32 | The id of the investment. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The index into {investorPayoutList}. |
getOwnerPayoutsCount
Returns the total number of owner payouts.
function getOwnerPayoutsCount() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The length of {ownerPayoutsList}. |
getOwnerPayoutAt
Returns an owner payout at an index.
function getOwnerPayoutAt(uint256 index) external view returns (HOwnerPayout memory);
Parameters
| Name | Type | Description |
|---|---|---|
index | uint256 | The index into {ownerPayoutsList}. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | HOwnerPayout | The {HOwnerPayout} at the given index. |
getOwnerPayoutIndex
Returns the most recent owner payout index for an investment.
function getOwnerPayoutIndex(bytes32 investmentId) external view returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
investmentId | bytes32 | The id of the investment. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The index into {ownerPayoutsList}. |
getOwnerPayoutHistory
Returns the aggregate owner payout history for an investment.
function getOwnerPayoutHistory(bytes32 investmentId) external view returns (HOwnerPayoutsHistory memory);
Parameters
| Name | Type | Description |
|---|---|---|
investmentId | bytes32 | The id of the investment. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | HOwnerPayoutsHistory | The {HOwnerPayoutsHistory} for the investment. |
getCompletedRiderInvestmentsCount
Returns the number of completed rider investments.
function getCompletedRiderInvestmentsCount() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The length of {completedRiderInvestmentList}. |
getCompletedRiderInvestmentAt
Returns a completed rider investment index.
function getCompletedRiderInvestmentAt(uint256 index) external view returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
index | uint256 | The index into {completedRiderInvestmentList}. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The 1-based index into {investmentsList} (subtract 1 to index the array). |
getInvestmentsCompletedCount
Returns the number of investments marked complete.
function getInvestmentsCompletedCount() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The length of {investmentsCompleted}. |
getInvestmentsCompletedAt
Returns a completed investment index.
function getInvestmentsCompletedAt(uint256 index) external view returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
index | uint256 | The index into {investmentsCompleted}. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The 1-based index into {investmentsList} (subtract 1 to index the array). |
getInvestors
Returns every registered investor profile.
Returns the whole list in one call; the paginated getInvestorsCount / getInvestorAt pair remains available for callers that page.
function getInvestors() external view returns (HInvestor[] memory);
Returns
| Name | Type | Description |
|---|---|---|
<none> | HInvestor[] | All entries of {investorsList}. |
getRiders
Returns every registered rider profile.
Returns the whole list in one call; the paginated getRidersCount / getRiderAt pair remains available for callers that page.
function getRiders() external view returns (HRider[] memory);
Returns
| Name | Type | Description |
|---|---|---|
<none> | HRider[] | All entries of {ridersList}. |
getHireRequests
Returns every rider hire-purchase request ever made.
Returns the whole list in one call; the paginated getHireRequestsCount / getHireRequestAt pair remains available for callers that page.
function getHireRequests() external view returns (HRiderHirePurchaseRequest[] memory);
Returns
| Name | Type | Description |
|---|---|---|
<none> | HRiderHirePurchaseRequest[] | All entries of {ridersHirePurchasesRequestsList}. |
getInvestorPayouts
Returns every investor payout ever made.
Returns the whole list in one call; the paginated getInvestorPayoutsCount / getInvestorPayoutAt pair remains available for callers that page.
function getInvestorPayouts() external view returns (HInvestorPayout[] memory);
Returns
| Name | Type | Description |
|---|---|---|
<none> | HInvestorPayout[] | All entries of {investorPayoutList}. |
getRiderPayins
Returns every rider periodic payment ever made.
Returns the whole list in one call; the paginated getRiderPayinsCount / getRiderPayinAt pair remains available for callers that page.
function getRiderPayins() external view returns (HRiderPayin[] memory);
Returns
| Name | Type | Description |
|---|---|---|
<none> | HRiderPayin[] | All entries of {riderPayinsList}. |
getOwnerPayouts
Returns every owner/contract payout ever made.
Returns the whole list in one call; the paginated getOwnerPayoutsCount / getOwnerPayoutAt pair remains available for callers that page.
function getOwnerPayouts() external view returns (HOwnerPayout[] memory);
Returns
| Name | Type | Description |
|---|---|---|
<none> | HOwnerPayout[] | All entries of {ownerPayoutsList}. |
getRiderSavingsSlashes
Returns every rider savings slash ever applied.
Returns the whole list in one call; the paginated getRiderSavingsSlashesCount / getRiderSavingsSlashAt pair remains available for callers that page.
function getRiderSavingsSlashes() external view returns (HRiderSavingsSlash[] memory);
Returns
| Name | Type | Description |
|---|---|---|
<none> | HRiderSavingsSlash[] | All entries of {riderSavingsSlashesList}. |
HMath
Title: HMath
Author: Obiaraije Henry
Stateless numeric helpers shared across the Henriable contracts.
Functions
min
Returns the smaller of two values.
function min(uint256 a, uint256 b) internal pure returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
a | uint256 | First value to compare. |
b | uint256 | Second value to compare. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The smaller of a and b. |
max
Returns the larger of two values.
function max(uint256 a, uint256 b) internal pure returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
a | uint256 | First value to compare. |
b | uint256 | Second value to compare. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The larger of a and b. |
Contents
MockUSDC
Inherits: ERC20
Title: MockUSDC
Author: Obiaraije Henry
Minimal 6-decimal ERC20 token standing in for USDC on a local network.
Used by the deploy script; the platform only touches it through {IERC20}. It exposes an unrestricted mint faucet so local balances can be funded; never use it outside a test network.
Functions
constructor
Deploys the mock token with the USDC name and symbol.
constructor() ERC20("USD Coin", "USDC");
mint
Mints amount tokens to to.
Deliberately unrestricted: this is a local test faucet with no access control, so any address can be funded. Do not deploy on a real network.
function mint(address to, uint256 amount) external;
Parameters
| Name | Type | Description |
|---|---|---|
to | address | The address receiving the newly minted tokens. |
amount | uint256 | The amount to mint, in token units (6 decimals). |
decimals
USDC uses 6 decimals rather than the ERC20 default of 18.
function decimals() public pure override returns (uint8);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint8 | The number of decimals, 6. |
Contents
- HAsset
- HInvestment
- HInvestor
- HRider
- HRiderHirePurchaseRequest
- HRiderPayin
- HSharingBreakdown
- HPayingHistory
- HOwnerPayout
- HOwnerPayoutsHistory
- HInvestorPayout
- HInvestorPayoutsHistory
- HInvestmentPayoutsHistory
- HRiderSavingsHistory
- HRiderSavings
- HRiderSavingsSlash
- HRiderSavingsSlashesHistory
- HStats
- HInvestmentType
- HInvestmentStatus
- HPayoutType
- HOwner2IsOwner1
- HAssetInvalidId
- HAssetAlreadyExists
- HAssetDoesNotExist
- HAssetHasNonPendingInvestments
- HAssetInvalidName
- HAssetInvalidCostPrice
- HAssetInvalidSellPrice
- HAssetNotActive
- HAssetInvalidSettings
- HInvestmentInvalidId
- HInvestmentAlreadyExists
- HInvestmentDoesNotExist
- HInvestmentInvalidRiderInitialBuyin
- HInvestmentRiderInitialBuyinTooHigh
- HInvestmentInvalidPeriodicRiderPayingInMinutes
- HInvestmentInvalidMinimumRiderPeriodicPayings
- HInvestmentHasInvestors
- HInvestmentInvalidSettings
- HInvestmentNotPending
- HInvestmentNotDone
- HInvestmentInvalidStartTime
- HInvestmentInvalidEndTime
- HInvestmentNotActive
- HInvestmentNotAccepting
- HInvestmentInvalidAmount
- HInvestmentNoOpenSlot
- HInvestorDoesNotExist
- HInvestorInvalidAge
- HInvestmentNotAcceptingRiders
- HRiderInvalidName
- HRiderInvalidCountry
- HRiderInvalidAge
- HRiderInsufficientInitialBuyin
- HRiderAlreadyRegistered
- HInvestmentAlreadyHasHiredRider
- HRiderDidNotApplyForHire
- HRiderAlreadyRejectedForHire
- HRiderDoesNotExist
- HInvestmentNotHired
- HRiderNotHired
- HRiderPaymentsCompleted
- HRiderPaymentsNotCompleted
- HInvestmentAlreadyComplete
- HRiderPayinBelowMinimum
- HRiderPayinLate
- HInvestmentInvalidRiderNextPayinDate
- HRiderSavingsSlashExceedsSaved
- HVehicleNftUnauthorizedMinter
- common constants
HAsset
Title: HAsset
Defines an asset (e.g. Keke, Car, Bike, Truck) that riders can acquire through hire purchase and that investors can fund.
The struct holds both the physical/economic settings of the asset and the aggregate economics of the investor pools funding it. The admin configures these values, and they are validated (via the asset/opportunity accuracy calculators) to guarantee that the amount riders pay over time covers the profits promised to senior and junior investors.
struct HAsset {
/// @notice Unique identifier of the asset.
/// @dev Used as the primary key for assets and referenced by investments.
bytes32 id;
/// @notice Whether the asset is currently active and available for investment.
/// @dev May only be toggled off while no investor has invested in any
/// investment that uses this asset.
bool active;
/// @notice Human-readable name of the asset (e.g. "Keke-0001-2026", "Bike-0001-2026").
bytes32 name;
/// @notice Purchase/cost price of the asset, in USDC base units (6 decimals).
/// @dev The amount required to acquire one unit of the asset.
uint256 costPrice;
/// @notice Total amount the rider would need to pay over the life of the hire purchase, in USDC base units (6 decimals).
/// @dev Must be large enough to cover the asset cost plus the profits
/// promised to both the senior and junior investor pools (except the fixed extra charge for rider slashable, refundable, savings).
uint256 sellPrice;
/// @notice Buying price contributed by one senior investor, in USDC base units (6 decimals).
/// @dev The senior pool total is this times {totalNumberOfSeniorInvestorsNeeded}.
uint256 oneSeniorInvestorBuyingPrice;
/// @notice Profit one senior investor earns over time, in USDC base units (6 decimals).
/// @dev Senior investors are paid first and carry the lowest risk/reward.
uint256 oneSeniorInvestorProfit;
/// @notice Buying price contributed by one junior investor, in USDC base units (6 decimals).
/// @dev The junior pool total is this times {totalNumberOfJuniorInvestorsNeeded}.
uint256 oneJuniorInvestorBuyingPrice;
/// @notice Profit one junior investor earns over time, in USDC base units (6 decimals).
/// @dev Junior investors are paid after senior investors and carry the
/// higher risk/reward.
uint256 oneJuniorInvestorProfit;
/// @notice At every paying, this amount is charged extra from the rider and saved for the rider,
/// in USDC base units (6 decimals).
/// Then on the day of ownership transfer, its refunded to the rider.
/// This would help with repairs and reward for their faithfulness through the process.
/// If they default, these savings could be slashed as penalty and to fund investor payouts.
uint256 riderSlashableRepayableExtraCharge;
/// @notice Profit owner will earn over time, in USDC base units (6 decimals).
uint256 ownerProfit;
/// @notice Reserved. Payouts are driven by each pool's buying price plus profit (see
/// {HAsset.oneSeniorInvestorBuyingPrice}/{HAsset.oneSeniorInvestorProfit} and their
/// junior equivalents), so this share no longer affects any payout.
uint256 sharingPercentSeniorInvestor;
/// @notice Reserved. Payouts are driven by each pool's buying price plus profit, so this
/// share no longer affects any payout.
uint256 sharingPercentJuniorInvestor;
/// @notice Reserved. The owner receives the remainder after both pools are paid up to
/// their buying price plus profit, so this share no longer affects any payout.
uint256 sharingPercentOwner;
/// @notice Reserved. Payouts are driven by each pool's buying price plus profit, so this
/// share no longer affects any payout.
uint256 sharingPercentJuniorInvestorAfterSeniorPaid;
/// @notice Reserved. The owner receives the remainder after both pools are paid up to
/// their buying price plus profit, so this share no longer affects any payout.
uint256 sharingPercentOwnerAfterSeniorPaid;
/// @notice Number of senior investor slots required to fund one unit of this asset.
/// @dev Used to know when the senior pool is fully funded.
uint256 totalNumberOfSeniorInvestorsNeeded;
/// @notice Number of junior investor slots required to fund one unit of this asset.
/// @dev Used to know when the junior pool is fully funded.
uint256 totalNumberOfJuniorInvestorsNeeded;
}
HInvestment
Title: HInvestment
The full on-chain record of an investment opportunity.
Solidity structs cannot inherit, so the admin-supplied creation settings and the contract-filled fields are combined into this single struct and demarcated by the editor-folds below.
struct HInvestment {
//<editor-fold desc="Fields: Admin Supplied">
/// @notice Unique identifier of this investment slot.
bytes32 investmentId;
/// @notice Identifier of the {HAsset} this opportunity invests in.
bytes32 assetId;
/// @notice Initial buy-in a rider must pay to start the hire purchase, in USDC base units (6 decimals).
uint256 riderInitialBuyinUsd;
/// @notice Length of each rider payment period, in minutes.
uint256 periodicRiderPayingInMinutes;
/// @notice Minimum amount a rider must pay per period, in USDC base units (6 decimals).
uint256 minimumRiderPeriodicPayingsUsd;
//</editor-fold desc="Fields: Admin Supplied">
//<editor-fold desc="Fields: Contract Filled">
/// @notice Whether this opportunity is active.
/// @dev May only be changed while no investor has invested in it. Forced
/// active when the opportunity is created.
bool active;
/// @notice Ordered list of senior investor addresses that have invested.
address[] seniorInvestorsList;
/// @notice Maps a senior investor address to its index in {seniorInvestorsList}.
mapping(address => uint256) seniorInvestors;
/// @notice Ordered list of junior investor addresses that have invested.
address[] juniorInvestorsList;
/// @notice Maps a junior investor address to its index in {juniorInvestorsList}.
mapping(address => uint256) juniorInvestors;
/// @notice Timestamp at which the investment finished raising its target.
uint256 investmentsDoneAt;
/// @notice Current lifecycle state of the investment.
HInvestmentStatus status;
//</editor-fold desc="Fields: Contract Filled">
//<editor-fold desc="Fields: Scheduling">
/// @notice Timestamp at which the next investment round is allowed to start.
uint256 timeNextInvestmentStart;
/// @notice Timestamp at which the next investment round ends.
uint256 timeNextInvestmentEnd;
/// @notice Timestamp at which the next rider hire-request round starts.
uint256 timeNextRiderHireRequestStart;
/// @notice Timestamp at which the next rider hire-request round ends.
uint256 timeNextRiderHireRequestEnd;
//</editor-fold desc="Fields: Scheduling">
//<editor-fold desc="Fields: Rider Hire Purchase">
/// @notice Indices (into the riders' request list) of hire requests for this investment.
uint256[] ridersHirePurchaseRequestsList;
/// @notice Maps a rider address to its index in {ridersHirePurchaseRequestsList}.
mapping(address => uint256) ridersHirePurchaseRequests;
/// @notice Address of the rider who has hired (or will hire) this asset.
address riderWhoHiredIt;
/// @notice Timestamp at which the rider's next periodic payment is due.
uint256 riderNextPayinDate;
/// @notice Aggregate record of the rider's payments toward this investment.
HPayingHistory riderPayinsHistory;
/// @notice Indices (into the global rider payins list) of this investment's payments,
/// stored as `index + 1`.
uint256[] riderPayinIndexes;
//</editor-fold desc="Fields: Rider Hire Purchase">
//<editor-fold desc="Fields: Rider Savings">
/// @notice Record of savings accumulated from the rider's payments (slashable).
HRiderSavingsHistory riderSavings;
/// @notice Indices (into the global rider savings slashes list) of the slashes applied to
/// this investment's rider savings, stored as `index + 1`.
uint256[] riderSavingsSlashes;
/// @notice Aggregate record of the savings slashed from this investment's rider.
HRiderSavingsSlashesHistory riderSavingsSlashesHistory;
//</editor-fold desc="Fields: Rider Savings">
//<editor-fold desc="Fields: Payouts">
/// @notice Per-investor payout history for this investment.
mapping(address => HInvestorPayoutsHistory) investorPayoutHistory;
/// @notice Aggregate payout history for this investment across all investors.
HInvestmentPayoutsHistory investmentPayoutHistory;
/// @notice Payout history for the contract/owner on this investment.
HOwnerPayoutsHistory contractPayoutHistory;
//</editor-fold desc="Fields: Payouts">
//<editor-fold desc="Fields: Completion">
/// @notice Token id of the NFT title minted for the asset in this investment.
uint256 nftTokenId;
/// @notice Timestamp at which the rider completed all payments.
uint256 timeRiderCompletedPayments;
/// @notice Timestamp at which the NFT title was transferred to the rider.
uint256 timeNftTransferedToRider;
//</editor-fold desc="Fields: Completion">
}
HInvestor
Title: HInvestor
Profile of an investor participating in the platform.
struct HInvestor {
/// @notice Wallet address of the investor.
address investorAddress;
/// @notice Investor's name.
bytes32 name;
/// @notice Investor's country.
bytes32 country;
/// @notice Investor's age in years; must be at least 18.
uint8 age;
}
HRider
Title: HRider
Profile of a rider who acquires an asset through hire purchase.
struct HRider {
/// @notice Wallet address of the rider.
address riderAddress;
/// @notice Rider's name.
bytes32 name;
/// @notice Rider's country.
bytes32 country;
/// @notice Rider's age in years; must be at least 18.
uint8 age;
}
HRiderHirePurchaseRequest
Title: HRiderHirePurchaseRequest
A rider’s request to hire the asset backing a given investment.
struct HRiderHirePurchaseRequest {
/// @notice Identifier of the rider making the request.
/// @dev The rider's address encoded as bytes32.
bytes32 riderId;
/// @notice Identifier of the investment the rider is requesting.
bytes32 investmentId;
/// @notice Timestamp at which the request was made.
uint256 timeRequested;
}
HRiderPayin
Title: HRiderPayin
A single periodic payment made by a rider under a hire purchase.
struct HRiderPayin {
/// @notice Identifier of the paying rider.
bytes32 riderId;
/// @notice Identifier of the investment the payment is for.
bytes32 investmentId;
/// @notice Amount paid in this instalment, in USDC base units (6 decimals).
uint256 amountPaid;
/// @notice Timestamp at which the payment was made.
uint256 timePaid;
/// @notice Address the payment was transferred into.
address addressPaidInto;
}
HSharingBreakdown
Title: HSharingBreakdown
Split of one rider periodic payment across the owner and the investor pools.
Returned by the sharing calculator; the caller credits each party. The rider’s refundable savings charge is collected separately and is not part of this split.
struct HSharingBreakdown {
/// @notice Amount credited to the contract owner, in USDC base units (6 decimals).
uint256 ownerAmount;
/// @notice Total amount credited to the senior investor pool, in USDC base units (6 decimals).
uint256 seniorInvestorsAmount;
/// @notice Total amount credited to the junior investor pool, in USDC base units (6 decimals).
uint256 juniorInvestorsAmount;
}
HPayingHistory
Title: HPayingHistory
Aggregate record of a rider’s payments toward one investment.
The total the rider owes is {HAsset.sellPrice}; this struct only tracks what they have paid so far against it.
struct HPayingHistory {
/// @notice Address of the rider.
address riderAddress;
/// @notice Total amount the rider has paid so far, in USDC base units (6 decimals).
uint256 totalAmountPaid;
/// @notice Total number of payments the rider has made.
uint256 totalNumberOfTimesPaid;
}
HOwnerPayout
Title: HOwnerPayout
A single payout made to the contract/owner.
struct HOwnerPayout {
/// @notice Identifier of the investment the payout came from.
bytes32 investmentId;
/// @notice Amount paid out, in USDC base units (6 decimals).
uint256 amountPaid;
/// @notice Timestamp at which the payout was made.
uint256 timePaid;
/// @notice Address the payout was transferred into.
address addressPaidInto;
/// @notice What produced the payout ({HPayoutType.RiderPaying} or
/// {HPayoutType.RiderSavingsSlash}).
HPayoutType payoutType;
}
HOwnerPayoutsHistory
Title: HOwnerPayoutsHistory
Aggregate record of payouts made to the contract/owner.
struct HOwnerPayoutsHistory {
/// @notice Total amount paid out so far, in USDC base units (6 decimals).
uint256 totalAmountPaid;
/// @notice Total number of payouts made.
uint256 totalNumberOfTimesPaid;
}
HInvestorPayout
Title: HInvestorPayout
A single payout made to an investor.
struct HInvestorPayout {
/// @notice Identifier of the investment the payout came from.
bytes32 investmentId;
/// @notice Amount paid out, in USDC base units (6 decimals).
uint256 amountPaid;
/// @notice Timestamp at which the payout was made.
uint256 timePaid;
/// @notice Address the payout was transferred into.
address addressPaidInto;
/// @notice What produced the payout ({HPayoutType.RiderPaying} or
/// {HPayoutType.RiderSavingsSlash}).
HPayoutType payoutType;
}
HInvestorPayoutsHistory
Title: HInvestorPayoutsHistory
Aggregate record of a single investor’s payouts for one investment.
struct HInvestorPayoutsHistory {
/// @notice Address of the investor.
address investorAddress;
/// @notice Identifier of the investment.
bytes32 investmentId;
/// @notice Total amount paid to the investor so far, in USDC base units (6 decimals).
uint256 totalAmountPaid;
/// @notice Total number of payouts made to the investor.
uint256 totalNumberOfTimesPaid;
/// @notice Total amount the investor is due to receive over time, in USDC base units (6 decimals).
uint256 targetTotalPay;
}
HInvestmentPayoutsHistory
Title: HInvestmentPayoutsHistory
Aggregate record of all payouts made on one investment.
struct HInvestmentPayoutsHistory {
/// @notice Identifier of the investment.
bytes32 investmentId;
/// @notice Total amount paid out so far on the investment, in USDC base units (6 decimals).
uint256 totalAmountPaid;
/// @notice Total number of payouts made on the investment.
uint256 totalNumberOfTimesPaid;
/// @notice Total amount due to be paid out on the investment, in USDC base units (6 decimals).
uint256 targetTotalPay;
}
HRiderSavingsHistory
Title: HRiderSavingsHistory
Record of a rider’s savings for one investment.
A portion of every periodic payment is set aside as savings. The savings can be slashed if the rider defaults or pays late, and are refunded in full if the rider stays committed through the end of the hire purchase, giving them capital for repairs and cash once they own the vehicle.
struct HRiderSavingsHistory {
/// @notice Address of the rider.
address riderAddress;
/// @notice Total amount saved so far, in USDC base units (6 decimals).
uint256 totalAmountSaved;
/// @notice Individual savings entries.
HRiderSavings[] savings;
}
HRiderSavings
Title: HRiderSavings
A single savings entry made by a rider.
struct HRiderSavings {
/// @notice Address of the rider.
address riderAddress;
/// @notice Amount saved in this entry, in USDC base units (6 decimals).
uint256 amountSaved;
/// @notice Timestamp at which the amount was saved.
uint256 timeSaved;
}
HRiderSavingsSlash
Title: HRiderSavingsSlash
A single slash applied to a rider’s savings for one investment.
The slash is split to the owner and investor pools by {HPayoutType.RiderSavingsSlash} payouts, and reduces the savings that would otherwise be refunded at completion.
struct HRiderSavingsSlash {
/// @notice Identifier of the investment the rider was saving on.
bytes32 investmentId;
/// @notice Address of the rider whose savings were slashed.
address riderAddress;
/// @notice Amount slashed in this entry, in USDC base units (6 decimals).
uint256 amountSlashed;
/// @notice Timestamp at which the slash was applied.
uint256 timeSlashed;
}
HRiderSavingsSlashesHistory
Title: HRiderSavingsSlashesHistory
Aggregate record of the savings slashed from a rider on one investment.
struct HRiderSavingsSlashesHistory {
/// @notice Address of the rider.
address riderAddress;
/// @notice Total amount slashed so far, in USDC base units (6 decimals).
uint256 totalAmountSlashed;
/// @notice Total number of slashes applied.
uint256 totalNumberOfTimesSlashed;
}
HStats
Title: HStats
Aggregate platform statistics for the frontend, returned by {Henriable.getStats}.
Every field is maintained in O(1) as the contract is used, so the getter never loops. Investor figures count filled slots, not distinct addresses (an address may hold a senior and a junior slot, and slots in several investments). The totals derived from list lengths are filled in by the getter at read time.
struct HStats {
//<editor-fold desc="Fields: Assets">
/// @notice Total number of registered assets.
uint256 totalAssets;
/// @notice Number of assets currently active.
uint256 activeAssets;
/// @notice Number of assets with at least one active investment.
uint256 assetsWithRunningInvestments;
/// @notice Number of assets with at least one completed investment.
uint256 assetsWithCompletedInvestments;
//</editor-fold desc="Fields: Assets">
//<editor-fold desc="Fields: Investments">
/// @notice Total number of investment opportunities ever created.
uint256 totalInvestments;
/// @notice Number of investment opportunities currently active.
uint256 activeInvestments;
/// @notice Number of investments currently in {HInvestmentStatus.Hired}.
uint256 investmentsInHire;
/// @notice Number of investments in {HInvestmentStatus.Complete}.
uint256 investmentsPaidInFull;
//</editor-fold desc="Fields: Investments">
//<editor-fold desc="Fields: People">
/// @notice Total number of registered investors.
uint256 totalInvestors;
/// @notice Total senior investor slots filled across all investments.
uint256 totalSeniorPositions;
/// @notice Total junior investor slots filled across all investments.
uint256 totalJuniorPositions;
/// @notice Total number of registered riders.
uint256 totalRiders;
/// @notice Total number of rider hire-purchase requests.
uint256 totalHireRequests;
//</editor-fold desc="Fields: People">
//<editor-fold desc="Fields: Amounts">
/// @notice Gross amount senior investors have invested so far, in USDC base units (6 decimals).
uint256 totalSeniorInvestedUsd;
/// @notice Gross amount junior investors have invested so far, in USDC base units (6 decimals).
uint256 totalJuniorInvestedUsd;
/// @notice Gross amount riders have paid in, including refundable savings charges,
/// in USDC base units (6 decimals).
uint256 totalPayinsUsd;
/// @notice Cumulative amount paid out to senior investors, in USDC base units (6 decimals).
uint256 totalSeniorPayoutsUsd;
/// @notice Cumulative amount paid out to junior investors, in USDC base units (6 decimals).
uint256 totalJuniorPayoutsUsd;
/// @notice Cumulative amount paid out to the owner, in USDC base units (6 decimals).
uint256 totalOwnerPayoutsUsd;
/// @notice Amount currently held as refundable rider savings, in USDC base units (6 decimals).
uint256 riderSavingsHeldUsd;
/// @notice Cumulative amount of rider savings slashed so far, in USDC base units (6 decimals).
uint256 totalRiderSavingsSlashedUsd;
//</editor-fold desc="Fields: Amounts">
}
HInvestmentType
Title: HInvestmentType
Identifies which investor tier a position belongs to.
enum HInvestmentType {
/// @notice Senior investor: paid first, with lower risk and lower reward.
Senior,
/// @notice Junior investor: paid after senior investors, with higher risk and higher reward.
Junior
}
HInvestmentStatus
Title: HInvestmentStatus
Lifecycle states of an investment opportunity.
enum HInvestmentStatus {
/// @notice Investment added but investing has not begun.
Pending,
/// @notice Investors can currently invest.
AcceptingInvestments,
/// @notice All required investors are in place.
InvestmentDone,
/// @notice Riders can now request to hire the asset.
AcceptingRiders,
/// @notice A rider has been hired and is making periodic payments.
Hired,
/// @notice Rider finished paying and the NFT title has been transferred.
Complete
}
HPayoutType
Title: HPayoutType
Identifies what produced a payout entry, so payouts can be told apart by source.
enum HPayoutType {
/// @notice The payout was funded by a rider's periodic payment.
RiderPaying,
/// @notice The payout was funded by a slash of the rider's savings.
RiderSavingsSlash
}
HOwner2IsOwner1
Thrown when owner2 is set to the same address as owner1.
error HOwner2IsOwner1(address owner1);
Parameters
| Name | Type | Description |
|---|---|---|
owner1 | address | The current owner1 address. |
HAssetInvalidId
Thrown when an asset is registered without a non-zero id.
error HAssetInvalidId();
HAssetAlreadyExists
Thrown when registering an asset whose id is already in use.
error HAssetAlreadyExists(bytes32 id);
Parameters
| Name | Type | Description |
|---|---|---|
id | bytes32 | The already-existing asset id. |
HAssetDoesNotExist
Thrown when an operation references an asset id that is not registered.
error HAssetDoesNotExist(bytes32 id);
Parameters
| Name | Type | Description |
|---|---|---|
id | bytes32 | The unknown asset id. |
HAssetHasNonPendingInvestments
Thrown when an asset’s status is changed while one of its investments is no longer pending.
error HAssetHasNonPendingInvestments(bytes32 id);
Parameters
| Name | Type | Description |
|---|---|---|
id | bytes32 | The asset id. |
HAssetInvalidName
Thrown when an asset is registered without a name.
error HAssetInvalidName();
HAssetInvalidCostPrice
Thrown when an asset is registered with a zero cost price.
error HAssetInvalidCostPrice();
HAssetInvalidSellPrice
Thrown when an asset is registered with a zero sell price.
error HAssetInvalidSellPrice();
HAssetNotActive
Thrown when an operation references an asset that is not active.
error HAssetNotActive(bytes32 id);
Parameters
| Name | Type | Description |
|---|---|---|
id | bytes32 | The inactive asset id. |
HAssetInvalidSettings
Thrown when an asset’s pricing settings cannot cover the payouts it promises, i.e. the rider’s sell price does not cover the investor principal and profits.
error HAssetInvalidSettings();
HInvestmentInvalidId
Thrown when an investment is registered without a non-zero id.
error HInvestmentInvalidId();
HInvestmentAlreadyExists
Thrown when registering an investment whose id is already in use.
error HInvestmentAlreadyExists(bytes32 id);
Parameters
| Name | Type | Description |
|---|---|---|
id | bytes32 | The already-existing investment id. |
HInvestmentDoesNotExist
Thrown when an operation references an investment id that is not registered.
error HInvestmentDoesNotExist(bytes32 id);
Parameters
| Name | Type | Description |
|---|---|---|
id | bytes32 | The unknown investment id. |
HInvestmentInvalidRiderInitialBuyin
Thrown when an investment is registered with a zero rider initial buy-in.
error HInvestmentInvalidRiderInitialBuyin();
HInvestmentRiderInitialBuyinTooHigh
Thrown when an investment’s initial rider buy-in is not below the asset’s sell price.
The buy-in is credited toward the rider’s hire-purchase total, so it must be less than the sell price or the rider would have nothing left to pay over the term.
error HInvestmentRiderInitialBuyinTooHigh(uint256 buyin, uint256 sellPrice);
Parameters
| Name | Type | Description |
|---|---|---|
buyin | uint256 | The supplied initial buy-in, in USDC base units (6 decimals). |
sellPrice | uint256 | The asset’s sell price, in USDC base units (6 decimals). |
HInvestmentInvalidPeriodicRiderPayingInMinutes
Thrown when an investment is registered with a zero periodic rider paying period.
error HInvestmentInvalidPeriodicRiderPayingInMinutes();
HInvestmentInvalidMinimumRiderPeriodicPayings
Thrown when an investment is registered with a zero minimum rider periodic payment.
error HInvestmentInvalidMinimumRiderPeriodicPayings();
HInvestmentHasInvestors
Thrown when an investment’s active flag is changed after an investor has joined.
error HInvestmentHasInvestors(bytes32 id);
Parameters
| Name | Type | Description |
|---|---|---|
id | bytes32 | The investment id. |
HInvestmentInvalidSettings
Thrown when an investment’s level-1 settings are not accurate enough to cover the profits promised to senior and junior investors.
error HInvestmentInvalidSettings();
HInvestmentNotPending
Thrown when next-round times are changed on an investment whose current status does not allow it (no longer Pending, or, when extending a round, no longer AcceptingInvestments).
error HInvestmentNotPending(bytes32 id);
Parameters
| Name | Type | Description |
|---|---|---|
id | bytes32 | The investment id. |
HInvestmentNotDone
Thrown when an operation requires an investment that has finished raising funds ({HInvestmentStatus.InvestmentDone}) but it has not.
error HInvestmentNotDone(bytes32 id);
Parameters
| Name | Type | Description |
|---|---|---|
id | bytes32 | The investment id. |
HInvestmentInvalidStartTime
Thrown when an investment round’s start time is not in the future.
error HInvestmentInvalidStartTime(uint256 startTime);
Parameters
| Name | Type | Description |
|---|---|---|
startTime | uint256 | The invalid start timestamp. |
HInvestmentInvalidEndTime
Thrown when an investment round’s end time is not after its start time.
error HInvestmentInvalidEndTime(uint256 startTime, uint256 endTime);
Parameters
| Name | Type | Description |
|---|---|---|
startTime | uint256 | The proposed start timestamp. |
endTime | uint256 | The invalid end timestamp. |
HInvestmentNotActive
Thrown when investing in an investment that is not active.
error HInvestmentNotActive(bytes32 id);
Parameters
| Name | Type | Description |
|---|---|---|
id | bytes32 | The investment id. |
HInvestmentNotAccepting
Thrown when investing in an investment that is not accepting investments.
error HInvestmentNotAccepting(bytes32 id);
Parameters
| Name | Type | Description |
|---|---|---|
id | bytes32 | The investment id. |
HInvestmentInvalidAmount
Thrown when the approved USDC amount does not match the required slot amount.
error HInvestmentInvalidAmount(uint256 provided, uint256 required);
Parameters
| Name | Type | Description |
|---|---|---|
provided | uint256 | The approved amount supplied. |
required | uint256 | The required per-slot amount. |
HInvestmentNoOpenSlot
Thrown when investing in a tier whose investor slots are all filled.
error HInvestmentNoOpenSlot(bytes32 id);
Parameters
| Name | Type | Description |
|---|---|---|
id | bytes32 | The investment id. |
HInvestorDoesNotExist
Thrown when an operation references an investor that is not registered.
error HInvestorDoesNotExist(address investor);
Parameters
| Name | Type | Description |
|---|---|---|
investor | address | The unknown investor address. |
HInvestorInvalidAge
Thrown when an investor is younger than the required minimum age.
error HInvestorInvalidAge(uint8 age);
Parameters
| Name | Type | Description |
|---|---|---|
age | uint8 | The supplied age. |
HInvestmentNotAcceptingRiders
Thrown when a rider registers for an investment that is not accepting riders.
error HInvestmentNotAcceptingRiders(bytes32 id);
Parameters
| Name | Type | Description |
|---|---|---|
id | bytes32 | The investment id. |
HRiderInvalidName
Thrown when a rider is registered without a name.
error HRiderInvalidName();
HRiderInvalidCountry
Thrown when a rider is registered without a country.
error HRiderInvalidCountry();
HRiderInvalidAge
Thrown when a rider is younger than the required minimum age.
error HRiderInvalidAge(uint8 age);
Parameters
| Name | Type | Description |
|---|---|---|
age | uint8 | The supplied age. |
HRiderInsufficientInitialBuyin
Thrown when a rider’s approved initial buy-in is below the required amount.
error HRiderInsufficientInitialBuyin(uint256 provided, uint256 required);
Parameters
| Name | Type | Description |
|---|---|---|
provided | uint256 | The approved amount supplied. |
required | uint256 | The required initial buy-in. |
HRiderAlreadyRegistered
Thrown when a rider tries to register twice for the same investment.
error HRiderAlreadyRegistered(bytes32 investmentId, address rider);
Parameters
| Name | Type | Description |
|---|---|---|
investmentId | bytes32 | The investment id. |
rider | address | The rider address. |
HInvestmentAlreadyHasHiredRider
Thrown when a rider is accepted for an investment that already has a hired rider.
error HInvestmentAlreadyHasHiredRider(bytes32 investmentId);
Parameters
| Name | Type | Description |
|---|---|---|
investmentId | bytes32 | The investment id. |
HRiderDidNotApplyForHire
Thrown when accepting a rider who never applied to hire the investment.
error HRiderDidNotApplyForHire(bytes32 investmentId, address rider);
Parameters
| Name | Type | Description |
|---|---|---|
investmentId | bytes32 | The investment id. |
rider | address | The applicant address. |
HRiderAlreadyRejectedForHire
Thrown when accepting a rider who was already rejected for the investment.
error HRiderAlreadyRejectedForHire(bytes32 investmentId, address rider);
Parameters
| Name | Type | Description |
|---|---|---|
investmentId | bytes32 | The investment id. |
rider | address | The applicant address. |
HRiderDoesNotExist
Thrown when an operation references a rider that is not registered.
error HRiderDoesNotExist(address rider);
Parameters
| Name | Type | Description |
|---|---|---|
rider | address | The unknown rider address. |
HInvestmentNotHired
Thrown when a rider pays on an investment whose hire purchase is not running.
error HInvestmentNotHired(bytes32 id);
Parameters
| Name | Type | Description |
|---|---|---|
id | bytes32 | The investment id. |
HRiderNotHired
Thrown when an address that is not the hired rider tries to pay.
error HRiderNotHired(bytes32 investmentId, address rider);
Parameters
| Name | Type | Description |
|---|---|---|
investmentId | bytes32 | The investment id. |
rider | address | The caller address. |
HRiderPaymentsCompleted
Thrown when a rider pays after already completing the required total.
error HRiderPaymentsCompleted(bytes32 id);
Parameters
| Name | Type | Description |
|---|---|---|
id | bytes32 | The investment id. |
HRiderPaymentsNotCompleted
Thrown when ownership is transferred before the rider has completed all payments.
error HRiderPaymentsNotCompleted(bytes32 id);
Parameters
| Name | Type | Description |
|---|---|---|
id | bytes32 | The investment id. |
HInvestmentAlreadyComplete
Thrown when ownership is transferred for an investment that is already complete.
error HInvestmentAlreadyComplete(bytes32 id);
Parameters
| Name | Type | Description |
|---|---|---|
id | bytes32 | The investment id. |
HRiderPayinBelowMinimum
Thrown when a rider’s approved payment is below the minimum periodic payment.
error HRiderPayinBelowMinimum(uint256 provided, uint256 required);
Parameters
| Name | Type | Description |
|---|---|---|
provided | uint256 | The approved amount supplied. |
required | uint256 | The required minimum periodic payment. |
HRiderPayinLate
Thrown when a rider pays after the due date ({HInvestment.riderNextPayinDate}).
error HRiderPayinLate(bytes32 id);
Parameters
| Name | Type | Description |
|---|---|---|
id | bytes32 | The investment id. |
HInvestmentInvalidRiderNextPayinDate
Thrown when the hired rider’s next payment date is not extended to a later time.
error HInvestmentInvalidRiderNextPayinDate(uint256 newTime, uint256 currentTime);
Parameters
| Name | Type | Description |
|---|---|---|
newTime | uint256 | The proposed new next-payment timestamp. |
currentTime | uint256 | The investment’s current next-payment timestamp. |
HRiderSavingsSlashExceedsSaved
Thrown when a savings slash exceeds the rider’s currently saved amount.
error HRiderSavingsSlashExceedsSaved(uint256 amountSlashed, uint256 totalSaved);
Parameters
| Name | Type | Description |
|---|---|---|
amountSlashed | uint256 | The requested slash, in USDC base units (6 decimals). |
totalSaved | uint256 | The rider’s current saved amount, in USDC base units (6 decimals). |
HVehicleNftUnauthorizedMinter
Thrown when an address that is not the configured vehicle-title NFT minter attempts to mint a title.
error HVehicleNftUnauthorizedMinter(address caller);
Parameters
| Name | Type | Description |
|---|---|---|
caller | address | The unauthorized caller. |
Constants
USDC_UNIT
uint256 constant USDC_UNIT = 10 ** 6
Counter
State Variables
number
uint256 public number
Functions
setNumber
function setNumber(uint256 newNumber) public;
increment
function increment() public;
Henriable
Inherits: HHelper
Title: The Henriable contract.
Author: Obiaraije Henry
All USD amounts are expressed as integers in USDC base units (6 decimals), i.e.
micro-USDC, where 1 USDC == USDC_UNIT == 10 ** 6 base units (e.g. $14 ==
14_000_000 and $0.14 == 140_000). The contract never converts or scales; it moves
the raw base-unit value. Callers must therefore pass base units: the frontend uses
viem’s parseUnits(x, 6), not a whole-dollar number.
Functions
constructor
Deploys Henriable, setting the contract owner, the USDC token and the NFT.
constructor(address initialOwner, IERC20 ownerUsdToken_, HenriableVehicleNFT vehicleNft_)
HHelper(initialOwner, ownerUsdToken_, vehicleNft_);
Parameters
| Name | Type | Description |
|---|---|---|
initialOwner | address | The address that will own the contract. |
ownerUsdToken_ | IERC20 | The USDC token used for investments, payouts and payments. |
vehicleNft_ | HenriableVehicleNFT | The vehicle-title NFT collection, whose minter must be set to this contract so it can mint and later transfer asset titles. |
actionAdminSetOwner2
Sets the secondary owner, who may run every admin action but not manage owners.
Only owner1 ({onlyOwner}) may call this, so owner2 cannot set or clear owners.
Pass address(0) to clear owner2; rejected when _owner2 is owner1 itself.
States updated: {owner2}.
function actionAdminSetOwner2(address _owner2) external onlyOwner;
Parameters
| Name | Type | Description |
|---|---|---|
_owner2 | address | The new secondary owner address, or address(0) to clear it. |
actionAdminAddAsset
Adds a new asset that can be invested in.
Only an owner (admin: owner1 or owner2) may call this. Validates the asset, forces it active, appends it to {assetsList} and records its position in the {assets} index mapping. States updated: {assetsList}, {assets}.
function actionAdminAddAsset(HAsset calldata _asset) external onlyOwners;
Parameters
| Name | Type | Description |
|---|---|---|
_asset | HAsset | The asset configuration to register. Its id must be unique and non-zero, name non-empty, and costPrice/sellPrice non-zero. The active field is ignored and set to true. |
actionAdminChangeAssetStatus
Enables or disables an asset.
Only an owner (admin: owner1 or owner2) may call this. The asset status may only change while every investment that depends on the asset is still {HInvestmentStatus.Pending}; once any such investment has moved past Pending, the asset is locked. Disabling an asset also disables its still-pending investments. Enabling an asset does NOT re-enable those investments. States updated: {assetsList}, and {investmentsList} when disabling.
function actionAdminChangeAssetStatus(bytes32 _assetId, bool _status) external onlyOwners;
Parameters
| Name | Type | Description |
|---|---|---|
_assetId | bytes32 | The id of the asset to update. |
_status | bool | The new active status. |
actionAdminAddInvestment
Adds a new investment opportunity against an existing active asset.
Only an owner (admin: owner1 or owner2) may call this. {HInvestment} contains mappings and therefore cannot be passed as a calldata parameter, so the admin-supplied settings are taken as individual arguments. Validates them, checks the level-1 settings against the asset, forces the opportunity active and Pending, appends it to {investmentsList}, records its position in the {investments} index mapping and links it to its asset via {assetInvestments}. States updated: {investmentsList}, {investments}, {assetInvestments}.
function actionAdminAddInvestment(
bytes32 _investmentId,
bytes32 _assetId,
uint256 _riderInitialBuyinUsd,
uint256 _periodicRiderPayingInMinutes,
uint256 _minimumRiderPeriodicPayingsUsd
) external onlyOwners;
Parameters
| Name | Type | Description |
|---|---|---|
_investmentId | bytes32 | Unique, non-zero id of the new investment slot. |
_assetId | bytes32 | Id of the asset to invest in; must exist and be active. |
_riderInitialBuyinUsd | uint256 | Initial rider buy-in, in USDC base units (6 decimals); must be non-zero. Callers pass base units (frontend: parseUnits(x, 6)). |
_periodicRiderPayingInMinutes | uint256 | Length of a rider period, in minutes; must be non-zero. |
_minimumRiderPeriodicPayingsUsd | uint256 | Minimum rider payment per period, in USDC base units (6 decimals); must be non-zero. Callers pass base units. |
actionAdminChangeInvestmentStatus
Enables or disables an investment opportunity.
Only an owner (admin: owner1 or owner2) may call this. The investment’s active flag may only change while no investor has joined it; once the senior or junior pool has any investor, the opportunity is locked. States updated: {investmentsList}.
function actionAdminChangeInvestmentStatus(bytes32 _investmentId, bool _status) external onlyOwners;
Parameters
| Name | Type | Description |
|---|---|---|
_investmentId | bytes32 | The id of the investment to update. |
_status | bool | The new active status. |
actionAdminSetNextInvestmentTimes
Sets the start and end of the next investment round for an investment.
Only an owner (admin: owner1 or owner2) may call this.
The opportunity must still be Pending or in investment(to extend it) and its asset active, and the
round must be in the future with _endTime after _startTime.
States updated: {investmentsList}.
function actionAdminSetNextInvestmentTimes(bytes32 _investmentId, uint256 _startTime, uint256 _endTime)
external
onlyOwners;
Parameters
| Name | Type | Description |
|---|---|---|
_investmentId | bytes32 | The id of the investment to schedule. |
_startTime | uint256 | Timestamp at which the next investment round starts; must be in the future. |
_endTime | uint256 | Timestamp at which the next investment round ends; must be after _startTime. |
actionAdminClearNextInvestmentsTimes
Clears the start and end of the next investment round for an investment.
Only an owner (admin: owner1 or owner2) may call this. The opportunity must still be Pending; both times are reset to 0. States updated: {investmentsList}.
function actionAdminClearNextInvestmentsTimes(bytes32 _investmentId) external onlyOwners;
Parameters
| Name | Type | Description |
|---|---|---|
_investmentId | bytes32 | The id of the investment whose round is cleared. |
actionInvest
Lets an address invest into a tier of an active investment opportunity.
The investor is {msg.sender}; _investor only supplies name, country
and age. The asset defines the per-investor buying price and the number
of slots, so the required amount is the tier’s one-investor buying price.
The contract pulls exactly that amount from the investor’s USDC.
An address may call this repeatedly and in either tier, taking one seat
per call, so the same address can appear more than once in a tier’s list
(each entry is a separate seat and is paid its own equal share).
States updated: {investorsList}, {investors}, and the chosen tier’s
list and mapping inside {investmentsList}.
function actionInvest(
HInvestor calldata _investor,
HInvestmentType _investmentType,
bytes32 _investmentId,
uint256 _approvedUSDAmount
) external;
Parameters
| Name | Type | Description |
|---|---|---|
_investor | HInvestor | The investor profile (name, country, age) to create or update. |
_investmentType | HInvestmentType | The tier to invest in (Senior or Junior). |
_investmentId | bytes32 | The id of the investment to invest in. |
_approvedUSDAmount | uint256 | The USDC amount approved for this slot, in USDC base units (6 decimals); must equal the slot amount. Callers pass base units (frontend: parseUnits(x, 6)). |
actionSetNextHireRoundTime
Sets the window during which riders may request to hire an investment’s asset.
Only an owner (admin: owner1 or owner2) may call this.
The opportunity must be funded ({HInvestmentStatus.InvestmentDone}) or, once a
hire round is open, still accepting riders ({HInvestmentStatus.AcceptingRiders})
so an in-progress round can be extended. The window must be in the future with
_endTime after _startTime.
States updated: {investmentsList}.
function actionSetNextHireRoundTime(bytes32 _investmentId, uint256 _startTime, uint256 _endTime)
external
onlyOwners;
Parameters
| Name | Type | Description |
|---|---|---|
_investmentId | bytes32 | The id of the investment to schedule. |
_startTime | uint256 | Timestamp at which the next hire-request round starts; must be in the future. |
_endTime | uint256 | Timestamp at which the next hire-request round ends; must be after _startTime. |
actionClearNextHireTime
Clears the rider hire-request window for a funded investment.
Only an owner (admin: owner1 or owner2) may call this. The opportunity must be funded ({HInvestmentStatus.InvestmentDone}); both hire-request times are reset to 0. States updated: {investmentsList}.
function actionClearNextHireTime(bytes32 _investmentId) external onlyOwners;
Parameters
| Name | Type | Description |
|---|---|---|
_investmentId | bytes32 | The id of the investment whose hire window is cleared. |
actionRiderRegisterAsARider
Registers the caller as a rider for a funded investment’s hire round.
The rider is {msg.sender}; the initial buy-in is pulled into the contract so it can be refunded if the rider is later rejected. Registration is only allowed while the investment is {HInvestmentStatus.AcceptingRiders}. States updated: {ridersList}, {riders}, {ridersHirePurchasesRequestsList}, {ridersHireRequestPurchasesByInvestment}, and the investment’s {HInvestment.ridersHirePurchaseRequestsList}/{ridersHirePurchaseRequests}.
function actionRiderRegisterAsARider(
bytes32 _name,
bytes32 _country,
uint8 _age,
uint256 _approvedInitialBuyin,
bytes32 _investmentId
) external;
Parameters
| Name | Type | Description |
|---|---|---|
_name | bytes32 | The rider’s name; must be non-zero. |
_country | bytes32 | The rider’s country; must be non-zero. |
_age | uint8 | The rider’s age; must be at least 18. |
_approvedInitialBuyin | uint256 | The USDC the rider approved, in USDC base units (6 decimals); must cover the required buy-in. Callers pass base units. |
_investmentId | bytes32 | The id of the investment to register for. |
actionAdminAcceptRider
Accepts one applicant as the rider for a funded investment and rejects the rest.
Only an owner (admin: owner1 or owner2) may call this. The investment must still be {HInvestmentStatus.AcceptingRiders} and have no hired rider yet; the chosen rider must exist, must have applied for the investment (recorded by actionRiderRegisterAsARider) and must not have been rejected before. Every other applicant is marked rejected via {rejectedRiders} and has their initial buy-in refunded. The accepted rider’s buy-in is credited toward their hire-purchase total and shared with the investor pools and the owner immediately. The investment then moves to {HInvestmentStatus.Hired} and the rider’s next payment date is set one period from now. States updated: {HInvestment.riderWhoHiredIt}, {HInvestment.riderNextPayinDate}, {HInvestment.status}, {rejectedRiders}, {HInvestment.riderPayinsHistory}, {ownerPayoutsList}, {investorPayoutList} and the payout histories.
function actionAdminAcceptRider(bytes32 _investmentId, address _riderAddress) external onlyOwners;
Parameters
| Name | Type | Description |
|---|---|---|
_investmentId | bytes32 | The id of the investment whose rider is being chosen. |
_riderAddress | address | The applicant to accept as the hired rider. |
actionAdminExtendRiderPayingForInvestment
Pushes the hired rider’s next payment due date to a later time and optionally slashes an amount from the rider’s accumulated savings.
Only an owner (admin: owner1 or owner2) may call this.
The opportunity must be {HInvestmentStatus.Hired}, i.e. a rider is
currently paying, and the new date must be later than the current
next-payment date. Extending the date gives the rider more time before
actionRiderPayin treats their next payment as late.
When _slashAmount is non-zero it must not exceed the rider’s saved amount;
the savings are reduced by it and the amount is split to the owner and
investor pools exactly like a rider payment, recorded as
{HPayoutType.RiderSavingsSlash} payouts and tracked via {HRiderSavingsSlash}.
States updated: {HInvestment.riderNextPayinDate}, {HInvestment.riderSavings},
{riderSavingsSlashesList}, and the investment’s slash and payout histories.
function actionAdminExtendRiderPayingForInvestment(
bytes32 _investmentId,
uint256 _newNextPayinDate,
uint256 _slashAmount
) external onlyOwners;
Parameters
| Name | Type | Description |
|---|---|---|
_investmentId | bytes32 | The id of the investment whose rider payment is extended. |
_newNextPayinDate | uint256 | The new timestamp at which the rider’s next payment is due; must be later than the investment’s current next-payment date. |
_slashAmount | uint256 | Amount to slash from the rider’s savings, in USDC base units (6 decimals); 0 extends without slashing. Callers pass base units. |
actionRiderPayin
Lets the hired rider make a periodic payment under a running hire purchase.
The rider must be the one hired on an investment in {HInvestmentStatus.Hired}, must not have completed the target total, and must make a non-late payment of at least {HInvestment.minimumRiderPeriodicPayingsUsd} plus the asset’s {HAsset.riderSlashableRepayableExtraCharge}. The extra charge is set aside as the rider’s savings, and the rest is split by {calcSharingFormula} and credited to the owner and the senior/junior investor pools. States updated: {riderPayinsList}, {riderPayins}, {HInvestment.riderPayinsHistory}, {HInvestment.riderNextPayinDate}, {ownerPayoutsList}, {investorPayoutList}, {HInvestment.riderSavings}, {HInvestment.investmentPayoutHistory} and the per-investor payout histories.
function actionRiderPayin(bytes32 _investmentId, uint256 _approvedUSD) external;
Parameters
| Name | Type | Description |
|---|---|---|
_investmentId | bytes32 | The id of the investment being paid. |
_approvedUSD | uint256 | The USDC the rider is paying, in USDC base units (6 decimals); must be at least the minimum plus the savings charge. Callers pass base units (frontend: parseUnits(x, 6)). |
actionTransferOwnershipToRider
Completes a hire purchase by transferring ownership of the asset to the rider.
Only valid once the rider has finished paying. The rider’s accumulated savings are refunded to them and cleared, the investment is marked {HInvestmentStatus.Complete}, the completion timestamps are recorded and the investment is appended to the completed lists. It cannot run twice, so the completion side effects happen exactly once. States updated: {HInvestment.riderSavings}, {investmentsList}, {completedRiderInvestmentList} and {investmentsCompleted}.
function actionTransferOwnershipToRider(address _rider, bytes32 _investmentId) public;
Parameters
| Name | Type | Description |
|---|---|---|
_rider | address | The rider receiving ownership; must be the investment’s hired rider. |
_investmentId | bytes32 | The id of the investment being completed. |
getStats
Returns every aggregate statistic the frontend displays in one call.
Counters are maintained in O(1) as the contract is used; the totals that mirror list lengths are filled in here so there is a single source of truth. Investor figures count filled slots, not distinct addresses.
function getStats() external view returns (HStats memory);
Returns
| Name | Type | Description |
|---|---|---|
<none> | HStats | platformStats The platform-wide statistics. |
IVehicleTitleInfo
The slice of the platform the title NFT reads for its metadata.
Functions
getTitleInfo
function getTitleInfo(uint256 tokenId) external view returns (bytes32 assetName, address rider);
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The title’s token id. |
Returns
| Name | Type | Description |
|---|---|---|
assetName | bytes32 | The bytes32 asset name. |
rider | address | The rider who hired the asset, or address(0). |
HenriableVehicleNFT
Inherits: ERC721, Ownable
Title: Henriable vehicle-title NFT.
Author: Obiaraije Henry
An ERC721 that represents the title deed of one physical asset. The platform mints it to itself once an investment is fully funded and transfers it to the rider when the hire purchase is paid in full. The token is a standard, transferable ERC721 after the rider receives it.
Kept as its own contract (not inherited by {Henriable}) so the platform’s business logic stays under the EIP-170 code-size limit. Minting is gated by a single {minter} address, which the owning deployer sets to the {Henriable} address during deployment; the deployer keeps admin control of the collection.
State Variables
minter
The only address allowed to mint titles (the {Henriable} platform).
address(0) means no address can mint until the owner sets it.
address internal minter
nextTokenId
Id that will be assigned to the next minted title.
Ids start at 1 so 0 keeps meaning “no title”, matching the platform.
uint256 internal nextTokenId
Functions
constructor
Deploys the collection with its name and symbol.
constructor(address initialOwner) ERC721("Henriable Vehicle Title", "HVT") Ownable(initialOwner);
Parameters
| Name | Type | Description |
|---|---|---|
initialOwner | address | The address that owns the collection and may set the minter. |
onlyMinter
Restricts a function to the configured {minter}.
Reverts with {HVehicleNftUnauthorizedMinter} when the caller is not the minter.
modifier onlyMinter() ;
setMinter
Sets the address allowed to mint titles, typically the platform.
Only the collection owner may call this. Pass address(0) to disable minting. States updated: {minter}.
function setMinter(address newMinter) external onlyOwner;
Parameters
| Name | Type | Description |
|---|---|---|
newMinter | address | The address allowed to mint, or address(0) to disable minting. |
mint
Mints the next title to an address.
Only the {minter} may call this. Ids are assigned sequentially from 1. States updated: {nextTokenId}.
function mint(address to) external onlyMinter returns (uint256 tokenId);
Parameters
| Name | Type | Description |
|---|---|---|
to | address | The address that will own the newly minted title. |
Returns
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The id of the newly minted title. |
tokenURI
Returns the token’s metadata as an on-chain base64 data URI.
ERC721 metadata JSON with an inline base64 SVG image, so titles render in Etherscan, wallets and marketplaces with no off-chain hosting. The owner on the card is read live, so it updates when the platform transfers the deed. Reverts for a non-existent token (via {_requireOwned}).
function tokenURI(uint256 tokenId) public view override returns (string memory);
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The title’s token id. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | string | A data:application/json;base64,... URI. |
_renderSvg
Renders the title card as an SVG.
function _renderSvg(uint256 tokenId, address owner, string memory asset, address rider)
internal
pure
returns (string memory);
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The title’s token id. |
owner | address | The current owner, shown on the card. |
asset | string | The asset name (empty when unknown). |
rider | address | The hired rider (address(0) when unknown), shown on the card. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | string | The SVG markup. |
_titleInfo
Reads the asset name and rider from the platform (the minter).
Returns zero values when the minter is unset or is not a contract that answers, so metadata degrades gracefully instead of reverting.
function _titleInfo(uint256 tokenId) internal view returns (bytes32 assetName, address rider);
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The title’s token id. |
Returns
| Name | Type | Description |
|---|---|---|
assetName | bytes32 | The bytes32 asset name, or bytes32(0). |
rider | address | The rider, or address(0). |
_bytes32ToString
Decodes a bytes32 asset name into a trimmed ASCII string.
function _bytes32ToString(bytes32 value) internal pure returns (string memory);
Parameters
| Name | Type | Description |
|---|---|---|
value | bytes32 | The bytes32 to decode. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | string | The decoded string (up to the first zero byte). |
getMinter
Returns the address allowed to mint titles.
function getMinter() external view returns (address);
Returns
| Name | Type | Description |
|---|---|---|
<none> | address | The configured minter, or address(0) when unset. |
getNextTokenId
Returns the id that will be assigned to the next minted title.
function getNextTokenId() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The next token id. |