Work / Cryptoopen brief

Gift a Share: a slice of a stock as a gift by link, on Base

What it was

Coinbase issued real US stocks as tokens on the Base network. Gifting a stock is still awkward: both people need brokerage accounts, a transfer between them, and with a child or a friend in another country it is nearly impossible. A tokenized stock lives in a wallet and can be handed over any way you like. What was missing was simple packaging: here is a link, your slice of Apple is in it, it opens on your birthday.

What we did

Wrote an escrow contract in Solidity with no owner and no admin keys, covered it with 9 tests and deployed it on Base mainnet. Built a Next.js site: a storefront of 13 companies, purchases from $5 through a swap aggregator, a gift page and a claim page. Every flow was run with real money, and the Builder Code tag was verified link by link on chain, not by eye.

What the client got

A live site, a contract on mainnet anyone can open on Basescan, and a 1 min 28 s video. From an empty folder to all of that took about a day and a half. The site checks on its own whether the tag reached the blockchain and tells the truth in green or red.

ClientBase (the Coinbase network). Open brief, Builder Quest
My roleIdea, smart contract and tests, website, on-chain attribution check, video editing
StatusSubmitted. Base sends results by email, no reply yet
Result1.5 days from an empty folder to a live site, a mainnet contract and a video · Open
Rejected: for stocks with no market the aggregator returns a placeholder price of 0.0000000001, and the site rendered it as '$0.00 per share'. Reconstruction, not a screenshot
Rejected: for stocks with no market the aggregator returns a placeholder price of 0.0000000001, and the site rendered it as '$0.00 per share'. Reconstruction, not a screenshot
Accepted: any price below 1 cent is not shown. The 4 companies with a live market are active, 9 are greyed out with 'no market yet'
Accepted: any price below 1 cent is not shown. The 4 companies with a live market are active, 9 are greyed out with 'no market yet'

The task

Base, the network built by Coinbase, published an open brief: build an app on top of their tokenized stocks and wire in Builder Code, a tag that lets Base see which transactions came from your app. One rule from the brief: do not show trading to US users, because Coinbase stocks are not available to them.

For us it was also a test of whether we can ship an on-chain product end to end: our own smart contract, a mainnet deployment, real money, other people’s wallets. Here a mistake costs money, not just a bug on screen. And a portfolio piece anyone can open and verify on the blockchain, not a mockup.

Why, and what the idea was

Gifting a stock today is awkward. The giver needs a brokerage account, the recipient needs one too, then a transfer between them, and with a child or a friend abroad it is nearly impossible. A store gift card is simpler, but that is just money locked to one shop.

A tokenized stock lives in a wallet, so it can be handed over any way you like. The idea: the link is the gift. The giver locks a slice of a share in a contract under the hash of a secret. The secret sits in the link after the # sign, a part the browser never sends to the server. We do not store it and cannot resend it, and the site says so plainly. Whoever opens the link with their wallet keeps the share. You can set a date before which nobody can open the gift, not even the giver.

The contract has no owner, no pause, no admin and no upgrade path. That is deliberate: nobody has to trust us, the code holds the shares.

How it went

When What happened
Evening of day 1 Next.js skeleton, contract and tests, deployment to Base mainnet. All 13 tickers checked for a live market: 4 work. Spread measured on amounts up to $20,000
Morning of day 2 Gift and claim work on mainnet. Half a day investigating why Builder Code did not reach the chain on purchases
Day 2 Video: four screen recordings, stitched by an ffmpeg script, three versions. In the third the “opens in 2027” episode moved to the end
5 days later Tweet with the video and the @buildonbase tag, submission form filled in with time to spare

The main fork came at the end of day 2. The Builder Code tag was getting lost on purchases, and the only real fix was our own swap adapter contract. We did the math: half a day of work, a new contract that other people’s money would flow through, five days before the deadline, for a field the brief did not require. We stopped and instead show the user on screen, honestly, whether the tag made it or not.

Tools and method

The StockGift.sol contract in Solidity 0.8.28, about 140 lines. The giver locks shares under the hash of a secret; whoever knows the secret can claim them, and only after the opening date. Reentrancy protection, a check of how many tokens actually arrived. If nobody claims the gift, the giver can take it back, but not sooner than 30 days after the opening date, so a gift cannot be pulled out from under the recipient. 9 Hardhat tests: cannot claim early, cannot claim twice, a stranger cannot reclaim, a wrong secret is rejected.

Purchase: our own Next.js API asks the LI.FI aggregator for an ETH-to-stock route, and LI.FI picks 1inch, Kyberswap, Aerodrome or others on its own. We only build the transaction; the user’s wallet signs it, our server never holds funds. The amount cap is $25,000, the largest volume we actually tested ($20,000 into Apple went through with a 0.31% spread).

Builder Code, per the ERC-8021 standard, is appended to the transaction data on the server, in one place you can check with plain curl. For smart wallets that wrap the call in their own operation, the tag goes in a separate field per EIP-5792. After a purchase the site re-reads the transaction from the chain and prints in green “Builder code confirmed in the mined transaction”, or in red that the wallet rebuilt the transaction and dropped the tag.

Site: Next.js 16, React 19, wagmi + viem, hosted on Vercel. Country comes from a hosting header; visitors from the US see “Not available where you are”. The whole codebase is about 1,300 lines including the contract and tests. The contract on Base mainnet: 0x0535…5a88 on Basescan.

Result

The live site is stockgift-pi.vercel.app. The storefront lists the 13 companies Coinbase issued on Base; 4 can be bought (Apple, Nvidia, Alphabet, Meta), the other 9 are greyed out with “no market yet”. That is not a guess: for every ticker we requested a real swap route at $5 and $15 with 1% and 3% slippage, and nine had no market. When a market appears they switch on without any rework, the list is already in the code.

Every flow was run on mainnet with real money: a $5 Nvidia purchase via Kyberswap at a 0.06% spread, a gift of 0.01 Nvidia share, a claim from a different browser and a different wallet, and a second gift set to open in 2027. All of it is in the 1 min 28 s video and on Basescan.

The Builder Code tag was verified link by link, not by eye:

Link in the chain How it was checked Outcome
Server returns transaction data with the tag curl against the live API present
Page received it with the tag green line on screen present
Router and network keep the tag our own test transaction present
Purchase through a wallet 5 purchases on chain tag missing
Gift, a call to our contract 2 times on chain present

A weak spot we left in: on purchases through some wallets the tag is lost. The site does not hide it, it prints it in red. A second weak spot the contract names in its own comment: at claim time the secret is briefly visible in the transaction queue and could in theory be intercepted. The damage is limited to one gift; the giver’s balance is never at risk.

Infrastructure cost nothing: Vercel and the LI.FI API without a key. The Builder Code experiment cost $0.15 from the deployer wallet; gas for a purchase in the video is about $0.01. What we do not know yet: the outcome of the brief. Base emails the winners, no public announcement was promised.

Mistakes and what we took from them

The wallet rebuilds the transaction on its own.Half a day went into why the tag reached the chain on gifts but not on purchases. It turned out the wallet recognizes a known swap router (LI.FI, Kyberswap), decodes the data by its ABI and re-encodes it, dropping our tail with the tag. Our contract is not published anywhere, so the wallet cannot decode it and sends it as is, which is why gifts carry the tag. Proven with our own transaction, not by reasoning. Lesson: check what landed on chain, not what left the page.
A setting that did nothing.A `dataSuffix` parameter sat in the wagmi config and gave the impression the tag was wired in. The word `dataSuffix` does not appear once in `@wagmi/core`; only `viem` knows it. Removed, with a comment in the code explaining why.
Smart wallets lose the tag too.On one real claim the on-chain sender turned out to be a smart wallet's relay, and the tag vanished. For such wallets the tag now travels in a separate field per EIP-5792.
A false hypothesis about caching.Purchases were being made from an old tab of the form `stockgift-.vercel.app`, which served an old build and an old API. That is where the caching theory came from. Rule: test only on the main address, typed by hand.
The edit misled the viewer.In early versions of the video the "gift opens in 2027" episode came before the one where a gift is claimed right away. A viewer reads that as the same gift and decides the app is lying. In the third version the timed gift moved to the end and is labelled as a second one.
The project lived two days outside of memory.No README in the folder, not a line in the notes, while there was an external deadline and a site under my name on the internet. Caught during an evening review; a project card was created. Rule: a project with a deadline gets written down on day one.
The "$0.00" price.For stocks with no market the aggregator returns a placeholder price of 0.0000000001. Showing it as "$0.00" is worse than nothing, so the site hides any price below 1 cent.

Tools

Solidity 0.8.28HardhatNext.js 16React 19wagmi + viemLI.FI APIBase mainnetVercelffmpegClaude Code