194 STOCK TOKENS · 12 HAVE TICKED · 24 REPRICINGS SCHEDULED

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.