Skip to main content

Overview

SettlementSale is Sonar’s standard smart contract for token sales. It supports both fixed-price sales and English auctions, with settlement computed offchain and recorded onchain.
For standard sale configurations, Sonar deploys and manages this contract for you. You only need to deploy your own contract if you have custom requirements.
Source code: SettlementSale.sol

Sale Stages

The contract progresses through the following stages:

PreOpen

Initial state before the sale opens. No commitments are accepted.
  • Used for setup and configuration
  • Sale manager can prepare parameters before opening
Transitions to: Commitment

Commitment

The active commitment phase where participants submit bids.
  • Participants with valid purchase permits can submit bids
  • Bids specify price, amount, and lockup preference
  • Bids can only increase (amounts and prices cannot be lowered)
  • Each new bid replaces the previous bid for the same entity
  • Automatically closes at a specified timestamp
Transitions to: Closed

Closed

The commitment phase has ended but settlement hasn’t begun.
  • No new bids accepted
  • Sale manager can reopen the commitment phase if needed
  • Can proceed to Cancellation or directly to Settlement
Transitions to: Commitment (reopen), Cancellation, or Settlement

Cancellation

Optional cooling-off period for regulatory compliance (e.g., EU requirements).
  • Participants can cancel their bids and receive immediate refunds
  • Preliminary allocations are computed offchain and shown to participants
  • Once a bid is cancelled, it cannot be reinstated
Transitions to: Settlement

Settlement

Final allocations are computed offchain and recorded onchain.
  • Settler role records allocations via setAllocations()
  • Each entity’s accepted amount is recorded per payment token
  • Settlement is finalized when all allocations are recorded
Transitions to: Done

Done

Sale is complete. Refunds and proceeds can be processed.
  • Refunds equal commitment minus accepted allocation
  • Participants can claim refunds (if enabled) or refunder role processes them
  • Proceeds are withdrawn to the designated receiver

Roles & Permissions

The contract uses role-based access control. Multiple addresses can hold each role.
RolePurposeTypical Holder
DEFAULT_ADMIN_ROLEFull administrative access, can grant/revoke all rolesProject (always)
SALE_MANAGER_ROLEManage sale stages (open, close, reopen)Sonar or Project
PURCHASE_PERMIT_SIGNER_ROLESign purchase permits that authorize participationSonar (always)
SETTLER_ROLERecord final allocations during settlementSonar or Project
SETTLEMENT_FINALIZER_ROLEFinalize settlement and transition to DoneSonar or Project
REFUNDER_ROLEProcess refunds for participantsSonar or Project
PAUSER_ROLEEmergency pause functionalitySonar or Project
TOKEN_RECOVERER_ROLEEmergency token recovery (not granted by default)Granted manually if needed
The project always retains DEFAULT_ADMIN_ROLE and full control over the contract. Sonar holds PURCHASE_PERMIT_SIGNER_ROLE to authorize eligible participants.

Key Concepts

Bids

Each entity has a single active bid containing:
FieldDescription
priceThe maximum price the entity is willing to pay (for auctions)
amountTotal commitment amount across all payment tokens
lockupWhether the entity opts for token lockup
Bid constraints:
  • Amounts can only increase, never decrease
  • Prices can only increase, never decrease
  • Lockup can be enabled but not disabled once set
  • Forced lockup can be required via purchase permit

Entity vs Wallet

  • Entity: A compliance identity (individual or organization) verified by Sonar
  • Wallet: A blockchain address used to commit funds
One entity can use multiple wallets, but each wallet is tied to exactly one entity. Limits and allocations are tracked at the entity level, not wallet level.

Multi-Token Support

The contract accepts multiple payment tokens (e.g., USDC and USDT):
  • All tokens assumed to have the same value (e.g., USD stablecoins)
  • Commitments, allocations, and refunds tracked separately per token
  • Each transaction uses a single payment token
Not compatible with rebasing tokens (e.g., stETH) or fee-on-transfer tokens. Using incompatible tokens will result in incorrect accounting.

When to Use

Use SettlementSale when:
  • Running a fixed-price sale with pro-rata or iterative fill settlement
  • Running an English auction
  • You need offchain settlement computation
  • Standard Sonar compliance and permit validation is sufficient
Consider a custom contract when:
  • You need first-come first-served with on-chain ordering
  • You have custom allocation logic
  • You need multiple commitments per entity (increase and decrease)

See Also