Build
Contracts
Two files. Read-only, ownerless, no fee.
Scrip.sol composes the four numbers into a single call. Nobody else does this: Chainlink knows the token price but not the share price, the token knows the multiplier but not the price, and a router knows the pool but not the multiplier.
Scrip.sol
struct Asset {
address token;
uint256 multiplier; // 1e18, shares per token
uint256 tokenPrice; // 1e8, multiplier already inside
uint256 sharePrice; // 1e8, tokenPrice * 1e18 / multiplier
uint64 updatedAt;
bool hasFeed;
}
function asset(address token) external view returns (Asset memory);
function assets(address[] calldata tokens) external view returns (Asset[] memory);
function sharesOf(address token, address stock, uint256 amount)
external view returns (uint256);
function driftBps(address token, uint256 poolPrice1e8)
external view returns (int256);ScripCalendar.sol
struct Action {
uint8 kind; // 0 cash dividend, 1 split, 2 other
uint64 effectiveAt;
uint128 rate1e8; // per underlying share
uint64 postedAt;
bool settled;
}
function post(address token, Action calldata a) external; // poster only
function settle(address token) external; // anyone
function upcoming() external view returns (address[] memory, Action[] memory);
event ActionPosted(address indexed token, uint8 kind, uint64 effectiveAt, uint128 rate);
event ActionSettled(address indexed token, uint256 oldMultiplier, uint256 newMultiplier, uint64 at);settle() takes no privileges. It reads uiMultiplier() and, if it has changed since the action was posted, writes the observed old and new values into an event. The forecast is ours; the settlement is the chain’s.
