Settlement contract
SamaSettlement executes a fully signed multi-party plan atomically. It never matches, prices or holds tokens.
Deployment
| Network | Address |
|---|---|
| BNB Smart Chain (56) | 0x7811a30D29d6c2Ca95Aeb4EE9D896cE44Cb72AC8 |
Solidity 0.8.33, optimizer on (10,000 runs), EVM cancun. Built on OpenZeppelin EIP712, SignatureChecker, SafeERC20 and ReentrancyGuard. No constructor arguments, no owner, no upgrade path.
Types
SamaSettlement.sol
struct Leg {
address token;
address from;
address to;
uint256 amount;
}
struct SettlementPlan {
bytes32 roundId;
bytes32 planId;
bytes32 valuationSnapshotHash;
uint64 validAfter;
uint64 validUntil;
address[] participants; // strictly ascending
Leg[] legs; // strictly ascending by (token, from, to)
}
struct Approval {
uint256 nonce;
bytes signature; // EIP-712 PlanApproval, EOA or ERC-1271
}Functions
| Function | Description |
|---|---|
settle(plan, approvals) → planHash | Validates the window, participants, legs, every approval and nonce, then runs safeTransferFrom for each leg. Anyone may call it |
cancelNonce(nonce) | Withdraws an approval you signed but that hasn't been used |
hashPlan(plan) | The EIP-712 struct hash of a plan; offchain signers must produce the same value |
approvalDigest(plan, participant, nonce) | The exact digest a participant signs |
domainSeparator() | The EIP-712 domain: name Sama, version 1, chain id, this contract |
planSettled(hash), nonceUsed(owner, nonce) | Public replay-protection state |
Events
solidity
event PlanSettled(bytes32 indexed roundId, bytes32 indexed planId, bytes32 indexed planHash, uint256 participantCount, uint256 legCount);
event CrossingLeg(bytes32 indexed planHash, address indexed token, address indexed from, address to, uint256 amount);
event NonceConsumed(address indexed owner, uint256 indexed nonce, bytes32 indexed planHash);
event NonceCancelled(address indexed owner, uint256 indexed nonce);Errors
| Error | When |
|---|---|
PlanNotYetValid, PlanExpired | Outside the plan's time window |
PlanAlreadySettled | The plan hash already settled |
TooFewParticipants, EmptyPlan | Fewer than two participants, or no legs |
ParticipantsNotSorted, LegsNotSorted | The plan isn't in canonical order |
ApprovalCountMismatch | Approvals don't match participants one to one |
NonceAlreadyUsed, InvalidSignature | A reused or cancelled nonce, or a bad signature |
ZeroAmount, ZeroToken, SelfTransfer | A malformed leg |
UnknownParty, IdleParticipant | A leg party outside the participants, or a participant with no leg |
Build, test, deploy
bash
cd sama-contract
forge build
forge test # unit + fuzz tests
forge test --match-path test/fork/* # against a BSC mainnet fork
# Dry run against the live chain (sends nothing)
forge script script/DeploySettlement.s.sol --rpc-url bsc
# Deploy and verify on BscScan (needs SAMA_DEPLOYER_PRIVATE_KEY, ETHERSCAN_API_KEY)
forge script script/DeploySettlement.s.sol --rpc-url bsc --broadcast --verify