How It Works

Lifecycle, permissions, and execution rules

Every alliance follows a strict finite-state model. You cannot perform actions from the wrong state even if UI still shows inputs.

State: Funding

Participants deposit ERC20 and coordinate acquisition governance until target is reached or deadline expires.

  • Allowed: `deposit`, `cancelFunding`, `voteToAcquire`, `resetAcquisitionProposal`, `buyNFT`
  • Blocked: sale voting and emergency withdrawal actions
  • Key checks: participant role, allowance, remaining target, acquisition tuple consistency, quorum, deadlines

State: Acquired

Alliance holds NFT and governance actions are open.

  • Allowed: `voteToSell`, `resetSaleProposal`, `executeSale`, `voteEmergencyWithdraw`, `emergencyWithdrawNFT`
  • Blocked: `deposit`, `cancelFunding`
  • Key checks: vote quorum, sale deadline, proposal consistency

State: Closed

Terminal state after sale execution, emergency withdrawal, or failed funding closure.

  • Allowed conditionally: `withdrawRefund` only if funding failure path was activated
  • `withdrawRefund` is available even when contract pause is active
  • No transition back to Funding

Role model

  • Participant: funding and governance actions.
  • Owner: pause/unpause administration.
  • Non-participant: read-only access.

Common action failures and meaning

  • `alliance is not in Funding state`: current state is Acquired or Closed.
  • `amount exceeds remaining target`: target already reached.
  • `quorum not reached`: proposal has not accumulated enough weighted votes yet.
  • `no acquisition proposal` or `acquisition expired`: buy/reset called outside active acquisition window.
  • `unsupported token`: token transfer amount changed unexpectedly (fee/rebase/non-standard behavior).
  • `only participant`: wallet is not in participant list.
  • `seller not owner` or transfer failures: wrong seller/NFT approval context.

Operational best practices

  1. Always read state and remaining target before signing transactions.
  2. Use one test wallet per role during QA to avoid accidental cross-role confusion.
  3. Treat Hardhat restart as full chain reset and redeploy immediately.