upstream

Trust

Security model

What Upstream defends against, what it asks you to trust, and what a dishonest party can do.

What you are asked to trust

  • The platforms to show the right text on the right account and to let only the owner edit it.
  • The attesters: at least threshold of them must be honest and must read the page they say they read.
  • The vault program (once it exists) to implement the rules in The vault. It would have no admin key.

Threats and answers

ThreatAnswer
Someone copies a posted code and asks to be paidThe code is bound to a wallet. For another wallet the attesters do not find their code. Tested.
Someone claims a handle they do not ownThey cannot put text on the account. Without the code on the page no attester signs.
A handle is renamed or soldThe vault is bound to the platform's stable id. The new owner of the name has a different id. Tested.
One attester lies or is hackedOne signature is below the default threshold of 2 of 3. Tested.
The same attester signs twice to reach the thresholdDistinct keys only. Tested.
A key nobody trusts signsNot in the trusted list, ignored. Tested.
An old signature is replayed15 minute freshness plus the epoch. Tested.
A hijacked account redirects the feesFresh proof, a two day delay, and a veto from the current wallet.
Fees sit unclaimed foreverExpiry sweeps them to the launcher or burns them.
A launcher takes most of the moneyThe streamer share cannot be under 50 percent.
Rounding loses moneyInteger maths with the remainder to the streamer; the invariant is tested over 400 random operations.
The same attestations are replayed on another coinThey are bound to the mint. Refused by the engine and by the program. Tested.
Someone makes two claims serialise to the same signed bytes by putting | in a fieldEvery field is validated before it is hashed or signed. A test checks that 336 different claims give 336 different messages.
Someone occupies another launcher's vault addressThe address includes the launcher, who must sign. Tested on chain.
Someone passes their own account as the launcher or the incinerator to redirect a payoutAccounts are checked against the vault's own fields. Tested on chain.
A tampered signatureSolana's Ed25519 precompile fails the whole transaction before the program runs. Tested.
An attester endpoint is used to fetch arbitrary addressesIt only builds requests for the four platforms from validated handles. A test checks that bad input causes no outgoing request.
A page injects text through a profile fieldThe site writes platform data with textContent and never as HTML.

What a dishonest attester can and cannot do

Can: sign something false. A single one cannot move money alone. If two collude, they can bind a wallet of their choosing to an account that has not claimed yet, and take the waiting fees.

Cannot: change the split, the expiry or the threshold; pay anyone other than the wallet in a code that was signed; move fees that were already paid to a bound wallet; sign for a vault that does not trust them.

The defences are the threshold, public attester identities, and, once a wallet is bound, the rotation delay and veto.

No admin key

There is no owner, no pause, no upgrade and no fee in the rules. The launcher chooses parameters at creation and cannot change them later, and pump.fun's own routing is one-way once set. Nobody can freeze or redirect a vault by decision. On chain this is only true once the program's upgrade authority has been removed (solana program set-upgrade-authority --final); until then the program's deployer can change it, which is why that step comes after an audit.

Privacy

Everything is public: the coin, the target account, the code, the attestations, the payouts. The proof reveals that a wallet controls a handle. This is not a privacy tool.

The website

The site has no backend and stores nothing. Reads go straight from your browser to the platforms. The demo wallet in the app is generated in your tab and never leaves it. Config keys that appear in config.js (such as a YouTube key) are public by nature: restrict them to your domain.