<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Yinghui</title>
    <description>The latest articles on DEV Community by Yinghui (@yinghuicrypto).</description>
    <link>https://dev.to/yinghuicrypto</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4219559%2F863b9c8a-96db-4de6-95db-bab2fb439624.png</url>
      <title>DEV Community: Yinghui</title>
      <link>https://dev.to/yinghuicrypto</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yinghuicrypto"/>
    <language>en</language>
    <item>
      <title>Rate-Limiting Writes, Not Reads: A Referral System Redesign</title>
      <dc:creator>Yinghui</dc:creator>
      <pubDate>Mon, 02 Nov 2026 08:39:25 +0000</pubDate>
      <link>https://dev.to/yinghuicrypto/rate-limiting-writes-not-reads-a-referral-system-redesign-dc</link>
      <guid>https://dev.to/yinghuicrypto/rate-limiting-writes-not-reads-a-referral-system-redesign-dc</guid>
      <description>&lt;p&gt;A referral system's core write happens once, at account creation, and is immutable afterwards. The design rationale is fraud resistance: if the field could be edited, users could self-refer or arbitrage commission structures after the fact.&lt;/p&gt;

&lt;p&gt;That rationale is sound. The implementation usually is not.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with write-once
&lt;/h2&gt;

&lt;p&gt;Write-once solves the fraud case and creates a silent-failure case. The referrer column is nullable because signing up without a code is legitimate - so a dropped write is indistinguishable from a deliberate opt-out.&lt;/p&gt;

&lt;p&gt;No exception. No retry. No alert. The account is created successfully and the user never learns they are unqualified.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the fraud model actually needs
&lt;/h2&gt;

&lt;p&gt;Self-referral is a write-side abuse. The constraint that matters is &lt;strong&gt;who can create attribution, and how often&lt;/strong&gt; - not &lt;strong&gt;whether attribution can ever be read or repaired&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Three constraints do the work:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Rate-limit attribution creation per identity document and per device fingerprint.&lt;/li&gt;
&lt;li&gt;Require the referrer to have an active, verified account at the time of referral.&lt;/li&gt;
&lt;li&gt;Cap commission-eligible referrals per referrer per period.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;None of those require making the field permanently immutable. All of them target the abuse directly.&lt;/p&gt;

&lt;h2&gt;
  
  
  What an editable-with-audit model looks like
&lt;/h2&gt;

&lt;p&gt;Instead of write-once, use write-once-with-a-pending-second-write:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The signup write is the canonical attribution and takes effect immediately.&lt;/li&gt;
&lt;li&gt;A second write is allowed only within a short window (say 24 hours) and only if the first was empty.&lt;/li&gt;
&lt;li&gt;Every write is logged with the source (query parameter, form field, support override) and immutable in the audit trail.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This closes the silent-failure case without opening the self-referral case, because the second write cannot overwrite an existing attribution.&lt;/p&gt;

&lt;h2&gt;
  
  
  The observability fix
&lt;/h2&gt;

&lt;p&gt;The deeper problem is that the failure is invisible to engineers too. A nullable column with no companion metric means you cannot compute a referral attribution rate, so you never discover that some percentage of signups are silently failing.&lt;/p&gt;

&lt;p&gt;The fix is small: persist the referral parameter separately from the resolved attribution. Then a mismatch between "parameter present" and "referrer stored" is a measurable, alertable event.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it stays broken
&lt;/h2&gt;

&lt;p&gt;The discount comes out of the customer acquisition budget. The platform pays either way. A silent failure costs the platform nothing, the user a few percent, and the referrer their commission - and only the last of those has any incentive to complain.&lt;/p&gt;

&lt;p&gt;When a failure has no owner, it has no fix. That is the actual design lesson.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Disclosure: author has a referral code. Not financial advice.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>backend</category>
      <category>systemdesign</category>
    </item>
    <item>
      <title>Why Referral Attribution Fails Silently (And How to Design Around It)</title>
      <dc:creator>Yinghui</dc:creator>
      <pubDate>Mon, 02 Nov 2026 07:05:58 +0000</pubDate>
      <link>https://dev.to/yinghuicrypto/why-referral-attribution-fails-silently-and-how-to-design-around-it-18f5</link>
      <guid>https://dev.to/yinghuicrypto/why-referral-attribution-fails-silently-and-how-to-design-around-it-18f5</guid>
      <description>&lt;p&gt;Every referral system I have audited has the same shape: one write, at account creation, and no way to correct it afterwards.&lt;/p&gt;

&lt;p&gt;That shape is not an accident. It is what you get when you design for fraud resistance first and user experience second, and it produces a failure mode that engineers rarely think about because it never throws an exception.&lt;/p&gt;

&lt;h2&gt;
  
  
  The write
&lt;/h2&gt;

&lt;p&gt;The backend stores a referrer field inside the signup transaction. That single write is the entire attribution. Everything downstream - fee discount, commission, reporting - reads from it.&lt;/p&gt;

&lt;p&gt;The write competes with email verification state, KYC status, and initial balance creation. If the code arrives as a query parameter, it also competes with session state, redirects, and whatever the frontend did to the form before submitting.&lt;/p&gt;

&lt;p&gt;Any of those can drop it. None surface an error.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the bug is invisible
&lt;/h2&gt;

&lt;p&gt;The field is nullable, so "no referrer" is a valid state - identical to a user who deliberately declined a code. You cannot distinguish "user opted out" from "our pipeline dropped it" after the fact.&lt;/p&gt;

&lt;p&gt;That is the design tension in one sentence.&lt;/p&gt;

&lt;h2&gt;
  
  
  The UI compounds it
&lt;/h2&gt;

&lt;p&gt;Most interfaces display your own outbound code prominently and record your referrer quietly. Users check the first, see a code, and conclude the relationship is active.&lt;/p&gt;

&lt;p&gt;If a system writes something once and never again, it owes the user a verification surface for that value.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a better design looks like
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Echo the value back immediately.&lt;/strong&gt; After signup, show "You were referred by X". If the value is empty and the user arrived via a referral link, warn them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Preserve the evidence.&lt;/strong&gt; Keep the original signup request payload long enough that support can adjudicate a rebind weeks later.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Rate-limit writes, not reads.&lt;/strong&gt; The fraud concern is self-referral, a write-side problem. Making the field read-only does not solve fraud; it moves the pain to honest users.&lt;/p&gt;

&lt;h2&gt;
  
  
  The economics explain persistence
&lt;/h2&gt;

&lt;p&gt;The discount comes from the customer acquisition budget. The platform pays either way, so a silent failure costs nothing to the platform and a few percent to the user, permanently and invisibly.&lt;/p&gt;

&lt;p&gt;When a failure costs the platform nothing and the user invisibly, it survives for years.&lt;/p&gt;

&lt;p&gt;If you want a code to try, mine is BBBKK (&lt;a href="https://www.binance.com/register?ref=BBBKK" rel="noopener noreferrer"&gt;https://www.binance.com/register?ref=BBBKK&lt;/a&gt;) - but the verification habit matters more than the code.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Disclosure: I receive a commission if you sign up with the code above. This is not financial advice.&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Wallet Basics: Custodial, Hot, and Cold - Where Each Fails</title>
      <dc:creator>Yinghui</dc:creator>
      <pubDate>Mon, 02 Nov 2026 06:53:28 +0000</pubDate>
      <link>https://dev.to/yinghuicrypto/wallet-basics-custodial-hot-and-cold-where-each-fails-30cd</link>
      <guid>https://dev.to/yinghuicrypto/wallet-basics-custodial-hot-and-cold-where-each-fails-30cd</guid>
      <description>&lt;p&gt;Wallet basics get explained with metaphors that are accurate and useless for decisions. Here is the practical version: what each type does, and where it fails.&lt;/p&gt;

&lt;h2&gt;
  
  
  Custodial wallets
&lt;/h2&gt;

&lt;p&gt;The exchange balance. You have an account, they have the keys. Fails when the company fails, freezes, or restricts access - mitigated with 2FA, a withdrawal whitelist, and by not keeping everything there.&lt;/p&gt;

&lt;p&gt;This is where the fee discount lives: a referral code gives roughly 20% off spot fees. Mine is BBBKK at &lt;a href="https://www.binance.com/register?ref=BBBKK" rel="noopener noreferrer"&gt;https://www.binance.com/register?ref=BBBKK&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Software wallets (hot)
&lt;/h2&gt;

&lt;p&gt;Keys on an internet-connected device. You control them, which means you can lose them. Fails through malware, phishing for the seed phrase, and device compromise.&lt;/p&gt;

&lt;p&gt;Reasonable for spending-size amounts. Not for savings.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hardware wallets (cold)
&lt;/h2&gt;

&lt;p&gt;Keys on a dedicated device that signs without exposing the secret. Fails through a lost seed phrase, a counterfeit device, and social engineering that convinces you to type the phrase somewhere digital.&lt;/p&gt;

&lt;p&gt;The correct choice for long-term holdings, and the one requiring the most setup discipline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three practical rules
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Rule 1.&lt;/strong&gt; Buy hardware wallets from the manufacturer, never from a marketplace.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rule 2.&lt;/strong&gt; Test recovery once with a small amount before trusting any wallet with savings. An untested backup is a rumour.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rule 3.&lt;/strong&gt; Never enter a seed phrase into anything with a screen that is not the device itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  How this connects to the exchange question
&lt;/h2&gt;

&lt;p&gt;People ask whether a referral code matters if they move to self-custody. The code applied to the trading you do on the venue - and if you trade at all, it applies. Mine is BBBKK: &lt;a href="https://www.binance.com/register?ref=BBBKK" rel="noopener noreferrer"&gt;https://www.binance.com/register?ref=BBBKK&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Disclosure: I receive a commission if you sign up with the code above. This is not financial advice.&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>New Exchange Account: Four Settings to Enable, Two to Skip, One to Verify</title>
      <dc:creator>Yinghui</dc:creator>
      <pubDate>Sun, 01 Nov 2026 10:04:09 +0000</pubDate>
      <link>https://dev.to/yinghuicrypto/new-exchange-account-four-settings-to-enable-two-to-skip-one-to-verify-1pn5</link>
      <guid>https://dev.to/yinghuicrypto/new-exchange-account-four-settings-to-enable-two-to-skip-one-to-verify-1pn5</guid>
      <description>&lt;p&gt;New account holders face a wall of settings described in language that assumes you already know what they do. Short version: four things to enable before your first deposit, two to skip, one to verify within the first hour.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enable before the first deposit
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. An authenticator-app second factor.&lt;/strong&gt; Not SMS - SIM swap attacks are cheap, and SMS is the factor most often bypassed in practice. Hardware key support is better still.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. A withdrawal address whitelist.&lt;/strong&gt; Rejects any withdrawal to a pre-unapproved address at the payout layer - below where a stolen session can act. The single setting that makes a stolen login useless for moving funds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. An anti-phishing code&lt;/strong&gt;, if offered. A custom word in every legitimate email. A withdrawal confirmation without it is phishing, no judgement required.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Withdrawal and security-change notifications.&lt;/strong&gt; Immediately, not eventually.&lt;/p&gt;

&lt;h2&gt;
  
  
  Skip for now
&lt;/h2&gt;

&lt;p&gt;API keys, until a specific script needs one (then: withdrawals off, IP restricted). Sub-accounts, until your structure requires them. Advanced order types, until your strategy does.&lt;/p&gt;

&lt;p&gt;Skipping is not neglect - it is refusing to widen an attack surface you do not need.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verify within the first hour
&lt;/h2&gt;

&lt;p&gt;If you entered a referral code at signup, verify it took: profile menu → referral section → the field naming your referrer. Not your own outbound code - that is always populated.&lt;/p&gt;

&lt;p&gt;Empty means a ticket the same day. Rebind requests are adjudicated from the raw signup session, which ages out. First hours: strong odds. Weeks: usually no.&lt;/p&gt;

&lt;p&gt;My code is BBBKK: &lt;a href="https://www.binance.com/register?ref=BBBKK" rel="noopener noreferrer"&gt;https://www.binance.com/register?ref=BBBKK&lt;/a&gt; (~20% off spot fees). The verification is the part that protects it.&lt;/p&gt;

&lt;h2&gt;
  
  
  First week
&lt;/h2&gt;

&lt;p&gt;Make a small withdrawal to a wallet you control. It confirms your whitelist config, your exit path, and the venue's normal speed - three things you want tested before you need them under pressure.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Disclosure: commission if you sign up with the code. Not financial advice.&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Why Referral Attribution Fails Silently: A Lesson in Write-Once Design</title>
      <dc:creator>Yinghui</dc:creator>
      <pubDate>Sat, 31 Oct 2026 19:13:27 +0000</pubDate>
      <link>https://dev.to/yinghuicrypto/why-referral-attribution-fails-silently-a-lesson-in-write-once-design-4h3n</link>
      <guid>https://dev.to/yinghuicrypto/why-referral-attribution-fails-silently-a-lesson-in-write-once-design-4h3n</guid>
      <description>&lt;p&gt;Every referral system I have audited has the same shape: one write, at account creation, and no way to correct it afterwards.&lt;/p&gt;

&lt;p&gt;That shape is not an accident. It is what you get when you design for fraud resistance first and user experience second, and it produces a failure mode that engineers rarely think about, because it never throws an exception.&lt;/p&gt;

&lt;h2&gt;
  
  
  The write
&lt;/h2&gt;

&lt;p&gt;When a new account is created, the backend stores a referrer field. That single write is the entire attribution. Everything downstream - fee discount, commission calculation, reporting - reads from it.&lt;/p&gt;

&lt;p&gt;The write happens inside the signup transaction, so it competes with everything else in that transaction: email verification state, KYC status, initial balance. If the referral code arrives from a query parameter, it also competes with session state, redirects, and whatever the frontend did to the form before submitting.&lt;/p&gt;

&lt;p&gt;Any of those can drop it. None of them surface an error.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the bug is invisible
&lt;/h2&gt;

&lt;p&gt;From the system's point of view, nothing failed. No exception, no retry, no alert. The referral field is nullable, so "no referrer" is a perfectly valid state - the same state as a user who deliberately signed up without a code.&lt;/p&gt;

&lt;p&gt;That is the core design tension: you cannot distinguish "user declined the discount" from "our pipeline dropped the discount" after the fact.&lt;/p&gt;

&lt;h2&gt;
  
  
  The UI makes it worse
&lt;/h2&gt;

&lt;p&gt;Most exchanges show your own outbound referral code prominently, and record your referrer quietly. Users check the first one, see a code, and conclude their relationship is active. It is not. Your outbound code says nothing about who referred you.&lt;/p&gt;

&lt;p&gt;If a system writes something once and never again, it owes the user a verification surface for that value. A read-only "referred by" line on the profile is not a nice-to-have; it is the difference between a recoverable mistake and an invisible one.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a better design looks like
&lt;/h2&gt;

&lt;p&gt;Three changes would remove most of this failure class:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Echo the value back immediately.&lt;/strong&gt; After signup, show "You were referred by X". If the value is empty and the user arrived via a referral link, warn them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Preserve the evidence.&lt;/strong&gt; Keep the original signup request payload long enough that support can adjudicate a rebind request weeks later.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate-limit writes, not reads.&lt;/strong&gt; The fraud concern is self-referral, which is a write-side problem. Making the field read-only does not solve fraud; it moves the pain to honest users.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The economics explain why it stays broken
&lt;/h2&gt;

&lt;p&gt;A referral code on Binance gives around 20% off spot trading fees. The money comes from the customer acquisition budget - the exchange pays either way. So a silent failure costs the platform nothing and costs the user a few percent, permanently and invisibly.&lt;/p&gt;

&lt;p&gt;That is the tell. When a failure costs the platform nothing and a few percent to the user, it survives for years.&lt;/p&gt;

&lt;p&gt;If you want a code to try, mine is BBBKK (&lt;a href="https://www.binance.com/register?ref=BBBKK" rel="noopener noreferrer"&gt;https://www.binance.com/register?ref=BBBKK&lt;/a&gt;) - but the habit that matters is the verification step, not the code.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Disclosure: I receive a commission if you sign up with the code above. This is not financial advice.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>web3security</category>
    </item>
  </channel>
</rss>
