A check takes a class, a sender, a recipient, a number of units and a date. It returns every rule that fails, not just the first one. These are rule checks against the rules an entity set. They are not a legal conclusion.
The rules, in order
- The class must not be frozen.
- The request must be for at least one unit.
- The recipient must be a real address, other than the sender.
- The sender must hold that many units.
- That many of them must have vested.
- If the class uses an eligibility list, the recipient must be on it and in date.
- If the class uses windows, one must be open at that time.
- The class lockup and the sender's own lockup must have passed.
- If the class has a holder cap, the move must stay within it.
Checking another date
You can ask about any date. A check at a future date uses today's balances, list and windows, and works out vesting and lockups for that date. Anything that changes in between can change the answer, which is why recording runs every rule again at that moment.
Same answer in two places
The rules exist twice: in the contract, and in a TypeScript copy that runs in your browser so a check costs nothing and needs no wallet. The project's tests run one shared file of test cases through both, and any difference fails them. When the book is live, the check page shows the contract's own answer beside the local one.
The owner's example
An employee wants to transfer 500 units. Forsiq checks the vested amount, the recipient's eligibility and the transfer window. In the demo all three fail on the default date, and each failure says what must be met. Move the date and add the recipient to the list, and they clear one at a time.