Every public entry point of the tributary-splitter contract, with its
parameters, return value, the errors it can raise, the event it emits, and its
authorization requirement. Shares are always basis points that must sum to
exactly TOTAL_SHARES (10,000); a split has at most MAX_RECIPIENTS (32)
recipients. See architecture.md for the model behind these
calls.
| Type | Definition |
|---|---|
Recipient |
Account(Address) or Split(u64) — a payee address or a child split id |
Split |
{ recipients: Vec<Recipient>, shares: Vec<u32>, controller: Option<Address> } |
TokenDistribution |
{ token: Address, amount: i128 } — one token paid by distribute_all_tokens |
| Code | Name | Meaning |
|---|---|---|
| 1 | NoRecipients |
recipient/id list was empty |
| 2 | LengthMismatch |
two paired lists had different lengths |
| 3 | ZeroShare |
a share was 0 |
| 4 | BadShareTotal |
shares did not sum to exactly 10,000 |
| 5 | SplitNotFound |
no split with that id |
| 6 | SplitImmutable |
split has no controller (locked) |
| 7 | InvalidAmount |
amount was not strictly positive |
| 8 | NothingToDistribute |
no credited balance for that token |
| 9 | TooManyRecipients |
more than 32 recipients |
| 10 | BadChildSplit |
child split is self-referential or does not exist |
| 11 | ArithmeticOverflow |
intermediate share math did not fit i128 (guarded, effectively unreachable) |
| 12 | SplitHasBalance |
tried to close or update a split still holding funds |
| 13 | MaxDepthExceeded |
cascade depth was greater than MAX_CASCADE_DEPTH (5) |
| 14 | TooManyTokens |
more than MAX_DISTRIBUTE_TOKENS (10) tokens were requested |
| 15 | NoPendingTransfer |
no pending controller transfer exists for the split |
Registers a new split and returns its id. shares are basis points and must sum
to exactly 10,000. A Some(controller) makes the split mutable by that address;
None locks it forever.
- Auth:
creator - Errors:
NoRecipients,TooManyRecipients,LengthMismatch,ZeroShare,BadShareTotal,BadChildSplit - Event:
SplitCreated { id, creator }
Moves amount of token from the payer to every recipient of the split in one
call. Rounding dust goes to the last recipient, so amount in equals amount out.
- Auth:
from - Errors:
InvalidAmount,SplitNotFound - Event:
SplitPaid { id, token, amount }
Pays several splits from one signer in a single transaction. ids and amounts
pair up positionally; any failure reverts the whole call.
- Auth:
from - Errors:
NoRecipients,LengthMismatch,InvalidAmount,SplitNotFound - Event:
SplitPaid { id, token, amount }per split
Pays several splits from one signer, allowing each split to use a different
token. ids, amounts, and tokens pair up positionally; any failure reverts
the whole call.
- Auth:
from - Errors:
NoRecipients,LengthMismatch,InvalidAmount,SplitNotFound - Event:
SplitPaid { id, token, amount }per split
Replaces the recipients and shares of a mutable split. Controller only.
Rejected while the split holds a balance in any token — a depositor's escrow
cannot be redirected by a routing-table change made after the deposit lands.
Call distribute for every token in held_tokens first.
- Auth: the split's
controller - Errors:
SplitNotFound,SplitImmutable,SplitHasBalance,NoRecipients,TooManyRecipients,LengthMismatch,ZeroShare,BadShareTotal,BadChildSplit - Event:
SplitUpdated { id }
Proposes transferring a mutable split to another address, or locks it forever
when new_controller is None. A proposed address must call accept_control
to complete the handover; the current controller may call cancel_transfer.
- Auth: the split's current
controller - Errors:
SplitNotFound,SplitImmutable - Event:
ControlTransferProposed { id, new_controller }forSome, orControlTransferred { id, new_controller: None }when locking
Accepts a pending transfer and makes the proposed address the split controller.
- Auth: the pending controller
- Errors:
NoPendingTransfer,SplitNotFound - Event:
ControlTransferred { id, new_controller }
Cancels any pending controller transfer. The call succeeds when no proposal is pending.
- Auth: the split's current
controller - Errors:
SplitNotFound,SplitImmutable - Event: none
Closes a split and reclaims its storage. Controller only, and only when the split holds no balances.
- Auth: the split's
controller - Errors:
SplitNotFound,SplitImmutable,SplitHasBalance - Event:
SplitClosed { id }
Moves funds into the contract and credits them to the split without paying anyone
yet. Credits the amount the vault balance actually increased by (not the
requested amount), so fee-on-transfer tokens cannot over-credit the split.
The routing table this deposit will pay out against cannot be changed out from
under it: update_split refuses to run while the split holds a balance in any
token, so escrowed funds always pay out to the recipients that were in place
when the deposit landed. This only applies to mutable splits — immutable
splits (controller: None) have no routing table to change.
- Auth:
from - Errors:
InvalidAmount,SplitNotFound - Event:
Deposited { id, token, amount }(only when the received amount is positive)
Pays out everything credited to the split for the given token and returns the amount distributed. Permissionless — the routing table alone decides where funds go.
- Auth: none (anyone may call)
- Errors:
SplitNotFound,NothingToDistribute - Event:
Distributed { id, token, amount }
Distributes one split and recursively distributes newly credited direct child
splits through max_depth. A depth of 0 distributes only the parent; the
maximum is MAX_CASCADE_DEPTH (5). Returns the parent amount distributed.
- Auth: none (anyone may call)
- Errors:
MaxDepthExceeded,SplitNotFound,NothingToDistribute - Event:
Distributed { id, token, amount }per distributed split
Distributes up to MAX_DISTRIBUTE_TOKENS (10) token balances for a split.
Some(tokens) selects the tokens; None uses every token currently held.
Zero-balance tokens are skipped. Returns each token that was distributed and
its amount.
- Auth: none (anyone may call)
- Errors:
SplitNotFound,TooManyTokens - Event:
Distributed { id, token, amount }per distributed token
Returns the exact per-recipient amounts a payment of amount would produce,
without moving any funds.
- Auth: none
- Errors:
InvalidAmount,SplitNotFound
Credited amount waiting to be distributed for the split and token. Returns 0 when nothing is held.
- Auth: none
Returns whether a split record exists for id.
- Auth: none
Returns the split record.
- Auth: none
- Errors:
SplitNotFound
Tokens the split currently holds an escrow balance in. Empty when none.
- Auth: none
Ids of all splits a creator registered. Empty when none.
- Auth: none
Returns at most limit creator split ids beginning at zero-based offset
start. Returns an empty vector when start is out of range or limit is 0.
- Auth: none
Number of splits registered by creator.
- Auth: none
Number of splits created so far (also the id the next create_split will use).
- Auth: none
Returns the proposed controller awaiting acceptance, or None when no transfer
is pending.
- Auth: none