Settlement
The settlement contract is DarkDesk.sol at 0x0785646d7323F274E20E287A883E60679097082A, a name fixed on-chain together with its signing domain. Every DarkHooks swap ends in its fill, called by the hook as the taker. A wallet can also call fill itself: that is direct settlement, the secondary route, with the same checks and the same quote. The contract never holds the traded tokens: both legs move straight between the two wallets with transferFrom.
function fill(Quote calldata q, bytes calldata sig, uint8 side, uint256 amount)
external returns (uint256 quoteAmount);
// side 0 = BUY: you take the ask. side 1 = SELL: you hit the bid.Checks, in order
- The contract is not paused and the quote has not expired.
- The side is 0 or 1, and the amount is above zero and at most the quote's size.
- The maker can settle: a house agent, or an external maker with at least the minimum $DARKHOOKS bond.
- The signature recovers to the maker (or the maker's EIP-1271 check passes).
- The nonce is unused; it is marked used before any token moves.
The two legs
| Side | Taker sends | Maker sends |
|---|---|---|
| BUY (0) | USDG at the ask, plus the fee | The base amount |
| SELL (1) | The base amount | USDG at the bid, minus the fee |
Before anything moves, the contract checks that the maker holds and has approved its leg. A house agent that falls short reverts the whole fill. A bonded external maker that falls short is in default: the fill does not revert, the taker pays nothing, and part of the maker's bond goes to the taker (see $DARKHOOKS).
Fee
The fee is 5 bps of the USDG leg, sent to the fee address, capped at 10 bps by a constant in the contract. A taker holding the $DARKHOOKS threshold pays none, once the token is bound. Every fill emits:
event Filled(bytes32 indexed quoteHash, address indexed maker, address indexed taker,
address base, address quote, uint8 side, uint256 baseAmount,
uint256 quoteAmount, uint256 price, uint256 fee);Approvals
Takers and makers approve the contract for both tokens of a pair. The contract only ever pulls from msg.sender (the taker) and from the maker named in a quote that maker signed, so an approval cannot be used by anyone else.
