Sitowise
Protocol

Fee flow

Follow one unit of value from end to end. Purchase money and payout money never mix, they arrive at different addresses, and only one of them can ever reach a holder. Knowing which is which answers most questions about the protocol.

Two pots, kept apart

PotHoldsCan pay holders
Payments walletNode purchases, received as plain transfersNo. It is an ordinary account outside the contract entirely.
Factory balancePayout money, sent by the distributor with creditBatch, plus anything added through fund() or a plain transferYes. This is the only balance a withdrawal draws from.

The separation is not a policy, it is a consequence of where the money is sent. Buying a node is a transfer to a wallet; the factory has no payable mint and never sees your 0.02 ETH, not for one block. Purchase money cannot become payout liquidity because it is never in the contract to begin with.

Payout money arrives the other way round, from the distributor, and it arrives attached to specific nodes. If the two shared an address every payout would be partly funded by the next buyer and the contract could not tell them apart. Keeping them separate is what gives outstanding and freeBalance() a meaning that can be checked from outside.

The path, hop by hop

Sitowise, launch periodPaymentA plain transfer tothe payments walletWatcherSees the transfer andrecords the tx hashmintForThe relayer createsthe node, pays the gascreditBatchThe distributor sendsETH onto balancesNode balanceHeld on chain,counted in outstandingwithdrawYou call it yourself,the whole balance moves
The spine is what happens today. The branch dropping into creditBatch is launch-period funding.
  1. Payment. The buyer sends exactly 0.02 ETH to the payments wallet. Plain transfer, no calldata, no contract involved. That money has left the flow at this point: it funds the operation, and nothing downstream draws on it.
  2. Watcher. The server reads blocks, finds the transfer, and records it with its transaction hash before anything is minted. See Deploying a node.
  3. mintFor. The relayer creates the node for the paying address and pays that gas itself. The payment transaction hash goes in as paymentRef, which is what ties the sale to the node in the explorer.
  4. creditBatch. The distributor sends the round’s ETH and the per-node amounts in one payable call. msg.value must equal the sum of the amounts, so the money and the record land together. See Distribution.
  5. Node balance. The value now sits in the factory, attached to your node and counted in outstanding. It stays there until you move it. Nobody else can, including the contract owner.
  6. withdraw. You call it yourself, from the wallet that owns the node, naming any destination. The whole balance of that node moves. withdrawAll does the same across every node you own in one transaction. See Withdrawing.

Where the value comes from today

When that changes, it changes one hop only. A swap through a pool naming the hook would pay a share of the unspecified side into the hook, and sweepNative() would move it into the factory, giving the distributor money to credit that it did not have to fund. The mechanism is described on How accrual works, and it is described as intended, not as running. Everything from creditBatch onward is identical either way: the same call, the same balances, the same withdrawal from your own wallet.

Who pays what

CostPaid byWhen
0.02 ETH node priceYouOnce, as a transfer to the payments wallet
Gas for the transferYouWith the payment
Gas for mintForSitowise, from the relayerWhen your node is created
Gas for creditBatch, and the ETH it carriesSitowise, from the distributorEvery round
Gas to withdrawYouEvery withdrawal
The hook’s share of a swapThe swapperLater, inside the swap, on the unspecified side

Checking the flow yourself

A handful of reads describe the state of the payout pot at any moment, and none of them require this website.

cast
cast call $FACTORY "totalDistributed()(uint256)"  # every wei ever credited to nodes
cast call $FACTORY "totalWithdrawn()(uint256)"    # every wei owners have taken out
cast call $FACTORY "outstanding()(uint256)"       # credited, not yet withdrawn
cast call $FACTORY "freeBalance()(uint256)"       # balance above what is owed
cast call $FACTORY "isSolvent()(bool)"

cast balance $FACTORY                             # the pot itself

outstanding is the sum of every node balance, and freeBalance() is what is left over. Those two are the whole guarantee: rescue is bounded by the second, so no sequence of owner calls reaches the first. If isSolvent() ever returns false the contract is not holding enough to cover the balances it has written, which is a state worth watching for and is listed among the failure modes on Risks.