The standard
ERC-555: an ERC-20 where whoever owns a unit can program it. A nickname, not an assigned EIP number.
Every unit leaves the pool plain.
If you own it you can program it, and the program follows the unit from wallet to wallet.
Only two things erase the program: the pool, when sold, and the end date.
The cycle
What happens to a unit, from the pool and back.
The program travels with the units in between: every wallet they reach carries it.
Functions
balanceOf counts every unit, plain and programmed.
programWrites a program on plain units you own, with your settings and an end date. The units stay in your balance.transferBehaves like any ERC-20: plain units go first. Past them, programmed units go too, whole, and their program is asked.sendMoves one chosen row to another wallet. The program follows it.sellTakes a row into the pool. The program is asked, the pool erases it and pays ETH.expireErases a program after its end date. Anyone can call it, the units stay where they are.What a program can do
A read-only contract. It never holds a unit and never touches ETH.
When units ask to move, it answers yes or no. Its settings are typed by whoever writes it and can never be edited, not by you, not by someone holding your keys.
Any program may also answer with one verb from a closed list, and the token carries it out: sell these units for their owner, or hand them to whoever pays the owner the price written in the settings. Programs are permissionless, like Uniswap v4 hooks: this site lists the ones it has reviewed.
Built-in programs
Fixed when the token was deployed. Nobody can add or change one.
Write your own
Any contract with three read-only functions. Everything it may look at arrives in one struct.
contract Weekend is IProgram { // sellable on Saturdays and Sundays only. Free between wallets. function check(Ask calldata ask) external pure returns (bytes4) { if (!ask.toPool) return IProgram.check.selector; // yes uint256 day = (ask.time / 1 days + 4) % 7; // 0 = Sunday return day == 0 || day == 6 ? IProgram.check.selector : bytes4(0); } function validate(Ask calldata ask) external pure returns (bytes4) { return ask.params.length == 0 ? IProgram.validate.selector : bytes4(0); } function describe(bytes calldata) external pure returns (string memory) { return "These units can only be sold on Saturdays and Sundays (UTC)."; } }
- Deploy it, once. It has no owner and no state.
- Paste its address on Write a program. The site reads describe() from the chain and shows you the sentence before you sign.
- Press Program. From there it behaves like any other: it follows the units, the pool erases it, it stops on the end date.
DIAL never checks a program. If it is wrong, the worst it can do is say no until the end date.
Guarantees
Fees
DIAL trades on one pool. Anyone can add liquidity to it, no other pool can hold DIAL.