How to manage sale stages, set allocations, process refunds, and withdraw proceeds on the SettlementSale contract
After a sale’s commitment phase closes, you’ll need to finalize allocations, process refunds, and withdraw proceeds. This page describes both the available tooling and the underlying contract functions.This can be done through the Founder Dashboard, but we also provide scripts to perform these operations manually (e.g. if you haven’t granted the Sonar backend the necessary roles).
Sonar provides TypeScript scripts to manage common post-commitment operations. For full usage instructions, CSV formats, and all available options, see the Contract Scripts README.
Script
Purpose
commitment-data-csv
Export all commitment data from the sale contract to a CSV
set-allocations
Set accepted allocation amounts for each entity’s wallets
process-refunds
Refund the difference between committed and accepted amounts
The following functions are available on the SettlementSale contract. Functions marked Sonar-managed are called by the Sonar backend automatically; you don’t need to call them unless you’re operating independently.
Role required: SALE_MANAGER_ROLE | Stage: PreOpenTransitions the contract to Commitment, enabling participants to submit bids. Called automatically by Sonar after deployment.
Role required: SALE_MANAGER_ROLE | Stage: CommitmentTransitions to Cancellation, allowing participants to cancel their bids and receive immediate refunds. This stage is optional. Skip it by calling openSettlement() directly from Commitment if no cancellation period is needed.
Role required: SALE_MANAGER_ROLE | Stage: Commitment or CancellationTransitions to Settlement. Once settlement opens, no further cancellations are possible.
Role required: SETTLEMENT_FINALIZER_ROLE | Stage: SettlementFinalizes settlement and transitions to Done. The expectedTotalAcceptedAmount must exactly match totalAcceptedAmount(). This acts as a sanity check to ensure all allocations are correct before closing settlement.
Verify totalAcceptedAmount() matches your expected total before calling this. The check is exact and the call will revert if there’s any discrepancy.
Role required: SETTLER_ROLE | Stage: Settlement | Sonar-managedRecords the accepted amounts per wallet per payment token. Each Allocation specifies:
Field
Type
Description
saleSpecificEntityID
bytes16
The sale-specific ID for the entity whose wallet is being allocated
wallet
address
The wallet address to allocate
token
address
The payment token address
acceptedAmount
uint256
The accepted amount for this wallet and token
Accepted amount cannot exceed the wallet’s committed amount for that token
Unset allocations are implicitly zero
Set allowOverwrite=true to modify a previously set allocation; otherwise the call reverts if a non-zero allocation already exists
Emits AllocationSet for each entry
The settler must explicitly set each wallet+token pair. Sonar handles this automatically, but if you hold the SETTLER_ROLE you can run settlement independently.
Role required: REFUNDER_ROLE | Stage: Done | Sonar-managedProcesses refunds for a batch of entities. For each entity, transfers the difference between committed and accepted amounts back to each wallet, per payment token.
Role required: DEFAULT_ADMIN_ROLE | Stage: DoneWithdraws all remaining accepted token balances to the proceedsReceiver. Safe to call multiple times; only transfers what hasn’t been withdrawn yet. Emits ProceedsWithdrawn per token.
Role required: DEFAULT_ADMIN_ROLE | Stage: DoneWithdraws a specific amount of a specific token to the proceedsReceiver. Useful for test withdrawals or incremental processing. Reverts if amount exceeds the available (accepted minus already withdrawn) balance for that token.
Role required: PAUSER_ROLEImmediately halts all external user-facing functions (bidding, cancellations, refund claims). State and funds are unchanged. Use in emergencies such as suspicious activity, offchain system issues, or payment token depeg.
Role required: SALE_MANAGER_ROLEEnables or disables self-service refund claiming by participants. If disabled, only addresses with REFUNDER_ROLE can process refunds.
Role required: SALE_MANAGER_ROLEEnables or disables partial commitment reduction via reduceCommitment() during the Cancellation stage. Full cancellation via cancelBid() is always available regardless of this setting.
Role required: DEFAULT_ADMIN_ROLEUpdates the address that receives sale proceeds on withdrawal. Verify this is correct before calling withdraw(). Only affects future withdrawals.
Role required: SALE_MANAGER_ROLEUpdates the maximum number of wallet addresses a single entity can use. Must be greater than zero. Entities that have already registered more wallets than the new limit are unaffected.
Role required: DEFAULT_ADMIN_ROLEGrants a role to an address. Takes effect immediately. Common uses: granting additional hot wallets PAUSER_ROLE for emergency response, or granting a hardware wallet SALE_MANAGER_ROLE for stage transitions.
Role required: DEFAULT_ADMIN_ROLEForces the contract into any stage, bypassing all normal validation. Use only if the contract is stuck in an unexpected state or there’s a critical security issue. Can cause accounting inconsistencies if used carelessly.
Role required: COMMITMENT_REDUCER_ROLEReduces wallet commitments bypassing stage and pause restrictions. Correctly updates all accounting state (committed/cancelled amounts, bid totals, global counters). Prefer this over recoverTokens() for committed payment tokens.
Role required: TOKEN_RECOVERER_ROLETransfers any ERC20 token from the contract to a specified address. Intended for recovering tokens sent to the contract by mistake. Prefer forceReduceCommitment() for committed payment tokens, since it correctly updates accounting state. This role is not granted at deployment. Only grant it if you have a specific recovery need.
Current sale stage. Check before calling any stage transition to confirm the contract is in the expected state.
paymentTokens()
Configured payment token addresses. Useful to verify token configuration after deployment.
totalCommittedAmount()
Total committed across all entities and tokens. Check during or after commitment to track overall participation.
totalCommittedAmountByToken()
Per-token breakdown of commitments.
totalAcceptedAmount()
Total accepted (proceeds) across all tokens. Check this before calling finalizeSettlement() — the expected amount must match exactly or the call reverts.
totalAcceptedAmountByToken()
Per-token breakdown of accepted amounts.
totalCancelledAmount()
Total cancelled during the Cancellation stage across all tokens.
totalCancelledAmountByToken()
Per-token breakdown of cancellations.
totalRefundedAmount()
Total refunded across all tokens. Check after processing refunds to verify all refunds have been issued.
totalRefundedAmountByToken()
Per-token breakdown of refunds.
withdrawnAmount()
Total proceeds already withdrawn. Check before and after calling withdraw() to confirm the expected amounts were transferred.
withdrawnAmountByToken()
Per-token breakdown of withdrawn proceeds.
numEntities()
Number of participating entities. Useful for understanding participation scale and for paginating through entities with entitiesIn().
entityAt(index)
Sale-specific entity ID at a given index.
entitiesIn(from, to)
Sale-specific entity IDs in an index range. Use with numEntities() to paginate through all participants.
entityStatesByIDs(saleSpecificEntityIDs)
Full entity state including all wallet states. Use to inspect specific entities’ commitments, allocations, and refund status.
entityStatesIn(from, to)
Entity states in an index range. Use to export or audit all entity states in bulk.
walletStatesByAddresses(addresses)
Committed and accepted amounts per token for wallets. Use to debug or verify specific participants’ state.
paused()
Whether the contract is paused.
claimRefundEnabled()
Whether self-service refund claiming is enabled.
reduceCommitmentEnabled()
Whether partial commitment reduction is enabled during the Cancellation stage.
proceedsReceiver()
Address that will receive proceeds. Verify this is correct before calling withdraw().