Which layer failed
APOST /prepare-transactions call passes through three checks, in this order. Knowing which one
rejected you narrows the cause immediately.
1
Request validation
Field names, types, and formats. Returns
400 with a message naming the field, such as
tokenAmount is required. Nothing was read from the chain and nothing was created.2
API preflight
Balances, allowances, credits, and identity lookups the API performs itself. Returns
400
with a business message, such as Insufficient allowance to distribute dividends. Still no
transaction was broadcast.3
On-chain gas estimation
The API simulates the transaction against live chain state. If the contract would revert, the
simulation reverts and the raw revert data is returned to you. The transaction never left
Brickken — this is a simulated revert, not a failed broadcast.
A contract revert is always a chain-state problem — a timestamp, an allowance, a balance, a
whitelist entry, or the offering’s lifecycle stage. It is never a compliance verdict. Compliance
is checked in the preflight layer, before the chain is simulated, so a KYC problem always reaches
you as a plain
400 naming it rather than as revert data.Decoding a revert
Revert data is a hex string. The first 4 bytes are the error selector; everything after is the ABI-encoded arguments, one 32-byte word each.Selectors you are likely to see
Selectors are the first 4 bytes of the keccak-256 hash of the error’s canonical signature, so an
overload with different arguments is a different selector.
IssuanceNotStarted(address) and
IssuanceNotStarted(address,uint256) do not decode interchangeably.Solidity panics
A panic is not a custom error. It always arrives as selector0x4e487b71 followed by a code word:
0x11 is arithmetic overflow or underflow. On newInvest it almost always means the
payment token is being asked to subtract more than the wallet holds, or to pull against an
allowance that is zero. Check the balance and the allowance for this offering’s escrow before
looking anywhere else.
Some reverts arrive as execution reverted: Address: low-level delegate call failed. That is
OpenZeppelin’s message when an inner call reverts with no reason string; the real reason has been
swallowed by a proxy wrapper. Retry once, and if it persists send the exact request body to
tech@brickken.com so the call can be replayed directly.
Symptom to cause
Offerings
Payments and allowances
Tokens and investors
Wallets and environments
Offering lifecycle
claimTokens is gated on finalisation, and what it does depends on whether the offering met its
soft cap.
1
Create and open
newSto schedules the offering. It opens when startDate passes.2
Collect investments
newInvest works while the offering is open. Investors need a whitelisted wallet, an allowance
to this offering’s escrow, and the payment-token balance.3
Wait for the end date
closeOffer reverts with IssuanceNotEnded until endDate has passed. There is no admin
override and no minimum duration.4
Finalise
closeOffer finalises the issuance. If the soft cap was reached, the offering is successful.
If it was not, the issuance enters rollback.5
Claim or refund
claimTokens releases the purchased tokens on a successful issuance, and refunds the payment
token on a rolled-back one. It is the same call either way.Check the chain state yourself
Before reporting a problem, read the state the contract is reading:
If a call still fails after checking all of the above, send the exact request body, the
txId, and
the timestamp to tech@brickken.com.
Sandbox
Test tokens, storefront hosts, and fast test investors.
Browser wallets
Send a prepared transaction from MetaMask or another injected wallet.