Overview
For most sales, Sonar deploys and manages the SettlementSale contract for you. However, if you have specific requirements not covered by the standard contract, you can build a custom contract that integrates with Sonar’s compliance infrastructure.When to Build a Custom Contract
- You need custom onchain logic beyond what Sonar provides
- You want to integrate token sale logic with other contract functionality
- You have specific requirements for how commitments are structured
- You want to extend the standard contract with additional features
Deployment Models
Sonar supports different levels of customization:| Model | Contract | Settlement Computation |
|---|---|---|
| Standard | Sonar deploys SettlementSale | Sonar computes allocations |
| Custom with Sonar Settlement | You deploy custom contract | Sonar computes allocations |
| Fully Custom | You deploy custom contract | You compute and provide allocations |
ICommitmentDataReader- so Sonar can read commitment data, which enables computing prices (for auctions) and allocationsIOffchainSettlement- so Sonar can write the computed allocations to your contract
The Core Integration
Your custom contract must validate purchase permits—signed authorizations from Sonar that prove a wallet is eligible to participate. Sonar handles all compliance (KYC/KYB, accreditation, jurisdiction checks) and issues permits for eligible participants. The permit contains:- Entity identity and authorization proof
- Purchase limits (min/max amounts)
- Price limits (for auctions)
- Expiration timestamp
Purchase Permit
Sonar generates permits with this structure (see also the sonar contract repo):Validation
To ensure the validity of a purchase permit, you need to verify the following aspects (see also the example implementation below). Please make sure to implement all of these checks to ensure correct enforcement of the requirements of your sale.- The ECDSA signature was issued by the Sonar signer
- The permit’s sale UUID matches yours
- The permit is not expired
- The current time is within the permit’s time window (
opensAt<= now <closesAt) - The sender matches the wallet address in the permit
- The commitment amount is within the minimum and maximum amount limits
- The bid price is within the minimum and maximum price limits (for auctions)
Example Validation
These snippets are based on the example sale contract.1. Signature Verification
You must verify that permits are signed by Sonar’s authorized signer:2. Sale UUID Validation
Prevent permit reuse across different sales:3. Expiration Checks
Permits have short expiration times:4. Time Window Validation
Permits include a time window during which they are valid for commitments:5. Wallet Authorization
Ensure the permit is used by the authorized wallet:Integration Patterns
Wallet-Level Tracking (Basic)
The example contract tracks purchases by wallet address:Entity-Level Tracking
One might want to additionally enforce limits by entity, across all wallets they can use:Auction bid price validation
If you are running a sale with a dynamic pricing model where the user can commit with a requested price (e.g. auctions), you should validate the bid price is within the minimum and maximum price limits.Getting the Signer Address
Sonar signs all purchase permits using a global infrastructure key. When deploying your contract, grant thePURCHASE_PERMIT_SIGNER_ROLE to this address.
For EVM chains: 0x9a1964e04d10ccfe1a9ce300d943f71c6e3ae24c
For other chains, contact [email protected] to get the correct signer address.
The permit signer role is always held by Sonar’s infrastructure. This ensures all purchase authorizations flow through Sonar’s compliance verification, maintaining the integrity of the permit system.