Sale
The example code snippets used in this guide are experimental and have not been audited. They simply help exemplify usage of the OpenZeppelin Sui Package.
The openzeppelin_sale package runs a fixed-price token sale (presale / IDO) against a fixed, pre-deposited inventory. The issuer funds the sale with a Balance<SaleCoin> up front; buyers pay a PaymentCoin during a time window and each receives a non-transferable Receipt. After the window the sale resolves one of two ways: finalize (success - buyers claim their tokens, the issuer withdraws proceeds) or cancel (failure - buyers recover their payment from an escrow vault). Use it for capped public rounds, anti-whale public rounds, and compliance-gated strategic rounds.
Pricing is not baked in. The sale is generic over a witness-gated curve that computes each buyer's allocation; a built-in fixed-rate curve (allocation = paid * rate) covers the common case, and the seam is open for custom curves. The sale never holds a TreasuryCap - it only ever routes the inventory and payments deposited into it.
This is the prefunded flavor (prefunded_sale), which draws from a fixed inventory and never mints. A future minting flavor (holding a TreasuryCap<SaleCoin>) is a separate type sharing the same Receipt and lifecycle, and is out of scope for this package.
Usage
There are two ways to pull the package into your project. Pick whichever fits how much you want to own the code.
Git dependency
Add the dependency in Move.toml, pinned to a git revision:
[dependencies]
openzeppelin_sale = { git = "https://github.com/OpenZeppelin/contracts-sui.git", subdir = "contracts/sale", rev = "v1.5.0" }The sale's vesting path depends on openzeppelin_finance; Move resolves it transitively, so you do not need to add it yourself unless you also use it directly.
Copy the source
Alternatively, copy the module sources under contracts/sale/sources/ directly into your package's sources/ (renaming the module addresses to your own package). You then fully own the code - free to trim, fork, or swap the pricing curve - at the cost of tracking upstream fixes yourself. If you keep the optional vesting path, copy the openzeppelin_finance vesting sources alongside it.
Import
Once the package is available, import the modules you need:
use openzeppelin_sale::prefunded_sale;
use openzeppelin_sale::fixed_rate_curve;Modules
The guide covers all five modules of the package. Most integrators touch only prefunded_sale and fixed_rate_curve; the other three are supporting types you will see in signatures:
| Module | What it is |
|---|---|
prefunded_sale | The sale itself: setup, purchase, close, and redeem. Also home to the Phase lifecycle enum. Start here. |
fixed_rate_curve | The built-in pricing curve, allocation = paid * rate, fixed for the whole sale. Most sales use this. |
refund_vault | A generic refundable escrow over Balance<P>. Every sale is paired with one; on cancel it pays buyers back individually. Usable standalone. |
allowlist | A typed compliance slot (AllowlistAdmin + single-use AllowEntry). Ships no KYC logic - you wire your own scheme against these types. |
receipt | The non-transferable, buyer-bound claim ticket minted by purchase and consumed by claim / refund. |
Choosing a sale shape
A fixed-price sale is configured along four orthogonal, independent axes: a required hard cap (maximum raise), an optional soft cap (minimum raise to finalize), an optional per-buyer cap, and an optional allowlist (compliance gating). The three shapes they typically combine into:
| Shape | KYC | Soft cap | Per-buyer cap | Typical use |
|---|---|---|---|---|
| Public round | no | no | no | Open public sale, first-come-first-served |
| Capped public round | no | optional | yes | Anti-whale public sale |
| Strategic round | yes | yes | yes | Compliance-gated raise |
This primitive is not a bonding curve, LBP, auction (Dutch / English / sealed-bid), or fair launch - those have different mechanics and belong in separate standards.
Next steps
- Prefunded Sale for the full module guide: lifecycle, pricing, compliance, vesting, key concepts, and security notes.
- Sale API reference for function signatures, events, and errors across all modules.
- Finance for the vesting wallet behind
claim_into_vesting. - Access for role-based authorization to hold the
SaleAdminCapandAllowlistAdminin a recoverable container.